KNN实例
junjun
2016年2月10日
实例一、K近邻算法R语言实践,使用class包中的三个函数knn()、knn1()、knn.cv()分别做K近邻分类,并比较结果
#1、加载数据
data("iris")
#2、创建训练集和测试集数据
library(caret)
## Loading required package: lattice
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 3.2.3
set.seed(2006)
index <- createDataPartition(iris$Species, p=0.7, list = F)
train_iris <- iris[index, ]
test_iris <- iris[-index, ]
#3、建模
library(class)
#1)用knn()函数实现分类
model_knn <- knn(train_iris[, 1:4], test_iris[, 1:4], train_iris[, 5])
#注意:默认k为1
mean(model_knn==test_iris[, 5])
## [1] 0.9555556
#k=3时
model_knn <- knn(train_iris[, 1:4], test_iris[, 1:4], train_iris[, 5], k=3)
mean(model_knn==test_iris[, 5])
## [1] 0.9555556
#2)用knn1()函数实现分类
model_knn1 <- knn1(train_iris[, 1:4], test_iris[, 1:4], train_iris[, 5])
mean(model_knn1==test_iris[, 5])
## [1] 0.9555556
#3)用knn.cv()函数实现分类
model_knncv <- knn.cv(iris[, 1:4], iris[, 5], k=3)
mean(model_knncv==iris[, 5])
## [1] 0.96
#可以看到,同样使用 k = 3 的参数,knn.cv 比 knn 的表现要好一些
实例二、使用 caret 包实现 knn 算法
#1、加载数据
data("iris")
#2、创建训练集和测试集数据
library(caret)
set.seed(2006)
index <- createDataPartition(iris$Species, p=0.7, list = F)
train_iris <- iris[index, ]
test_iris <- iris[-index, ]
#3、建模
model_iris <- knn3(Species~., data=train_iris, k=3)
#4、模型评估
model_iris
## 3-nearest neighbor classification model
## Training set class distribution:
##
## setosa versicolor virginica
## 35 35 35
pred <- predict(model_iris, train_iris[, 1:4], type="class")
#5、预测
pred_iris <- predict(model_iris, test_iris[, 1:4], type="class")
mean(pred_iris==test_iris[,5])
## [1] 0.9555556
table(pred_iris, test_iris[, 5])
##
## pred_iris setosa versicolor virginica
## setosa 15 0 0
## versicolor 0 15 2
## virginica 0 0 13
实例三、使用kknn包的kknn()函数实现K最近邻算法
kknn(formula = formula(train),train, test, na.action = na.omit(), k= 7, distance = 2, kernel = “optimal”, ykernel = NULL, scale=TRUE, contrasts= c(‘unordered’ = “contr.dummy”, ordered =“contr.ordinal”)):为K最近邻算法。其中,formula表示训练集的表达式对象;train为训练集的数据框或矩阵;test为测试集的数据库或矩阵;distance为明科夫斯基距离;na.action 缺失值处理,默认为去掉缺失值;kernel内核使用,可能的选择是“rectangular”(这是标准的加权KNN),“triangular”, “epanechnikov”(或β(2,2)),“biweight”(或β(3,3)),“triweight”(或β(4,4)),“cos”, “inv”, “gaussian”, “rank” and “optimal”;k为考虑的邻近数量 fitted():提取模型拟合值。
#1、加载数据
data("iris")
#2、创建训练集和测试集数据
library(caret)
set.seed(2006)
index <- createDataPartition(iris$Species, p=0.7, list = F)
train_iris <- iris[index, ]
test_iris <- iris[-index, ]
#3、建模
library(kknn)
##
## Attaching package: 'kknn'
## The following object is masked from 'package:caret':
##
## contr.dummy
model_iris <- kknn(Species~., train_iris, test_iris, distance = 5, kernel = "triangular")
#4、模型评估
summary(model_iris)
##
## Call:
## kknn(formula = Species ~ ., train = train_iris, test = test_iris, distance = 5, kernel = "triangular")
##
## Response: "nominal"
## fit prob.setosa prob.versicolor prob.virginica
## 1 setosa 1 0.00000000 0.0000000
## 2 setosa 1 0.00000000 0.0000000
## 3 setosa 1 0.00000000 0.0000000
## 4 setosa 1 0.00000000 0.0000000
## 5 setosa 1 0.00000000 0.0000000
## 6 setosa 1 0.00000000 0.0000000
## 7 setosa 1 0.00000000 0.0000000
## 8 setosa 1 0.00000000 0.0000000
## 9 setosa 1 0.00000000 0.0000000
## 10 setosa 1 0.00000000 0.0000000
## 11 setosa 1 0.00000000 0.0000000
## 12 setosa 1 0.00000000 0.0000000
## 13 setosa 1 0.00000000 0.0000000
## 14 setosa 1 0.00000000 0.0000000
## 15 setosa 1 0.00000000 0.0000000
## 16 versicolor 0 0.80303905 0.1969610
## 17 versicolor 0 0.85418190 0.1458181
## 18 versicolor 0 0.81832163 0.1816784
## 19 versicolor 0 1.00000000 0.0000000
## 20 versicolor 0 1.00000000 0.0000000
## 21 versicolor 0 0.87568976 0.1243102
## 22 versicolor 0 1.00000000 0.0000000
## 23 virginica 0 0.39616914 0.6038309
## 24 versicolor 0 1.00000000 0.0000000
## 25 versicolor 0 0.88064600 0.1193540
## 26 versicolor 0 0.56269818 0.4373018
## 27 versicolor 0 1.00000000 0.0000000
## 28 versicolor 0 1.00000000 0.0000000
## 29 versicolor 0 1.00000000 0.0000000
## 30 versicolor 0 1.00000000 0.0000000
## 31 versicolor 0 0.97227890 0.0277211
## 32 virginica 0 0.00000000 1.0000000
## 33 virginica 0 0.00000000 1.0000000
## 34 virginica 0 0.00000000 1.0000000
## 35 virginica 0 0.00000000 1.0000000
## 36 virginica 0 0.08040661 0.9195934
## 37 virginica 0 0.00000000 1.0000000
## 38 versicolor 0 0.52950821 0.4704918
## 39 virginica 0 0.00000000 1.0000000
## 40 versicolor 0 0.77937141 0.2206286
## 41 versicolor 0 0.80660853 0.1933915
## 42 virginica 0 0.00000000 1.0000000
## 43 virginica 0 0.00000000 1.0000000
## 44 virginica 0 0.00000000 1.0000000
## 45 virginica 0 0.33221460 0.6677854
#5、对模型中测试集的数据进行拟合
fit_iris <- fitted(model_iris)
mean(fit_iris==test_iris[, 5])
## [1] 0.8888889
table(fit_iris, test_iris[, 5])
##
## fit_iris setosa versicolor virginica
## setosa 15 0 0
## versicolor 0 14 4
## virginica 0 1 11
实例四、信用卡数据(实现K的选择)
#1、加载数据并查看
dataset <- read.table("F:\\R\\Rworkspace\\信用卡数据/crx.data", header=F, sep=",", na.strings="?")
str(dataset)
## 'data.frame': 690 obs. of 16 variables:
## $ V1 : Factor w/ 2 levels "a","b": 2 1 1 2 2 2 2 1 2 2 ...
## $ V2 : num 30.8 58.7 24.5 27.8 20.2 ...
## $ V3 : num 0 4.46 0.5 1.54 5.62 ...
## $ V4 : Factor w/ 3 levels "l","u","y": 2 2 2 2 2 2 2 2 3 3 ...
## $ V5 : Factor w/ 3 levels "g","gg","p": 1 1 1 1 1 1 1 1 3 3 ...
## $ V6 : Factor w/ 14 levels "aa","c","cc",..: 13 11 11 13 13 10 12 3 9 13 ...
## $ V7 : Factor w/ 9 levels "bb","dd","ff",..: 8 4 4 8 8 8 4 8 4 8 ...
## $ V8 : num 1.25 3.04 1.5 3.75 1.71 ...
## $ V9 : Factor w/ 2 levels "f","t": 2 2 2 2 2 2 2 2 2 2 ...
## $ V10: Factor w/ 2 levels "f","t": 2 2 1 2 1 1 1 1 1 1 ...
## $ V11: int 1 6 0 5 0 0 0 0 0 0 ...
## $ V12: Factor w/ 2 levels "f","t": 1 1 1 2 1 2 2 1 1 2 ...
## $ V13: Factor w/ 3 levels "g","p","s": 1 1 1 1 3 1 1 1 1 1 ...
## $ V14: int 202 43 280 100 120 360 164 80 180 52 ...
## $ V15: int 0 560 824 3 0 0 31285 1349 314 1442 ...
## $ V16: Factor w/ 2 levels "-","+": 2 2 2 2 2 2 2 2 2 2 ...
summary(dataset)
## V1 V2 V3 V4 V5
## a :210 Min. :13.75 Min. : 0.000 l : 2 g :519
## b :468 1st Qu.:22.60 1st Qu.: 1.000 u :519 gg : 2
## NA's: 12 Median :28.46 Median : 2.750 y :163 p :163
## Mean :31.57 Mean : 4.759 NA's: 6 NA's: 6
## 3rd Qu.:38.23 3rd Qu.: 7.207
## Max. :80.25 Max. :28.000
## NA's :12
## V6 V7 V8 V9 V10
## c :137 v :399 Min. : 0.000 f:329 f:395
## q : 78 h :138 1st Qu.: 0.165 t:361 t:295
## w : 64 bb : 59 Median : 1.000
## i : 59 ff : 57 Mean : 2.223
## aa : 54 j : 8 3rd Qu.: 2.625
## (Other):289 (Other): 20 Max. :28.500
## NA's : 9 NA's : 9
## V11 V12 V13 V14 V15 V16
## Min. : 0.0 f:374 g:625 Min. : 0 Min. : 0.0 -:383
## 1st Qu.: 0.0 t:316 p: 8 1st Qu.: 75 1st Qu.: 0.0 +:307
## Median : 0.0 s: 57 Median : 160 Median : 5.0
## Mean : 2.4 Mean : 184 Mean : 1017.4
## 3rd Qu.: 3.0 3rd Qu.: 276 3rd Qu.: 395.5
## Max. :67.0 Max. :2000 Max. :100000.0
## NA's :13
#从上可知:共计690条数据,16个变量;其中,有因子类型和数字类型的变量;数据集中含有缺失值
#2、数据清洗:删除含有缺失值的数据
dataset <- na.omit(dataset)
str(dataset)
## 'data.frame': 653 obs. of 16 variables:
## $ V1 : Factor w/ 2 levels "a","b": 2 1 1 2 2 2 2 1 2 2 ...
## $ V2 : num 30.8 58.7 24.5 27.8 20.2 ...
## $ V3 : num 0 4.46 0.5 1.54 5.62 ...
## $ V4 : Factor w/ 3 levels "l","u","y": 2 2 2 2 2 2 2 2 3 3 ...
## $ V5 : Factor w/ 3 levels "g","gg","p": 1 1 1 1 1 1 1 1 3 3 ...
## $ V6 : Factor w/ 14 levels "aa","c","cc",..: 13 11 11 13 13 10 12 3 9 13 ...
## $ V7 : Factor w/ 9 levels "bb","dd","ff",..: 8 4 4 8 8 8 4 8 4 8 ...
## $ V8 : num 1.25 3.04 1.5 3.75 1.71 ...
## $ V9 : Factor w/ 2 levels "f","t": 2 2 2 2 2 2 2 2 2 2 ...
## $ V10: Factor w/ 2 levels "f","t": 2 2 1 2 1 1 1 1 1 1 ...
## $ V11: int 1 6 0 5 0 0 0 0 0 0 ...
## $ V12: Factor w/ 2 levels "f","t": 1 1 1 2 1 2 2 1 1 2 ...
## $ V13: Factor w/ 3 levels "g","p","s": 1 1 1 1 3 1 1 1 1 1 ...
## $ V14: int 202 43 280 100 120 360 164 80 180 52 ...
## $ V15: int 0 560 824 3 0 0 31285 1349 314 1442 ...
## $ V16: Factor w/ 2 levels "-","+": 2 2 2 2 2 2 2 2 2 2 ...
## - attr(*, "na.action")=Class 'omit' Named int [1:37] 72 84 87 93 98 203 207 244 249 255 ...
## .. ..- attr(*, "names")= chr [1:37] "72" "84" "87" "93" ...
summary(dataset)
## V1 V2 V3 V4 V5 V6
## a:203 Min. :13.75 Min. : 0.000 l: 2 g :499 c :133
## b:450 1st Qu.:22.58 1st Qu.: 1.040 u:499 gg: 2 q : 75
## Median :28.42 Median : 2.835 y:152 p :152 w : 63
## Mean :31.50 Mean : 4.830 i : 55
## 3rd Qu.:38.25 3rd Qu.: 7.500 aa : 52
## Max. :76.75 Max. :28.000 ff : 50
## (Other):225
## V7 V8 V9 V10 V11 V12
## v :381 Min. : 0.000 f:304 f:366 Min. : 0.000 f:351
## h :137 1st Qu.: 0.165 t:349 t:287 1st Qu.: 0.000 t:302
## ff : 54 Median : 1.000 Median : 0.000
## bb : 53 Mean : 2.244 Mean : 2.502
## j : 8 3rd Qu.: 2.625 3rd Qu.: 3.000
## z : 8 Max. :28.500 Max. :67.000
## (Other): 12
## V13 V14 V15 V16
## g:598 Min. : 0.0 Min. : 0 -:357
## p: 2 1st Qu.: 73.0 1st Qu.: 0 +:296
## s: 53 Median : 160.0 Median : 5
## Mean : 180.4 Mean : 1014
## 3rd Qu.: 272.0 3rd Qu.: 400
## Max. :2000.0 Max. :100000
##
#从上可知:还有653条数据
#3、创建训练集和测试集数据
set.seed(2007)
(n <- nrow(dataset))
## [1] 653
index <- sample(n, round(0.7*n))
train <- dataset[index, ]
test <- dataset[-index, ]
#4、建模
#1)首先测试一个knn模型,不做CV,不做标准化,不做数据类型转换得到的结果,这里,不转换数据类型会把因子类型的变量舍弃,仅保留数值变量
library(caret)
model_knn3 <- knn3(V16~., data=train, k=5)
pred <- predict(model_knn3, test, class="response")
pred <- ifelse(pred[, 1] < 0.5, "+", "-")
mean(pred==test$V16)
## [1] 0.7244898
table(pred, test$V16)
##
## pred - +
## - 89 30
## + 24 53
#2)knn CV for k
#通过CV选择K值
library(class)
cv.knn = function(data,n=5,k){
index = sample(1:5,nrow(data),replace = T)
acc=0
for ( i in 1:5){
ind = index == i
train = data[-ind,]
test = data[ind,]
knn.model1 = knn3(V16 ~ .,data = train, k = k)
knn.predict= predict(knn.model1,test,type = "class")
acc[i] = mean(knn.predict == test$V16)
}
mean(acc)
}
cv.knn(train, 3, 5)
## [1] 0.7744085
k <- 2:20
(acc <- sapply(k, function(x) cv.knn(train, 3, k)))
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## Warning in if (ntr < k) {: 条件的长度大于一,因此只能用其第一元素
## Warning in if (k < 1) stop(gettextf("k = %d must be at least 1", k), domain
## = NA): 条件的长度大于一,因此只能用其第一元素
## Warning in classProbs * k: 长的对象长度不是短的对象长度的整倍数
## [1] 0.8358924 0.8561838 0.8307229 0.8332468 0.8406706 0.8277890 0.8477890
## [8] 0.8431711 0.8353861 0.8307227 0.8067790 0.8356288 0.8265596 0.8510518
## [15] 0.8351298 0.8164453 0.8379080 0.8347684 0.8327287
plot(k, acc, type="b")
(k_final <- which.max(acc))
## [1] 2
#建模
model <- knn3(V16~., data=train, k=k_final)
pred <- predict(model, test, type="class")
mean(pred==test$V16)
## [1] 0.6326531
table(pred, test$V16)
##
## pred - +
## - 74 33
## + 39 50
实例五、利用KNN算法判断乳腺癌
数据准备 这里我们使用Breast Cancer Wisconsin Diagnostic数据集: 数据:http://mlr.cs.umass.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data 数据说明:http://mlr.cs.umass.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.names 数据包含了569个样本,32个特征的数据,其中关键特征为: + Radius+ Texture+ Perimeter+ Area+ Smoothness+ Compactness+ Concavity+ Concave points+ Symmetry+ Fractal dimension ?? ??1、加载数据: > wdbc <- read.csv(“F:\R\Rworkspace\机器学习实践课\乳腺癌数据/wdbc.data”, header=F)
2、调整数据: 1)对每列数据重命名 > wdbc.names=c(“Radius”, “Texture”, “Perimeter”, “Area”, “Smoothness”, “Compactness”, “Concavity”, “Concave points”, “Symmetry”, “Fractal dimension”) > wdbc.names=c(wdbc.names, paste(wdbc.names,“_mean“, sep=”“),paste(wdbc.names,”_worst“,sep=”“)) > head(wdbc) V1 V2 V3 V4 V5 V6 V7 V8 1 842302 M 17.99 10.38 122.80 1001.0 0.11840 0.27760 。。。
names(wdbc) <- c(“id”, “diagnosis”, wdbc.names) head(wdbc) id diagnosis Radius Texture Perimeter Area 1 842302 M 17.99 10.38 122.80 1001.0 。。。
最终的数据为: > str(wdbc) ‘data.frame’: 569 obs. of 32 variables: $ id : int 842302 842517 84300903 84348301 84358402 843786 844359 84458202 844981 84501001 … $ diagnosis : Factor w/ 2 levels “B”,“M”: 2 2 2 2 2 2 2 2 2 2 … $ Radius : num 18 20.6 19.7 11.4 20.3 … $ Texture : num 10.4 17.8 21.2 20.4 14.3 …
从这里我们知道数据集中357个样本未良性,212个为恶性肿瘤 > table(wdbc$diagnosis) 列联表,统计出频数 B M 357 212
2)我们再修改一下数据,同时去掉id,因为id对预测没有意义: > wdbcdiagnosis<−factor(wdbcdiagnosis, levels=c(“B”, “M”), labels=c(“Bengin”, “Malignant”)) > round(prop.table(table(wdbc$diagnosis))*100, digits=1) Bengin Malignant 62.7 37.3 > wdbc <- wdbc[-1] 去掉第一列,wdbc[1]指第一列 > dim(wdbc) [1] 569 31 prop.table(table, margins) :依margins定义的边际列表将表中条目表示为分数形式
3、对数据进行标准化、中心化处理: 通过summary,我们很明显看出不同的特征的度量值差别太大 > summary(wdbc[c(“Radius_mean”, “Area_mean”, “Smoothness_mean”)]) Radius_mean Area_mean Smoothness_mean
Min. :0.1115 Min. : 6.802 Min. :0.001713
1st Qu.:0.2324 1st Qu.: 17.850 1st Qu.:0.005169
Median :0.3242 Median : 24.530 Median :0.006380
Mean :0.4052 Mean : 40.337 Mean :0.007041
3rd Qu.:0.4789 3rd Qu.: 45.190 3rd Qu.:0.008146
Max. :2.8730 Max. :542.200 Max. :0.031130
1)数据转换:显然数据需要转换, 定义最大最小标准化转换函数为:(对数据进行标准化的函数) > normalize <- function(x) { return((x-min(x))/(max(x)-min(x))) }
接下来对数据进行转换后,执行summary可以看出特征的区间分布已经统一了 > wdbc_n <- as.data.frame(lapply(wdbc[2:31], normalize)) 对wdbc的第2到31列数据做标准化处理 > summary(wdbc_n[c(“Radius_mean”, “Area_mean”, “Smoothness_mean”)]) Radius_mean Area_mean Smoothness_mean Min. :0.00000 Min. :0.00000 Min. :0.0000
1st Qu.:0.04378 1st Qu.:0.02064 1st Qu.:0.1175
Median :0.07702 Median :0.03311 Median :0.1586
Mean :0.10635 Mean :0.06264 Mean :0.1811
3rd Qu.:0.13304 3rd Qu.:0.07170 3rd Qu.:0.2187
Max. :1.00000 Max. :1.00000 Max. :1.0000
2)用z-score来实现数据的标准化和中心化:最大最小值标准化强制把数据压缩在了0-1之间,也许减小了极值的影响,不过可能极值正好是恶性的标志 > wdbc_z <- as.data.frame(scale(wdbc[, -1])) 注意:默认标准化后为矩阵,所以要转化为数据框
4、构建训练集、测试集和validation数据集:最好用caret包中的createDataPartition()函数 接下来我们需要构造训练数据与测试数据,实际通常的做法是training,validation,test三个数据集, > install.packages(“caret”) > library(caret) > index <- createDataPartition(y=wdbc$diagnosis, p=0.8, list=F) 为数据拆分函数,y为一个向量的结果,p为要获取训练集的百分比,list为T时结果为列表 > train_wdbc <- wdbc_z[index, ] > test_wdbc <- wdbc_z[-index, ] > train_wdbc_diagnosis <- wdbc[index,1] > test_wdbc_diagnosis <- wdbc[-index, 1] > table(train_wdbc_diagnosis) train_wdbc_diagnosis Bengin Maligrant 286 170 > prop.table(table(train_wdbc_diagnosis)) train_wdbc_diagnosis Bengin Maligrant 0.627193 0.372807
4、构建KNN模型:我们采用 class 包的knn()函数实现:(当然其他实现你可以参考CRAN,例如 caret 包里面的 knn3) > library(class) > sqrt(nrow(train_wdbc)) [1] 21.35416 > pred <- knn(train=train_wdbc, test=test_wdbc, cl=train_wdbc_diagnosis, k=21) K近邻分类函数,train为训练数据,test为测试数据,cl为factor 训练数据的对应分类(训练集的真实分类因素),k为考虑的邻近数量 这里k=21,基于是采用“length(wdbc_train_label)”的平方根。
5、模型评估:这里采用 gmodels 的 CrossTable 函数 > require(gmodels) > CrossTable(test_wdbc_diagnosit, pred, prop.chisq=F) 为独立试验因素的交叉制表函数;x为真实的结果;y为预测的结果;prop.chisq为T将包含每个元素的卡方 Cell Contents |————————-| | N | | N / Row Total | | N / Col Total | | N / Table Total | |————————-|
Total Observations in Table: 113
| pred
test_wdbc_diagnosit | Bengin | Maligrant | Row Total | ——————–|———–|———–|———–| Bengin | 70 | 1 | 71 | | 0.986 | 0.014 | 0.628 | | 0.946 | 0.026 | | | 0.619 | 0.009 | | ——————–|———–|———–|———–| Maligrant | 4 | 38 | 42 | | 0.095 | 0.905 | 0.372 | | 0.054 | 0.974 | | | 0.035 | 0.336 | | ——————–|———–|———–|———–| Column Total | 74 | 39 | 113 | | 0.655 | 0.345 | | ——————–|———–|———–|———–|
分别得到 TN=70,TP=38, FN=4, FP=0 。因此: > accuracy=(TN+TP)/113=0.9557522 > sensitibity=TP/(TP+FN)=0.9047619 > specificity=TN/(TN+FP)=1 详细解释请参考维基百科(https://en.wikipedia.org/wiki/Sensitivity_and_specificity) 简单说sensitivity是检查正确识别恶性肿瘤的比例,specificity检查正确排除恶性肿瘤的比例。
6、查看预测的错误比率: > mean(test_wdbc[, 1]!=pred) [1] 0.07964602