線性判別分析
對Smarket數據做線性判別分析(LDA)
library(MASS)
lda.fit <- lda(Direction~Lag1+Lag2,data=Smarket,subset=(Year<2005))
lda.fit
Call:
lda(Direction ~ Lag1 + Lag2, data = Smarket, subset = (Year < 2005))
Prior probabilities of groups:
Down Up
0.491984 0.508016
Group means:
Lag1 Lag2
Down 0.04279022 0.03389409
Up -0.03954635 -0.03132544
Coefficients of linear discriminants:
LD1
Lag1 -0.6420190
Lag2 -0.5135293
LDA輸出兩個類別的前向概率,表明49.2%的訓練觀測對應着市場下降的時期;同時也輸出類平均值,即每個類中每個預測變量的平均,
可以用來估計每個類高斯分布的均值。這表明當市場上漲時,前兩天的投資回報率會趨向負值;當市場下跌時,前兩天的投資回報率會趨向正值。
線性判別系數輸出給出了線性判別函數中Lag1和Lag2的組合系數,用來形成LDA的決策准則,該決策函數是由式(4.19)X=x各變量相乘表示的,
如果-0.642Lag1-0.514Lag2很大,則LDA線性分類器將預測市場上漲;如果很小LDA分類器預測市場下跌。
plot(lda.fit) #生成線性判別圖像
lda.pred <- predict(lda.fit,test)#返回三元列表
names(lda.pred)
[1] "class" "posterior" "x"
predict()函數返回結果說明:
class因子型變量,存儲了LDA關於市場動向的預測;
posterior是一個矩陣,其中第k列是觀測屬於第k類的后驗概率,依據后驗概率大的類,結果包含在class之中;
x包含線性決策函數-0.642*Lag1-0.514*Lag2的結果。
lda.class <- lda.pred$class
table(lda.class,Direction.test)
Direction.test
lda.class Down Up
Down 35 35
Up 76 106
LDA與邏輯斯蒂回歸預測結果幾乎一樣
#預測正確率
mean(lda.class==Direction.test)
[1] 0.5595238
使用后驗概率50%的闕值,重新預測
sum(lda.pred$posterior[,1]>=0.5)
[1] 70 #70代表上漲的數目
sum(lda.pred$posterior[,1]<0.5)
[2] 182 #代表下跌的數目
如果闕值用一個非50%的后驗概率闕值做預測:
sum(lda.pred$posterior[,1]>0.9)
[1] 0 結果為0,說明在測試數據集中,下跌后驗概率沒有一天達到90%
二次判別分析(QDA)
對Smarket數據擬合QDA模型,在R中調用MASS庫中的qda()函數來實現
qda.fit <- qda(Direction~Lag1+Lag2,data=Smarket,subset=(Year<2005))
qda.fit
Call:
qda(Direction ~ Lag1 + Lag2, data = Smarket, subset = (Year < 2005))
Prior probabilities of groups:
Down Up
0.491984 0.508016
Group means:
Lag1 Lag2
Down 0.04279022 0.03389409
Up -0.03954635 -0.03132544
輸出結果包含類平均值,但是不包含線性判別系數,因為QDA分類器是一個二次函數,不是預測變量的線性函數。
predict()函數與LDA執行方式相同
qda.class <- predict(qda.fit,test)$class
table(qda.class,Direction.test)
Direction.test
qda.class Down Up
Down 30 20
Up 81 121
#正確的預測率
mean(qda.class==Direction.test)
[1] 0.5992063
對股票市場數據,QDA所假設的二次型比LDA和邏輯斯蒂回歸的線性假設更近於真實的關系
KNN法
library(class)
#knn()函數用法有所不同
#前兩種都是先擬合模型,再根據模型做預測
#knn函數中有四個必須的參數,就可以做預測
library(ISLR)
attach(Smarket)
#分成訓練數據集和測試數據集
train.X <- cbind(Lag1,Lag2)[Year<2005,]
test.X <-cbind(Lag1,Lag2)[Year>=2005,]
#訓練數據觀測類標簽的向量
train.Direction <- Direction[Year<2005]
test.Direction <- Direction[Year>=2005]
set.seed(123)#結果可重復
#knn返回測試數據的分類標簽
knn.pred <- knn(train.X,test.X,train.Direction,k=1)
table(knn.pred,test.Direction)
test.Direction
knn.pred Down Up
Down 43 58
Up 68 83
#測試正確率
mean(knn.pred==test.Direction)
[1] 0.5
正確率只有50%,改變k值,重新預測
knn.pred <- knn(train.X,test.X,train.Direction,k=3)
table(knn.pred,test.Direction)
test.Direction
knn.pred Down Up
Down 48 55
Up 63 86
#測試正確率
mean(knn.pred==test.Direction)
[1] 0.531746
結果略有改觀,隨着k的增加,結果不會有更進一步的改進。
detach(Smarket)