1. 程式人生 > 其它 >用貝葉斯判別分析方法預測股票漲跌

用貝葉斯判別分析方法預測股票漲跌

作者: 依然很拉風

原文:資料人網 http://shujuren.org/article/164.html

判別分析也是一種分類器,與邏輯迴歸相比,它具有以下優勢:

  1. 當類別的區分度高的時候,邏輯迴歸的引數估計不夠穩定,它點線上性判別分析中是不存在的;
  2. 如果樣本量n比較小,而且在每一類響應變數中預測變數X近似服從正態分佈,那麼線性判別分析比邏輯迴歸更穩定;
  3. 多於兩類的分類問題時,線性判別分析更普遍。

貝葉斯分類器

貝葉斯分類的基本思想是:對於多分類(大於等於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。