线性判别分析
对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)