7.1、KNN实例

来源:互联网 发布:sql删除重复 编辑:程序博客网 时间:2024/06/10 18:22
Loading [MathJax]/jax/output/HTML-CSS/jax.js



实例一、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为1mean(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

0 0
原创粉丝点击