43-R語言機器學習:K最近鄰與支持向量機

《精通機器學習:基于R 第二版》學習筆記

1、前文回顧

前面學習了邏輯斯蒂回歸,它被用來預測一個觀測屬于某個響應變量分類的概率——我們稱之為分類問題。邏輯斯蒂回歸只是分類方法的開始,還可以使用很多其他方法改善預測質量。
K最近鄰(KNN)與支持向量機(SVM)要比我們之前討論的那些技術復雜一些,因為放棄了線性假設。也就是說,不再必須使用特征的線性組合來定義決策邊界。這樣不一定能得到更好的預測結果,而且向業務伙伴解釋模型也會有一點問題,計算效率也更低。

2、K最近鄰

一般用特征的內積(點積)表示核函數,用 xi 和 xj 代表向量, γ 和 c 為參數,常用的核函數如下所示:
? 線性核函數: K(xi , xj) = xi · xj,無需轉換
? 多項式核函數: K(xi , xj) = (γxi · xj + c) d , d 為多項式的次數
? 徑向基核函數: K(xi , xj) = e( -γ | xi - xj | 2 )
? sigmod 核函數: K(xi , xj) = tanh(γxi · xj + c)

2.1 數據理解和數據準備

> library(pacman)
> p_load(MASS)
> str(Pima.tr)
## 'data.frame':    200 obs. of  8 variables:
##  $ npreg: int  5 7 5 0 0 5 3 1 3 2 ...
##  $ glu  : int  86 195 77 165 107 97 83 193 142 128 ...
##  $ bp   : int  68 70 82 76 60 76 58 50 80 78 ...
##  $ skin : int  28 33 41 43 25 27 31 16 15 37 ...
##  $ bmi  : num  30.2 25.1 35.8 47.9 26.4 35.6 34.3 25.9 32.4 43.3 ...
##  $ ped  : num  0.364 0.163 0.156 0.259 0.133 ...
##  $ age  : int  24 55 35 26 23 52 25 24 63 31 ...
##  $ type : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 2 1 1 1 2 ...
> str(Pima.te)
## 'data.frame':    332 obs. of  8 variables:
##  $ npreg: int  6 1 1 3 2 5 0 1 3 9 ...
##  $ glu  : int  148 85 89 78 197 166 118 103 126 119 ...
##  $ bp   : int  72 66 66 50 70 72 84 30 88 80 ...
##  $ skin : int  35 29 23 32 45 19 47 38 41 35 ...
##  $ bmi  : num  33.6 26.6 28.1 31 30.5 25.8 45.8 43.3 39.3 29 ...
##  $ ped  : num  0.627 0.351 0.167 0.248 0.158 0.587 0.551 0.183 0.704 0.263 ...
##  $ age  : int  50 31 21 26 53 51 31 33 27 29 ...
##  $ type : Factor w/ 2 levels "No","Yes": 2 1 1 2 2 2 2 1 1 2 ...
> pima <- rbind(Pima.tr, Pima.te)
> str(pima)
## 'data.frame':    532 obs. of  8 variables:
##  $ npreg: int  5 7 5 0 0 5 3 1 3 2 ...
##  $ glu  : int  86 195 77 165 107 97 83 193 142 128 ...
##  $ bp   : int  68 70 82 76 60 76 58 50 80 78 ...
##  $ skin : int  28 33 41 43 25 27 31 16 15 37 ...
##  $ bmi  : num  30.2 25.1 35.8 47.9 26.4 35.6 34.3 25.9 32.4 43.3 ...
##  $ ped  : num  0.364 0.163 0.156 0.259 0.133 ...
##  $ age  : int  24 55 35 26 23 52 25 24 63 31 ...
##  $ type : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 2 1 1 1 2 ...

數據集包含了 532 位女性患者的信息,存儲在兩個數據框中。數據集變量如下。
? npreg :懷孕次數
? glu :血糖濃度,由口服葡萄糖耐量測試給出
? bp :舒張壓(單位為mm Hg)
? skin :三頭肌皮褶厚度(單位為mm)
? bmi :身體質量指數
? ped :糖尿病家族影響因素
? age :年齡
? type :是否患有糖尿病(是 / 否)

> p_load(class, kknn, caret, reshape2, ggplot2, dplyr)
> 
> # 使用箱線圖進行探索性數據分析
> pima.melt <- melt(pima, id.vars = "type")
> head(pima.melt)
##   type variable value
## 1   No    npreg     5
## 2  Yes    npreg     7
## 3   No    npreg     5
## 4   No    npreg     0
## 5   No    npreg     0
## 6  Yes    npreg     5
> ggplot(pima.melt, aes(type, value)) + 
+     geom_boxplot(outlier.colour = "red") + 
+     facet_wrap(~variable, 
+     ncol = 2)
箱線圖進行探索性分析

很難從這張圖發現任何明顯區別,除了血糖濃度( glu ),也間接說明血糖濃度與糖尿病關系很大。
這里最大的問題是,不同統計圖的單位不同,但卻共用一個 Y 軸。所以需要對數據進行標準化處理并重新做圖,進行 KNN 時,使所有特征具有同樣的測量標準是很重要的。如果不進行標準化,那么對最近鄰的距離計算就會出現錯誤。如果一個特征的測量標準是 1~100 ,那么和另一個測量標準為 1~10 的特征相比,肯定會對結果有更大的影響。

> pima.scale <- scale(pima[, 1:7]) %>% as_tibble() %>% bind_cols(type = pima$type)
> head(pima.scale)
## # A tibble: 6 x 8
##    npreg    glu     bp   skin    bmi    ped    age type 
##    <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <fct>
## 1  0.448 -1.13  -0.285 -0.112 -0.391 -0.403 -0.708 No   
## 2  1.05   2.39  -0.122  0.363 -1.13  -0.987  2.17  Yes  
## 3  0.448 -1.42   0.852  1.12   0.423 -1.01   0.315 No   
## 4 -1.06   1.42   0.365  1.31   2.18  -0.708 -0.522 No   
## 5 -1.06  -0.453 -0.935 -0.397 -0.943 -1.07  -0.801 No   
## 6  0.448 -0.775  0.365 -0.207  0.394 -0.363  1.89  Yes
> # 重新生成箱線圖
> pima.scale %>% melt(id.var = "type") %>% 
+     ggplot(aes(type, value)) + 
+     geom_boxplot(outlier.colour = "red") + 
+     facet_wrap(~variable, ncol = 2)
數據標準化后的箱線圖

標準化之后,除了血糖濃度(glu),年齡(age)也可以看出明顯的變化。
查看各個變量之間的相關性:

> pima.scale[, 1:7] %>% cor(.) %>% corrplot::corrplot.mixed(.)
變量之間的相關性

有兩對變量之間具有相關性: npreg / age 和 skin / bmi 。
拆分訓練集和測試集,確保數據劃分平衡是非常重要的,如果某個結果過于稀疏,就會導致問題,可能引起分類器在優勢類和劣勢類之間發生偏離。

> table(pima.scale$type)
## 
##  No Yes 
## 355 177

經驗法則是,結果中的比例至少應該達到 2 ∶ 1 ,可見剛好滿足要求。
將數據拆分為訓練集和測試集:

> set.seed(120)
> ind <- sample(2, nrow(pima.scale), replace = T, prob = c(0.7, 0.3))
> train <- pima.scale[ind == 1, ] %>% as.data.frame()
> test <- pima.scale[ind == 2, ] %>% as.data.frame()
> dim(train)
## [1] 370   8
> dim(test)
## [1] 162   8

2.2 KNN建模與模型評價

> grid1 <- expand.grid(.k = seq(2, 20, by = 1))
> control <- trainControl(method = "cv")
> set.seed(120)
> 
> # 建立計算最優K值的對象
> knn.train <- train(type ~ ., data = train, method = "knn", trControl = control, tuneGrid = grid1)
> knn.train
## k-Nearest Neighbors 
## 
## 370 samples
##   7 predictor
##   2 classes: 'No', 'Yes' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 332, 333, 333, 333, 333, 333, ... 
## Resampling results across tuning parameters:
## 
##   k   Accuracy   Kappa    
##   2  0.7270547  0.3567295
##   3  0.7785641  0.4636882
##   4  0.7999763  0.5132567
##   5  0.7945630  0.4991270
##   6  0.7756441  0.4625649
##   7  0.7918642  0.5000437
##   8  0.7673937  0.4522207
##   9  0.7892366  0.4958273
##   10  0.7893789  0.4891893
##   11  0.7756480  0.4626446
##   12  0.7945669  0.5058332
##   13  0.7918642  0.4906550
##   14  0.7920816  0.4910259
##   15  0.7891576  0.4795236
##   16  0.8055990  0.5188055
##   17  0.7892366  0.4821212
##   18  0.7784218  0.4540767
##   19  0.7784930  0.4501733
##   20  0.7731626  0.4332072
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 16.

除了得到 k = 16 這個結果之外,我們在輸出的表格中還可以看到正確率和 Kappa 統計量的信息,以及交叉驗證過程中產生的標準差。正確率告訴我們模型正確分類的百分比。 Kappa 又稱科恩的K統計量,通常用于測量兩個分類器對觀測值分類的一致性。

查看模型在測試集上的表現:

> # knn不支持tibble,所以前面轉換為dataframe
> knn.test <- class::knn(train[, -8], test[, -8], train[, 8], k = 16)
> table(knn.test, test$type)
##         
## knn.test No Yes
##      No  90  29
##      Yes 13  30

計算準確率:

> accu <- (90 + 30)/nrow(test)
> print(accu)
## [1] 0.7407407

準確率為74%。計算Kappa統計量:

> prob.chance <- ((90 + 29)/nrow(test)) * ((90 + 13)/nrow(test))
> print(prob.chance)
## [1] 0.4670401
> kappa <- (accu - prob.chance)/(1 - prob.chance)
> print(kappa)
## [1] 0.5135483

Kappa統計量的值為0.51,根據 Altman 給出的啟發式的方法中解釋,模型的一致性強度為“中等”。

2.3 加權最近鄰法

加權最近鄰法提高了離觀測更近的鄰居的影響力,降低了遠離觀測的鄰居的影響力。觀測離空間點越遠,對它的影響力的懲罰就越大。
kknn 包中有 10 種不同的加權方式,不加權也是其中之一。它們是: retangular (不加權)、 triangular、 epanechnikov、 biweight、 triweight、 consine、inversion、 gaussian、 rank 和 optimal。

> set.seed(130)
> # distance=1 表示絕對值距離, 2 表示歐氏距離)
> kknn.train <- train.kknn(type ~ ., data = train, kmax = 25, distance = 2, 
+    kernel = c("rectangular",  "triangular", "epanechnikov"))
> plot(kknn.train)
加權最近鄰

圖中 X 軸表示的是 k 值, Y 軸表示的是核函數誤分類觀測百分比。可以調用對象看看分類誤差和最優參數:

> kknn.train
## 
## Call:
## train.kknn(formula = type ~ ., data = train, kmax = 25, distance = 2, 
## + kernel = c("rectangular", "triangular", "epanechnikov"))
## 
## Type of response variable: nominal
## Minimal misclassification: 0.2054054
## Best kernel: rectangular
## Best k: 11

從上面的數據可以看出,最好的核函數是rectangular,說明給距離加權不能提高模型在訓練集上的正確率。看看在測試集上的表現:

> kknn.pred <- predict(kknn.train, newdata = test)
> table(kknn.pred, test$type)
##          
## kknn.pred No Yes
##       No  90  31
##       Yes 13  28
> accu2 <- (90 + 28)/nrow(test)
> tibble(accu1 = accu, accu2 = accu2) %>% print(.)
## # A tibble: 1 x 2
##   accu1 accu2
##   <dbl> <dbl>
## 1 0.741 0.728

從結果可以看出,加權最近鄰法也不能提高測試集上的正確率。

2.4 SVM建模與模型評價

> p_load(e1071, kernlab)
> 
> # tune.svm可以幫助我們選擇調優參數及核函數,使用交叉驗證使調優參數達到最優
> linear.tune <- tune.svm(type ~ ., data = train, kernel = "linear", 
+     cost = c(0.001, 0.01, 0.1, 1, 5, 10))
> summary(linear.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost
##     5
## 
## - best performance: 0.2027027 
## 
## - Detailed performance results:
##    cost     error dispersion
## 1 1e-03 0.3189189 0.06955048
## 2 1e-02 0.2108108 0.06471454
## 3 1e-01 0.2108108 0.04376561
## 4 1e+00 0.2054054 0.04628913
## 5 5e+00 0.2027027 0.04459232
## 6 1e+01 0.2027027 0.04459232

對于這些數據,最優成本函數cost是5,這時的誤分類誤差率差不多為20%。在測試集上進行預測和檢驗:

> best.linear <- linear.tune$best.model
> tune.test <- predict(best.linear, newdata = test)
> table(tune.test, test$type)
##          
## tune.test No Yes
##       No  93  29
##       Yes 10  30

計算準確率:

> accu.svm <- (93 + 30)/nrow(test)
> print(accu.svm)
## [1] 0.7592593

表現比 KNN 稍好一些。現在看看非線性模型能否表現得更好,依然使用交叉驗證選擇調優參數:

> set.seed(150)
> poly.tune <- tune.svm(type ~ ., data = train, kernel = "polynomial", 
+     degree = c(3, 4, 5), coef0 = c(0.1, 0.5, 1, 2, 3, 4))
> summary(poly.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  degree coef0
##       3   0.5
## 
## - best performance: 0.2162162 
## 
## - Detailed performance results:
##    degree coef0     error dispersion
## 1       3   0.1 0.2189189 0.06795684
## 2       4   0.1 0.2324324 0.05582679
## 3       5   0.1 0.2297297 0.05873155
## 4       3   0.5 0.2162162 0.05697798
## 5       4   0.5 0.2270270 0.05435352
## 6       5   0.5 0.2243243 0.05704915
## 7       3   1.0 0.2216216 0.04732946
## 8       4   1.0 0.2513514 0.05104222
## 9       5   1.0 0.2594595 0.05582679
## 10      3   2.0 0.2270270 0.05726216
## 11      4   2.0 0.2756757 0.05222118
## 12      5   2.0 0.2837838 0.05733298
## 13      3   3.0 0.2243243 0.05845452
## 14      4   3.0 0.2729730 0.06552467
## 15      5   3.0 0.2918919 0.08138083
## 16      3   4.0 0.2270270 0.05726216
## 17      4   4.0 0.2729730 0.06795684
## 18      5   4.0 0.2783784 0.08261806

模型選擇的多項式階數為3,核系數為0.5。用這些參數在測試集上進行預測:

> best.poly <- poly.tune$best.model
> poly.test <- predict(best.poly, newdata = test)
> table(poly.test, test$type)
##          
## poly.test No Yes
##       No  89  33
##       Yes 14  26
> accu.svm.2 <- (89 + 26)/nrow(test)
> tibble(accu.svm.1 = accu.svm, accu.svm.2 = accu.svm.2) %>% print
## # A tibble: 1 x 2
##   accu.svm.1 accu.svm.2
##        <dbl>      <dbl>
## 1      0.759      0.710

這個模型的表現還不如線性模型。下面測試徑向基核函數,此處只需找出一個參數 gamma,在0.1 ~ 4中依次檢驗。如果gamma過小,模型就不能解釋決策邊界的復雜性;如果gamma過大,模型就會嚴重過擬合。

> set.seed(150)
> rbf.tune <- tune.svm(type ~ ., data = train, kernel = "radial", 
+     gamma = c(0.1, 0.5, 1, 2, 3, 4))
> summary(rbf.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  gamma
##    0.1
## 
## - best performance: 0.2054054 
## 
## - Detailed performance results:
##   gamma     error dispersion
## 1   0.1 0.2054054 0.06136716
## 2   0.5 0.2297297 0.06890567
## 3   1.0 0.2702703 0.07429019
## 4   2.0 0.3297297 0.08037733
## 5   3.0 0.3216216 0.08683301
## 6   4.0 0.3189189 0.08622332

最優的 gamma 值是0.1,在測試集上測試:

> best.rbf <- rbf.tune$best.model
> rbf.test <- predict(best.rbf, newdata = test)
> table(rbf.test, test$type)
##         
## rbf.test No Yes
##      No  88  32
##      Yes 15  27

計算準確率:

> accu.rbf <- (88 + 27)/nrow(test)
> print(accu.rbf)
## [1] 0.7098765

表現可謂慘不忍睹。最后只能看看kernel="sigmoid"了:

> set.seed(150)
> sigmoid.tune <- tune.svm(type ~ ., data = train, kernel = "sigmoid", 
+     gamma = c(0.1, 0.5, 1, 2, 3, 4), coef0 = c(0.1, 0.5, 1, 2, 3, 4))
> summary(sigmoid.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  gamma coef0
##    0.1   0.1
## 
## - best performance: 0.2081081 
## 
## - Detailed performance results:
##    gamma coef0     error dispersion
## 1    0.1   0.1 0.2081081 0.06747742
## 2    0.5   0.1 0.2810811 0.06136716
## 3    1.0   0.1 0.3108108 0.08475175
## 4    2.0   0.1 0.3081081 0.08753123
## 5    3.0   0.1 0.3378378 0.07775980
## 6    4.0   0.1 0.2702703 0.07207207
## 7    0.1   0.5 0.2621622 0.04942655
## 8    0.5   0.5 0.3081081 0.07001571
## 9    1.0   0.5 0.3270270 0.08494306
## 10   2.0   0.5 0.3000000 0.06036708
## 11   3.0   0.5 0.3108108 0.07982002
## 12   4.0   0.5 0.2972973 0.09275342
## 13   0.1   1.0 0.2702703 0.04225600
## 14   0.5   1.0 0.3162162 0.05104222
## 15   1.0   1.0 0.3243243 0.08641138
## 16   2.0   1.0 0.2945946 0.06036708
## 17   3.0   1.0 0.3216216 0.09227090
## 18   4.0   1.0 0.3270270 0.09740568
## 19   0.1   2.0 0.2270270 0.03648371
## 20   0.5   2.0 0.3459459 0.04558238
## 21   1.0   2.0 0.3270270 0.04843128
## 22   2.0   2.0 0.3405405 0.08936646
## 23   3.0   2.0 0.3270270 0.07368687
## 24   4.0   2.0 0.3216216 0.07478020
## 25   0.1   3.0 0.3189189 0.08622332
## 26   0.5   3.0 0.3540541 0.02974338
## 27   1.0   3.0 0.3594595 0.05560829
## 28   2.0   3.0 0.3000000 0.03916588
## 29   3.0   3.0 0.3351351 0.09379759
## 30   4.0   3.0 0.3054054 0.07961640
## 31   0.1   4.0 0.3189189 0.08622332
## 32   0.5   4.0 0.3459459 0.04732946
## 33   1.0   4.0 0.3567568 0.04732946
## 34   2.0   4.0 0.3243243 0.05697798
## 35   3.0   4.0 0.3108108 0.06890567
## 36   4.0   4.0 0.3324324 0.06626370

看看在測試集上的表現:

> best.sigmoid <- sigmoid.tune$best.model
> sigmoid.test <- predict(best.sigmoid, newdata = test)
> table(sigmoid.test, test$type)
##             
## sigmoid.test No Yes
##          No  90  28
##          Yes 13  31

計算準確率:

> accu.sigmoid <- (90 + 31)/nrow(test)
> print(accu.sigmoid)
## [1] 0.7469136

3、模型選擇

> caret::confusionMatrix(sigmoid.test, test$type, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Yes
##        No  90  28
##        Yes 13  31
##                                           
##                Accuracy : 0.7469          
##                  95% CI : (0.6727, 0.8119)
##     No Information Rate : 0.6358          
##     P-Value [Acc > NIR] : 0.001717        
##                                           
##                   Kappa : 0.4221          
##                                           
##  Mcnemar's Test P-Value : 0.028784        
##                                           
##             Sensitivity : 0.5254          
##             Specificity : 0.8738          
##          Pos Pred Value : 0.7045          
##          Neg Pred Value : 0.7627          
##              Prevalence : 0.3642          
##          Detection Rate : 0.1914          
##    Detection Prevalence : 0.2716          
##       Balanced Accuracy : 0.6996          
##                                           
##        'Positive' Class : Yes             
## 

生成的統計量介紹如下:
? No Information Rate :最大分類所占的比例—— 63% 的人沒有糖尿病
? P-Value :用來進行假設檢驗,說明正確率確實高于No Information Rate
? Mcnemar's Test :我們現在不關心這個統計量,它用于配對分析,主要用于流行病學的研究
? Sensitivity :敏感度,真陽性率;在本案例中,表示沒有糖尿病并且被正確識別的比例
? Specificity :特異度,真陰性率;在本案例中,表示有糖尿病并且被正確識別的比例
? Pos Pred Value :陽性預測率,被認為有糖尿病的人中真的有糖尿病的概率
? Neg Pred Value :陰性預測率,被認為沒有糖尿病的人中真的沒有糖尿病的概率
? Prevalence :患病率,某種疾病在人群中流行度的估計值,本例中的計算方法是第二列(Yes列)中的數之和除以總觀測數(矩陣中所有數之和)
? Detection Rate :真陽性預測中被正確識別的比例,在本案例中,用31除以總觀測數。
? Detection Prevalence :預測的患病率,在本案例中,底行中的數的和除以總觀測數
? Balanced Accuracy :所有類別正確率的平均數。用來表示由于分類器算法中潛在的偏差造成的對最頻繁類的過度預測。可以簡單地用 (敏感度 + 特異度)/2來計算

使用這些結果與線性SVM模型對比:

> confusionMatrix(tune.test, test$type, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Yes
##        No  93  29
##        Yes 10  30
##                                           
##                Accuracy : 0.7593          
##                  95% CI : (0.6859, 0.8229)
##     No Information Rate : 0.6358          
##     P-Value [Acc > NIR] : 0.0005302       
##                                           
##                   Kappa : 0.4418          
##                                           
##  Mcnemar's Test P-Value : 0.0039478       
##                                           
##             Sensitivity : 0.5085          
##             Specificity : 0.9029          
##          Pos Pred Value : 0.7500          
##          Neg Pred Value : 0.7623          
##              Prevalence : 0.3642          
##          Detection Rate : 0.1852          
##    Detection Prevalence : 0.2469          
##       Balanced Accuracy : 0.7057          
##                                           
##        'Positive' Class : Yes             
## 

兩個模型的結果差不多,線性SVM模型的準確率稍微還要高一些。

4、SVM中的特征選擇

前面做的工作就是把特征堆在一起,作為所謂的輸入空間,然后讓 SVM 這個黑盒去計算,最后給出一個預測分類。使用 SVM 的一個主要問題就是,它給出的結果非常難以解釋。
但是,還有一些其他辦法可以進行特征選擇:

> set.seed(150)
> rfeCNTL <- rfeControl(functions = lrFuncs, method = "cv", number = 10)
> 
> # rfe() 函數執行一個遞歸的特征選擇過程 
> # functions可以使用幾種不同的參數,此處使用lrFuncs
> # sizes 指定輸入特征的數量 kernlab包中的線性方法svmLinear,還有其他選項
> svm.features <- rfe(train[, 1:7], train[, 8], sizes = c(7, 6, 5, 4), 
+     rfeControl = rfeCNTL, method = "svmLinear")
> # 查看不同數量特征模型的表現
> svm.features
## 
## Recursive feature selection
## 
## Outer resampling method: Cross-Validated (10 fold) 
## 
## Resampling performance over subset size:
## 
##  Variables Accuracy  Kappa AccuracySD KappaSD Selected
##          4   0.7972 0.5055    0.05044  0.1189         
##          5   0.7973 0.5094    0.04839  0.1175        *
##          6   0.7945 0.5025    0.05096  0.1190         
##          7   0.7945 0.5025    0.05096  0.1190         
## 
## The top 5 variables (out of 5):
##    glu, npreg, bmi, ped, bp

出乎意料,五特征模型表現得相當好。看看在測試集上的表現:

> svm.5 <- svm(type ~ glu + npreg + bmi + ped + bp, data = train, kernel = "linear")
> test.new <- test %>% select(c("glu", "npreg", "bmi", "ped", "bp"))
> svm.5.predict <- predict(svm.5, newdata = test.new)
> confusionMatrix(svm.5.predict, test$type, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Yes
##        No  91  29
##        Yes 12  30
##                                           
##                Accuracy : 0.7469          
##                  95% CI : (0.6727, 0.8119)
##     No Information Rate : 0.6358          
##     P-Value [Acc > NIR] : 0.001717        
##                                           
##                   Kappa : 0.4177          
##                                           
##  Mcnemar's Test P-Value : 0.012462        
##                                           
##             Sensitivity : 0.5085          
##             Specificity : 0.8835          
##          Pos Pred Value : 0.7143          
##          Neg Pred Value : 0.7583          
##              Prevalence : 0.3642          
##          Detection Rate : 0.1852          
##    Detection Prevalence : 0.2593          
##       Balanced Accuracy : 0.6960          
##                                           
##        'Positive' Class : Yes             
## 

表現與全特征模型差不多。通過反復實驗,你可以看到這種方法是如何工作的,它的目的是對特征重要性做一個簡單的鑒別。

總結:

  • 1.KNN,包括不加權和加權的最近鄰算法;
  • 2.SVM,包括線性和非線性支持向量機;
  • 3.使用caret包進行粗略的特征選擇。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容