kNN算法根据不同病理特征来预测乳腺癌转移与否

kNN算法也称k最近邻算法,因其没有复杂的数据推导公式、且核心思想易于理解,作为机器学习“敲门砖”再合适不过。

因为个人时间关系,我们生信技能树的统计学专题一直无法收官,感兴趣的还是可以查看往期精彩:

这个间隙推荐一下生信补给站的笔记!

一 、kNN概念

本文介绍机器学习中的分类算法kNN(k-NearestNeighbor),即k邻近算法。核心思想类似“近朱者赤近墨者黑”,每个样本都可以用它最接近的k个邻居来代表。

给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最近邻的K个实例,这K个实例的多数属于某个类,就把该输入实例分为这个类。

img

例如如果要判断Xu 的颜色,只需要找到与其距离最近的5个点,发现有4个红色,1个绿色,因此可以认为Xu是属于红色的集合。

根据上述kNN的算法思想,可以梳理kNN算法主要流程如下:

  1. 计算测试对象到训练集中每个对象的距离,并按照距离的远近排序;

  2. 选取与当前测试对象最近的k个训练对象(K值自己定义);

  3. 测试对象即为k个邻居里频率最高的类别。

二 ,kNN预测乳腺癌

下面以一个乳腺癌预测的实例完成kNN算法的深入了解:

1 加载数据

使用威斯康星州临床科学中心的关于乳腺癌肿瘤的数据集。https://www.kaggle.com/uciml/breast-cancer-wisconsin-data 简单注册即可下载 breast-cancer-wisconsin-data.zip文件,解压后就可以进行下面我们演示的流程啦。

#载入数据
cancer <- read.csv('breast_cancer.csv',stringsAsFactors = F)
#查看数据情况
dim(cancer)
head(cancer,2)
str(cancer)

首先是对数据的一些认知,基础函数,其实大家看官网对这个乳腺癌肿瘤的数据集更炫酷。

乳腺癌数据包括569例细胞活检案例,每个案例有32个特征。

其中通过str(cancer)发现id是int,diagnosis诊断类型为character(编码“M”表示恶性,用编码“B”表示良性),其余30个特征均为numeric的实验室测量结果(10个不同特征的均值、标准差和最差值(即最大值))。

这些特征包括:Radius(半径)、Texture(质地)、、Perimeter(周长)、 Area(面积)、Smoothness(光滑度)、 Compactness(致密性)、 Concavity(凹度)、 Concave points(凹点)、 Symmetry(对称性)、Fractal dimension(分形维数)。可猜到似乎都与细胞核的形状和大小有关,但是很难知道每个特征如何诊断良性或者恶性的。

没关系,可以使用kNN(机器学习)算法进行“诊断”,并判断准确性如何?

2 数据探索和准备

2.1 数据探索

机器学习分类器要求将目标属性编码为因子类型,重新编码diagnosis变量,使用labels参数对B值和M值给出更多信息

#标识id列去掉
cancer_new <- cancer[,c(-1)]
##查看数据缺失情况,重要
sum(is.na(cancer_new))
[1] 0

#把diagnosis特征加上标签,和M的简写改成全称方便识别(推荐)
cancer_new$diagnosis <- factor(cancer_new$diagnosis,
                               levels = c("B","M"),
                               labels = c("benign","malignant"))
#查看乳腺癌良性和恶性的分布概率
round(prop.table(table(cancer_new$diagnosis))*100,2)

benign malignant 
    62.74     37.26 

2.2 数值归一化

当数据的量纲不同,就不能反映样本中每一个特征的重要程度。处理方式就需要数据归一化,把所有的数据都映射到同一个尺度(量纲)上。

#取几个特征观察数值差异
summary(cancer_new[,2:5])

radius_mean      texture_mean   perimeter_mean     area_mean     
 Min.   : 6.981   Min.   : 9.71   Min.   : 43.79   Min.   : 143.5  
 1st Qu.:11.700   1st Qu.:16.17   1st Qu.: 75.17   1st Qu.: 420.3  
 Median :13.370   Median :18.84   Median : 86.24   Median : 551.1  
 Mean   :14.127   Mean   :19.29   Mean   : 91.97   Mean   : 654.9  
 3rd Qu.:15.780   3rd Qu.:21.80   3rd Qu.:104.10   3rd Qu.: 782.7  
 Max.   :28.110   Max.   :39.28   Max.   :188.50   Max.   :2501.0 

30个特征都是numeric值,通过以上取几个特征值发现差异较大,需要通过标准化normalization减少数值之间的差异。

#min-max标准化
normalization_01 <- function(x){
  return((x-min(x))/(max(x)-min(x)))
}
#所有numeric类型的特征min-max标准化
cancer_new[2:31] <-as.data.frame(lapply(cancer_new[2:31], normalization_01))
summary(cancer_new[,2:5])

radius_mean      texture_mean    perimeter_mean     area_mean     
 Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
 1st Qu.:0.2233   1st Qu.:0.2185   1st Qu.:0.2168   1st Qu.:0.1174  
 Median :0.3024   Median :0.3088   Median :0.2933   Median :0.1729  
 Mean   :0.3382   Mean   :0.3240   Mean   :0.3329   Mean   :0.2169  
 3rd Qu.:0.4164   3rd Qu.:0.4089   3rd Qu.:0.4168   3rd Qu.:0.2711  
 Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  

到此为止,数据清洗阶段才算是完成,这个过程需要有对数据的整体认知!

2.3 拆分测试集和训练集

数据清洗完成之后,通过划分测试集和训练集来建模预测

#随机取样分为训练集和测试集,按8:2比例拆分
set.seed(123) ## 设置随机数种子,方便重复性研究
index <- sample(1:nrow(cancer_new),size = nrow(cancer_new)*0.8,replace = F)
cancer_train <- cancer_new[index,]
cancer_test <- cancer_new[-index,]
dim(cancer_train)
[1] 455  31
dim(cancer_test)
[1] 114  31

查看训练集和测试集中因变量的比重是否与总体吻合,很容易被忽视

round(prop.table(table(cancer_train$diagnosis))*100,2)

benign malignant 
    62.64     37.36

round(prop.table(table(cancer_test$diagnosis))*100,2)

benign malignant 
    63.16     36.84 

抽样效果还不错,训练集和测试集的因变量比例与总体因变量比例大体相当。

除了我们这样的随机数抽样,还有可以使用成熟的R包进行划分训练集和测试集。

3 KNN算法建模预测

3.1 R-class包中knn参数

本文使用的是R-class包里面的knn()函数:

knn(train, test, cl, k = 1, l = 0, prob = FALSE, use.all = TRUE)

train:指定训练样本集
test :指定测试样本集
cl :指定训练样本集中的分类变量
k :指定最邻近的k个已知分类样本点,默认为1
l :指定待判样本点属于某类的最少已知分类样本数,默认为0
prob:设为TRUE时,可以得到待判样本点属于某类的概率,默认为FALSE
use.all:如果有多个第K近的点与待判样本点的距离相等,默认情况下将这些点都纳入判别样本点.

大部分参数了解一下就好,总之就是使用所有其它参数来预测benign malignant。

3.2 kNN预测乳腺癌

将k值设为训练集样本数量的平方根(K=21)

library(class)
knn_model_predict <- knn(train=cancer_train[,-1],test=cancer_test[,-1],cl=cancer_train$diagnosis,k=21)
#查看准确率
sum(knn_model_predict == cancer_test[,1])/dim(cancer_test)[1]
[1] 0.9736842

#交叉表展示
library(gmodels)
CrossTable(x=cancer_test[,1],y=knn_model_predict,prop.chisq = F)

上图左上角的格子表示真阴性,分类器结果和临床结果一致认为是良性。右下角就是真阳性结果,分类器和临床一致认为是恶性(重要)。左下是假阴性,预测为良性实际是恶性(糟糕)。右上角是假阳性,预测是恶性实际是良性。

计算得到模型的准确率为(39+72)/ (39+72+3) * 100 = 97.37%,接下来我们测试一下不同k值对模型准确率的影响。

注:除准确率外,还有其他评价分类结果准确性的判断依据:精准率、召回率、F1 Score、ROC曲线等。

3.3 knn算法中K值的确定

knn为k近邻算法,需要解决的是选择一个合适的k值,可以结合训练集和测试集,循环k值,直到挑选出使测试集的准确率最高的k值。

#计算不同k值下的accuracy
result_k <- NULL
#从1循环到样本数量均方根
for(k in 1:round(sqrt(dim(cancer_train)[1]))){
  knn_model_predict <- knn(train=cancer_train[,-1],test=cancer_test[,-1],cl=cancer_train$diagnosis,k)
  result <- (table(knn_model_predict,cancer_test[,1])[1,1]+table(knn_model_predict,cancer_test[,1])[2,2])/dim(cancer_test)[1]
  result_k <- append(result_k,result)
  print(result)
}
[1] 0.9561404
[1] 0.9736842
[1] 0.9824561
[1] 0.9824561
[1] 0.9824561
[1] 0.9649123
[1] 0.9912281
[1] 0.9824561
[1] 0.9824561
[1] 0.9912281
[1] 0.9912281
[1] 0.9912281
[1] 0.9824561
[1] 0.9736842
[1] 0.9824561
[1] 0.9824561
[1] 0.9736842
[1] 0.9736842
[1] 0.9736842
[1] 0.9736842
[1] 0.9736842

#绘制结果折线图
x <- c(1:21)
plot(result_k,type = "o",xaxt="n")
axis(1,at=seq(1,21),labels = x) 

 

可以看到当k为7、10、11、12时模型准确率最高。

3.4 最优K值模型预测

knn_model_predict <- knn(train=cancer_train[,-1],test=cancer_test[,-1],cl=cancer_train$diagnosis,k=7)

CrossTable(x=cancer_test[,1],y=knn_model_predict,prop.chisq = F)

 

发现假阴性减少了2个,总体上预测的精度提高到了(72+41)/(72+41+1+0) * 100 =99.12% 。

三 kNN算法注意点

1)缺失值:k近邻需要计算距离,因此数据中不能含有缺失值;

2)数据标准化:knn()函数在调用前需标准化数据,可尝试其他标准化方式;

3)最优K值确定:k过小,噪声对分类的影响就会变得非常大,K过大,很容易误分类;

参考资料

《机器学习与R语言》

最后的最后

我们送书吧,图灵出版社每个月赞助我们生信技能树10本书,好像有几个月没有使用了,一忙就忘记了,粉丝最近支持力度(活跃度)也很小,活动搞起来没有啥意思。但,没意思也总比浪费好,还是搞一搞吧。

就是下面这本书咯!(老规矩,真粉丝可以拿到,根据留言精选)

规则参考:中秋节讲义赠送发货通知

Mastering Machine Learning with R, Second Edition

《精通机器学习:基于R(第2版)》

  • 利用 R 包轻松应用机器学习方法

  • 展示各类机器学习方法的优势与潜在问题

  • 技术与理论并重,通过丰富的商业案例实现机器学习高级概念

  • 在 AWS 等云平台上利用 R 亲手实践机器学习

(0)

相关推荐