用貝葉斯判別分析方法預測股票漲跌
作者: 依然很拉風
原文:資料人網 http://shujuren.org/article/164.html
判別分析也是一種分類器,與邏輯迴歸相比,它具有以下優勢:
- 當類別的區分度高的時候,邏輯迴歸的引數估計不夠穩定,它點線上性判別分析中是不存在的;
- 如果樣本量n比較小,而且在每一類響應變數中預測變數X近似服從正態分佈,那麼線性判別分析比邏輯迴歸更穩定;
- 多於兩類的分類問題時,線性判別分析更普遍。
貝葉斯分類器
貝葉斯分類的基本思想是:對於多分類(大於等於2類)的問題,計算在已知條件下各類別的條件概率,取條件概率最大的那一類作為分類結果。用公式描述如下:
其中,$pi_{k}$是第k類的先驗概率,$f_k(x)$是第k類的概率密度(當然如果是離散型變數就是條件概率,本文考慮連續型變數)。這個公式就是貝葉斯定理。
線性判別分析(Linear Discriminant Analysis, LDA)
1、 一元線性判別分析
假設特徵變數滿足正態分佈,即:
線性判別分析有一個重要假設:假設所有K類的劃分方差相同,即$delta_1^2$=$delta_2^2$=……=$delta_K^2$。根據貝葉斯定理有:
對分子取對數轉換,可見$p_k(x)$最大等價於下式最大:
(這裡十分誠意地附上推導過程,沒興趣的可以直接跳過:)
所以只要找到令上式最大的k值即可。從上式可看出,一共有$mu$、$delta^2$、$pi$這三種引數需要估計擬合。先驗概率$pi_k$可以根據業務知識進行預先估計,如果不行也可以直接以樣本中第k類的樣本在所有類的總樣本中的比例當作先驗概率,即
至於期望和方差,直接根據各類的觀測值計算即可:
從上上式(我就不編號)可看出,$delta_k(x)$是$x$的線性函式,這也是LDA名為“線性”的原因。
2、多元線性判別分析
多元LDA由於涉及到多個特徵變數,因此用協方差矩陣來代替一維方差(協方差矩陣的概念可參考延伸閱讀文獻3)。這裡直接給結論,線性模型就變成:
除了方差變成協方差矩陣,$x$和$mu$也變成了向量。注意這裡的$x$還是一次,仍然是線性模型。
二次判別分析(Quadratic Discriminant Analysis, QDA)
在LDA中假設所有的K類方差(或協方差矩陣)都相同,但這個假設有些嚴苛,如果放寬這個假設,允許每一類的觀測都各自服從一個正態分佈,協方差矩陣可以不同,LDA就變成了QDA。這裡依然直接給公式:
可見$delta_k(x)$是$x$的二次函式,故名“二次判別分析”。
QDA與LDA的關係類似於多項式迴歸與線性迴歸的關係,本質上仍是偏差和方差的權衡,這也是Machine Learning領域的一個核心問題。QDA比LDA光滑,偏差更小,但方差更大。那麼它們的適用條件呢?
一般而言,如果訓練觀測資料量相對較少,LDA是一個比QDA更好的決策,降低模型的方差很有必要。相反地,如果訓練集非常大,則更傾向於使用QDA,這時分類器的方差不再是一個主要關心的問題,或者說K類的協方差矩陣相同的假設是站不住腳的。
實戰:用LDA(QDA)再次預測股票漲跌
這裡為了方(tou)便(lan),依然使用延伸閱讀文獻4裡的資料集,即ISLR
包裡的Smarket
資料集。用不同方法做同樣的事,其實也方便將不同方法進行對比。
> library(ISLR)> library(MASS)> attach(Smarket)> lda.fit=lda(Direction~Lag1+Lag2,data=Smarket, subset=Year<2005)> lda.fitCall:lda(Direction ~ Lag1 + Lag2, data = Smarket, subset = Year < 2005)Prior probabilities of groups: Down Up 0.491984 0.508016 Group means: Lag1 Lag2Down 0.04279022 0.03389409Up -0.03954635 -0.03132544Coefficients of linear discriminants: LD1Lag1 -0.6420190Lag2 -0.5135293
Prior probabilities of groups
是先驗概率,實際上就是各類別在訓練集中的比例:
> table(Smarket[Year<2005,9])/nrow(Smarket[Year<2005,]) Down Up 0.491984 0.508016
Group means
是對每類每個變數計算平均,用來估計引數$mu$。通過Group means
矩陣可看出:當股票下跌時,前兩天的投資回報率會趨向於正;當股票上漲時,前兩天的投資回報率會趨向於負。Coefficients of linear discriminants
則是線性模型的係數,說明當$-0.642Lag1-0.514Lag2$很大時,LDA分類器預測上漲;$-0.642Lag1-0.514Lag2$很小時,LDA分類器預測下跌。
> plot(lda.fit)
上面的圖是對LDA模型的視覺化,實際上它是訓練集的$-0.642Lag1-0.514Lag2$分別在Down
類和Up
類的直方圖。下面驗證比較一下:
library(dplyr)Lag1_1 <- Smarket %>% filter(Year<"2005", Direction=="Down") %>% select(Lag1)Lag2_1 <- Smarket %>% filter(Year<"2005", Direction=="Down") %>% select(Lag2) Lag1_2 <- Smarket %>% filter(Year<"2005", Direction=="Up") %>% select(Lag1) Lag2_2 <- Smarket %>% filter(Year<"2005", Direction=="Up") %>% select(Lag2) lm_1 <- (-0.6420190*Lag1_1-0.5135293*Lag2_1)[,1]lm_2 <- (-0.6420190*Lag1_2-0.5135293*Lag2_2)[,1]par(mfrow=c(2,1))hist(lm_1,breaks=16,freq = F,col="lightblue")hist(lm_2,breaks=16,freq = F,col="lightblue")
可見直方圖形狀完全一致。
以上在訓練集中對LDA模型的訓練過程。下面在測試集中驗證LDA模型。
> Smarket.2005=subset(Smarket,Year==2005)> lda.pred=predict(lda.fit,Smarket.2005)> class(lda.pred)[1] "list"> names(lda.pred)[1] "class" "posterior" "x" > data.frame(lda.pred)[1:5,] class posterior.Down posterior.Up LD1999 Up 0.4901792 0.5098208 0.082930961000 Up 0.4792185 0.5207815 0.591141021001 Up 0.4668185 0.5331815 1.167230631002 Up 0.4740011 0.5259989 0.833350221003 Up 0.4927877 0.5072123 -0.03792892> table(lda.pred$class,Smarket.2005$Direction) Down Up Down 35 35 Up 76 106> mean(lda.pred$class==Smarket.2005$Direction)[1] 0.5595238
比較一下上一篇邏輯迴歸(延伸閱讀文獻4)中的結果:
> glm.fit=glm(Direction~Lag1+Lag2,data=Smarket,family=binomial, subset=train)> glm.probs=predict(glm.fit,newdata=Smarket[!train,],type="response") > glm.pred=ifelse(glm.probs >0.5,"Up","Down")> table(glm.pred,Direction.2005) Direction.2005glm.pred Down Up Down 35 35 Up 76 106> mean(glm.pred==Direction.2005)[1] 0.5595238
LDA的結果與邏輯迴歸完全一致!以一個數據分析獅敏銳的第六感,我們可以大膽猜測:LDA與邏輯迴歸這兩種演算法可能有某種內在聯絡!
這裡不做嚴謹的推導(深層的推導可參考延伸閱讀文獻6),只作一個簡單的驗證比較。為了簡單起見,只考慮二分類問題,多分類問題可同理類推。 <br>log(frac{p_1(x)}{1-p_1(x)})=log(frac{p_1(x)}{p_2(x)})=log(p_1(x))-log(p_2(x))=x*frac{mu_1-mu_2}{sigma^2}-frac{mu_1^2-mu_2^2}{2sigma^2}+log(frac{pi_1}{pi_2})<br><br>log(1−p1(x)p1(x))=log(p2(x)p1(x))=log(p1(x))−log(p2(x))=x∗σ2μ1−μ2−2σ2μ12−μ22+log(π2π1)<br> 可見這仍是關於x的線性函式,與邏輯迴歸形式一致!雖然形式一致,但邏輯迴歸的引數是通過極大似然法估計出來的,LDA的引數是概率密度函式計算出來的。
由於LDA與邏輯迴歸形只是擬合過程不同,因此二者所得的結果應該是接近的。事實上,這一情況經常發生,但並非必然。LDA假設觀測服從每一類的協方差矩陣都相同的正態分佈,當這一假設近似成立時,LDA效果比邏輯迴歸好;相反,若這個假設不成立,則邏輯迴歸效果比LDA好。
下面練習QDA:
> qda.fit=qda(Direction~Lag1+Lag2,data=Smarket,subset=train)> qda.fitCall:qda(Direction ~ Lag1 + Lag2, data = Smarket, subset = train)Prior probabilities of groups: Down Up 0.491984 0.508016 Group means: Lag1 Lag2Down 0.04279022 0.03389409Up -0.03954635 -0.03132544> qda.class=predict(qda.fit,Smarket.2005)$class> table(qda.class,Direction.2005) Direction.2005qda.class Down Up Down 30 20 Up 81 121> mean(qda.class==Direction.2005)[1] 0.5992063
可見QDA的準確率稍高於LDA。