(学习笔记,来源于美Brett Lantz著,李洪成译的《机器学习与R语言》)
也应当和算法学习类似,首先搞清楚算法/方法的原理,再考虑实现问题。
1、邻近分类概念
首先已经看出来这是用于分类的一类方法,不是某一个算法,原理是先把训练数据进行训练并标记,然后将未标记的案例归类为与之最相近的已标记的案例的所在类。就是物以类聚。
2、相关算法
a) kNN(k-Nearest Neighbor,k近邻)算法
这里有训练数据集和测试数据集,kNN算法会利用训练数据集进行训练,这些是已经分类了的数据;并设定一个k,即找到k个与测试案例最相近、相似度最高的训练案例,然后再从这k个训练案例的分类情况,来判别测试案例属于哪个类。
举个栗子,我有一组数据集,是记录部分学生的部分指标成绩以及是否为优秀学生的评价,大致如下:
假设有n项指标,有m个案例{A,B,C….},以及对每个指标的评价,这里就只有两个分类。
这时我们多了一位学生N以及其指标打分如下,作为测试案例判断他是否为优秀学生。
利用kNN算法,计算N与每一个训练案例的距离,并选出距离最近的k个案例,假设k=6,结果如下:
可以看到,前k个最邻近案例中,2/3为优秀学生,即N离优秀学生更近,因此我们判断N也是属于优秀学生一类。
大致原理和过程就这样。
a) 注意事项
首先是数据的整理,为了使结果不被类似单位差异的因素影响,因此需要将数据标准化处理,常用的有min-max标准化,z-score标准化。
然后是距离的选择,一般使用欧氏距离,即“直线距离”。
还有k的选择,一般设置k为训练数据集中案例数量的平方根。
最后是实现。
b) 算法实现与R语言
书中给的案例是关于诊断乳腺癌的数据,数据包括了569例细胞活检案例,每个案例有包含识别号码(等会会删除的无用特征)和诊断结果(恶性与良性)在内的32个特征。诊断结果用“M”表示恶性,“B”表示良性。大致如下(图片下面有数据情况):
数据是在http://archive.ics.uci.edu/ml/网站下载的,上面有很多可用于机器学习的免费数据。
第一步数据收集完成。
第二步数据整理。
数据内容我就不展示了,数据整理涉及如下:检查数据的完整性、可用性;对数据清洗,删除没用的;对数据格式等进行修改,比如时间、标准化等。
在这里需要做的有删除第一列无用的“号码”特征,对分类进行因子化、贴标签,对数据进行标准化处理。最后我们将569个案例,469个作为训练案例,100个作为测试案例。
R语言代码如下,我尽量详细(按顺序来)。
首先是读取数据和查看数据:
利用str()和table()查看如下:
表明有357个良性和212和恶性。
接下来对diagnosis进行因子化和标签。
我们已经知道不同指标的数值范围不同,因此接下来需要对数据标准化处理,你也可以先用summary()函数查看数值分布情况。
我们创建一个标准化函数,如下,运行后使用:
这里讲标准化后的特征值保存为一个新的数据框。一切准备就绪,接下来是:
第三步,数据准备:训练数据集与测试数据集
一共有569个案例,我们将前469个作为训练数据,后100个作为测试数据。然后我们单独将这两个数据集的diagnosis标签分出来,等会儿在训练和评估中要用:
第四步,训练模型
R中的class包里有关于kNN的算法实现,安装和加载class。里面的knn()函数提供标准的kNN实现。对于测试数据集中的每一个实例,采用欧氏距离标识k个近邻,然后通过“投票”——看比例来决定所在类别。
结果如下:
差不多了,也该吃饭了。
第五步,评估。已经说了是测试数据,是为了测试这个算法可行性高低,因此有评估这步。
评估我们的算法结果wbcd_test_pred与真实的分类标签wbcd_test_labels向量的匹配程度。我们利用gmodels包里面的CrossTable()函数,建立两个向量的交叉表。
结果如下:
这里的结果主要看中间的四个单元格,结合行列标签,左上角的表示有72个案例预测结果和实际分类都为Bengin良性。右下角表示有22个案例预测结果和实际分类都为Malignat恶性。左下角表示有1个案例被模型预测为良性但实际为恶性,右上角表示有5个案例被模型预测为恶性但实际为良性的节骨。
总体来看,失误率为6%,虽然比较小,但在这个案例中,一点误差可能都会造成严重损失。
完整代码:
以上。
2016/12/13