ISLR实验:分类 - K最近邻
目录
本文源自《统计学习导论:基于R语言应用》(ISLR) 中《4.6 R实验:逻辑斯谛回归、LDA、QDA和KNN》章节
library(ISLR)
library(class)
数据
股票市场数据
data(Smarket)
head(Smarket)
Year Lag1 Lag2 Lag3 Lag4 Lag5 Volume Today Direction
1 2001 0.381 -0.192 -2.624 -1.055 5.010 1.1913 0.959 Up
2 2001 0.959 0.381 -0.192 -2.624 -1.055 1.2965 1.032 Up
3 2001 1.032 0.959 0.381 -0.192 -2.624 1.4112 -0.623 Down
4 2001 -0.623 1.032 0.959 0.381 -0.192 1.2760 0.614 Up
5 2001 0.614 -0.623 1.032 0.959 0.381 1.2057 0.213 Up
6 2001 0.213 0.614 -0.623 1.032 0.959 1.3491 1.392 Up
训练集和测试集
训练集:2001 至 2004 年
测试集:2005 年
train <- (Year < 2005)
构建测试集和训练集
train_X <- cbind(Lag1, Lag2)[train,]
test_X <- cbind(Lag1, Lag2)[!train,]
train_direction <- Direction[train]
test_direction <- Direction[!train]
方法
class
包中的 knn()
函数
训练 k=1 的模型
set.seed(1)
knn_predict <- knn(
train_X,
test_X,
train_direction,
k=1
)
列联表
table(test_direction, knn_predict)
knn_predict
test_direction Down Up
Down 43 68
Up 58 83
正确率
(83+43)/252
[1] 0.5
训练 k=3 的模型
set.seed(1)
knn_predict <- knn(
train_X,
test_X,
train_direction,
k=3
)
列联表
table(test_direction, knn_predict)
knn_predict
test_direction Down Up
Down 48 63
Up 55 86
正确率
(86+48)/252
[1] 0.531746
应用
大篷车保险数据集
数据集
attach(Caravan)
dim(Caravan)
[1] 5822 86
summary(Purchase)
No Yes
5474 348
348/(5474+348)
[1] 0.05977327
只有 6% 的人购买了大篷车保险
标准化
scale()
函数将每列标准化为均值为 0,方差为 1 的数据
standardized_X = scale(Caravan[,-86])
c(var(Caravan[,1]), var(standardized_X[,1]))
[1] 165.0378 1.0000
c(var(Caravan[,2]), var(standardized_X[,2]))
[1] 0.1647078 1.0000000
测试集和训练集
test <- 1:1000
train_X <- standardized_X[-test,]
test_X <- standardized_X[test,]
train_Y <- Purchase[-test]
test_Y <- Purchase[test]
K最近邻
set.seed(1)
knn_predict <- knn(
train_X,
test_X,
train_Y,
k=1
)
mean(test_Y != knn_predict)
[1] 0.118
错误率为 12%
mean(test_Y != "No")
[1] 0.059
只有 6% 的顾客购买了保险
预测阳性率
精确率
真阳性值 / (真阳性值 + 假阳性值)
保险公司更愿意向有购买倾向性的客户销售保险,对总错误率不感兴趣,而对精确率感兴趣
k=1
table(knn_predict, test_Y)
test_Y
knn_predict No Yes
No 873 50
Yes 68 9
9/(68+9)
[1] 0.1168831
k=3
knn_predict_3 <- knn(
train_X,
test_X,
train_Y,
k=3
)
table(knn_predict_3, test_Y)
test_Y
knn_predict_3 No Yes
No 920 54
Yes 21 5
5/(5 + 21)
[1] 0.1923077
k=5
knn_predict_5 <- knn(
train_X,
test_X,
train_Y,
k=5
)
table(knn_predict_5, test_Y)
test_Y
knn_predict_5 No Yes
No 930 55
Yes 11 4
4/(11 + 4)
[1] 0.2666667
逻辑斯谛回归
glm_fit <- glm(
Purchase ~ .,
data=Caravan,
family=binomial,
subset=-test
)
glm_probs <- predict(
glm_fit,
Caravan[test,],
type="response"
)
以 0.5 作为阈值
glm_predict <- rep("No", 1000)
glm_predict[glm_probs > .5] = "Yes"
table(glm_predict, test_Y)
test_Y
glm_predict No Yes
No 934 59
Yes 7 0
0/(7 + 0)
[1] 0
没有一个预测对
以 0.25 为阈值
glm_predict <- rep("No", 1000)
glm_predict[glm_probs > .25] = "Yes"
table(glm_predict, test_Y)
test_Y
glm_predict No Yes
No 919 48
Yes 22 11
11/(22 + 11)
[1] 0.3333333
33% 比随机猜想的五倍还多
参考
https://github.com/perillaroc/islr-study
ISLR实验系列文章
线性回归
分类
重抽样方法
线性模型选择与正则化