懒惰学习——使用近邻分类(KNN)

    xiaoxiao2021-03-26  30

    KNN算法

    优点:

    简单有效;对数据的分布没有要求;训练阶段很快。

    缺点:

    不产生模型,在发现特征之间的关系上的能力有限;分类阶段很慢;需要大量的内存;名义变量(特征)和缺失数据需要额外处理。

    之所以被称为懒惰学习算法,是因为从技术上说,没有抽象化的步骤。抽象过程与一般过程都被跳跃过去了。由于高度依赖训练案例,所以懒惰学习又称为机械学习。机械学习不会建立一个模型,所以该方法被归类为非参数学习方法。

    案例用KNN算法诊断乳腺癌

    第一步——收集数据

    数据来源于UCI机器学习数据仓库的“威斯康星乳腺癌诊断”(Brest Cancer Wisconsin Diagnostic)数据集,网址:http://archive.ics.uci.edu/ml/

    数据集包括569个细胞活检案例,每个案例32个特征。一个特征是识别号,一个特征是诊断结果,其他30个特征是数值型测量结果,诊断结果用“M”表示恶性,“B”表示良性。

    第二步——探索和准备数据

    首先导入CSV文件:

    wbcd<-read.csv("wisc_bc_data.csv",header=F)

    第一个变量信息id不能提供有用信息,所以删除:

    wbcd<-wbcd[-1]

    使用table函数查看恶性和良性肿瘤个数:

    table(wbcd$V2) B M 357 212

    许多R机器学习分类器要求将目标属性编码为因子变量,所以重新编码wbcd的第一列,同时用labels参数对B值和M值给出更多信息:

    wbcd$V2<-factor(wbcd$V2,levels=c("B","M"),labels=c("Benign","Malignant")) round(prop.table(table(wbcd$V2))*100,digits=1) Benign Malignant 62.7 37.3

    由上述代码可知,Benign和Malignant分别有62.7%与37.3%。

    1. 转换——min-max标准化数值型数据

    首先建立一个函数:

    normalize<-function(x){ return((x-min(x))/(max(x)-min(x))) }

    把函数normalize应用于30个数值化特征,使用lapply函数,再用as.data.frame函数把lapply函数返回的列表转化成数据框:

    wbcd_n<-as.data.frame(lapply(wbcd[2:31],normalize))

    2. 数据准备——创建训练数据集和测试数据集

    wbcd_train<-wbcd_n[1:469,] wbcd_test<-wbcd_n[470:569,]

    再把类的标签存储在一个引子类型的向量中:

    wbcd_train_labels<-wbcd[1:469,1] wbcd_test_labels<-wbcd[470:569,1]

    第三步——基于数据训练模型

    使用class包中的knn函数:

    library(class) wbcd_test_pred<-knn(train=wbcd_train,test=wbcd_test,cl=wbcd_train_labels,k=21)

    其中,train是一个包含数值型训练数据的数据框;test是一个包含数值型测试数据的数据框;class是包含训练数据每一行分类的一个因子向量;k是标识最近邻树木的一个整数。k的值应该为训练数据样本的平方根数。即由于训练数据集含有469个实例,则尝试k=21。

    第四步——评估模型的性能

    该过程就是评估wbcd_test_pred与wbcd_test_labels中已知的值的匹配程度。使用gmodels包中的CrossTable函数:

    library(gmodels) CrossTable(x=wbcd_test_labels,y=wbcd_test_pred,prop.chisq=F) Cell Contents |-------------------------| | N | | N / Row Total | | N / Col Total | | N / Table Total | |-------------------------| Total Observations in Table: 100 | wbcd_test_pred wbcd_test_labels | Benign | Malignant | Row Total | -----------------|-----------|-----------|-----------| Benign | 77 | 0 | 77 | | 1.000 | 0.000 | 0.770 | | 0.975 | 0.000 | | | 0.770 | 0.000 | | -----------------|-----------|-----------|-----------| Malignant | 2 | 21 | 23 | | 0.087 | 0.913 | 0.230 | | 0.025 | 1.000 | | | 0.020 | 0.210 | | -----------------|-----------|-----------|-----------| Column Total | 79 | 21 | 100 | | 0.790 | 0.210 | | -----------------|-----------|-----------|-----------|

    从表格中看出假阴性有2个,假阳性0个,正确率98%。

    第五步——提高模型性能

    对前面的分类器,尝试两种改变,一种是用另一种方法标准化,另一个是尝试不同的k值。

    1. 转换——z-score标准化

    wbcd_z<-as.data.frame(scale(wbcd[-1]))

    再进行同样的步骤:

    wbcd_train<-wbcd_z[1:469,] wbcd_test<-wbcd_z[470:569,] wbcd_train_labels<-wbcd[1:469,1] wbcd_test_labels<-wbcd[470:569,1] wbcd_test_pred<-knn(wbcd_train,wbcd_test,cl=wbcd_train_labels,k=21) CrossTable(x=wbcd_test_labels,y=wbcd_test_pred,prob.chisq=F) Cell Contents |-------------------------| | N | | Chi-square contribution | | N / Row Total | | N / Col Total | | N / Table Total | |-------------------------| Total Observations in Table: 100 | wbcd_test_pred wbcd_test_labels | Benign | Malignant | Row Total | -----------------|-----------|-----------|-----------| Benign | 77 | 0 | 77 | | 4.298 | 16.170 | | | 1.000 | 0.000 | 0.770 | | 0.975 | 0.000 | | | 0.770 | 0.000 | | -----------------|-----------|-----------|-----------| Malignant | 2 | 21 | 23 | | 14.390 | 54.134 | | | 0.087 | 0.913 | 0.230 | | 0.025 | 1.000 | | | 0.020 | 0.210 | | -----------------|-----------|-----------|-----------| Column Total | 79 | 21 | 100 | | 0.790 | 0.210 | | -----------------|-----------|-----------|-----------|

    可以看出结果没有改变。另一种方法是改变k值,在此就不在列出。

     

     

     

     

     

     

     

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-658737.html

    最新回复(0)