懒惰学*-邻*分类

(学*笔记,来源于美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

posted @ 2017-02-09 20:18  隔壁老任  阅读(650)  评论(0编辑  收藏  举报