《机器学习实战》学习笔记:K-近邻算法

一、定义

k-近邻算法就是采用特定方法计算多个特征值之间的距离,来对数据进行分类的算法。

优点:精度高、对异常值不敏感、无数据输入假定

缺点:计算复杂度高、空间复杂度高

适用数据范围:数值型和标称型

二、工作原理

首先需要有一个已经标注过的数据集合,其中的每个数据都有已知的标签。每次输入没有标签的数据后,将新的数据每个特征与样本集中数据对应的特征进行比较,然后算法找出样本集中特征最相似数据的标签。算法选取最相似的前k个数据的标签,出现次数最多的分类作为新数据的分类标签。

一般流程:

收集数据 - 准备数据 - 分析数据 - 测试算法 - 使用算法

三、简单的用例

先定义一个训练集,也就是上面所说的已标注的集合:

group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']

解释一下:group就是数据集,里面有四个数据(每个数组表示一个数据,数组各个位置的内容即为各个特征的值);labels为已标注的标签,表示上面的四个数据分别对应的标签

然后编写算法:

from numpy import *
import operator

def classify0(inX, dataSet, labels, k): #第一个参数是输入的数据,是一个特征数组(表示一个数据),第二个和第三个参数分别是已标注的数据集,标记集,第四个参数就是kNN算法中的k
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()     
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]
运行:
>>> classify0([0,0],group, labels,2)

就能得到结果

四、实用案例

书本中说到了一个通过KNN算法(k-近邻算法)来判断约会对象是否心仪的程序,接下来实现一下:

1. 收集和准备数据:直接通过书本附带的数据来提取特征矩阵和标注信息:

数据:(第一列为约会对象的每年的飞行里程数,第二列为玩视频游戏所占时间比重,第三列为每周吃掉的冰淇淋公升数,第四列为主人公小黑对此人的态度,分为三种:很心仪largedoses、有点心动smalldoses和不喜欢didn'tlike)前三者为特征,最后一列主人公的态度即为我们所需要的标签,我们的目的就是给出一个约会对象(包含前三个特征),判断出小黑是否喜欢她:

40920	8.326976	0.953952	largeDoses
14488	7.153469	1.673904	smallDoses
26052	1.441871	0.805124	didntLike
75136	13.147394	0.428964	didntLike
38344	1.669788	0.134296	didntLike
72993	10.141740	1.032955	didntLike
35948	6.830792	1.213192	largeDoses
42666	13.276369	0.543880	largeDoses
67497	8.631577	0.749278	didntLike
35483	12.273169	1.508053	largeDoses
50242	3.723498	0.831917	didntLike
63275	8.385879	1.669485	didntLike
5569	4.875435	0.728658	smallDoses
51052	4.680098	0.625224	didntLike
77372	15.299570	0.331351	didntLike
43673	1.889461	0.191283	didntLike
61364	7.516754	1.269164	didntLike
69673	14.239195	0.261333	didntLike
15669	0.000000	1.250185	smallDoses
28488	10.528555	1.304844	largeDoses
6487	3.540265	0.822483	smallDoses
37708	2.991551	0.833920	didntLike
22620	5.297865	0.638306	smallDoses
28782	6.593803	0.187108	largeDoses
19739	2.816760	1.686209	smallDoses
36788	12.458258	0.649617	largeDoses
5741	0.000000	1.656418	smallDoses
28567	9.968648	0.731232	largeDoses
6808	1.364838	0.640103	smallDoses
41611	0.230453	1.151996	didntLike
36661	11.865402	0.882810	largeDoses
43605	0.120460	1.352013	didntLike
15360	8.545204	1.340429	largeDoses
63796	5.856649	0.160006	didntLike
10743	9.665618	0.778626	smallDoses
70808	9.778763	1.084103	didntLike
72011	4.932976	0.632026	didntLike
5914	2.216246	0.587095	smallDoses
14851	14.305636	0.632317	largeDoses
33553	12.591889	0.686581	largeDoses
44952	3.424649	1.004504	didntLike
17934	0.000000	0.147573	smallDoses
27738	8.533823	0.205324	largeDoses
29290	9.829528	0.238620	largeDoses
42330	11.492186	0.263499	largeDoses
36429	3.570968	0.832254	didntLike
39623	1.771228	0.207612	didntLike
32404	3.513921	0.991854	didntLike
27268	4.398172	0.975024	didntLike
5477	4.276823	1.174874	smallDoses
14254	5.946014	1.614244	smallDoses
68613	13.798970	0.724375	didntLike
41539	10.393591	1.663724	largeDoses
7917	3.007577	0.297302	smallDoses
21331	1.031938	0.486174	smallDoses
8338	4.751212	0.064693	smallDoses
5176	3.692269	1.655113	smallDoses
18983	10.448091	0.267652	largeDoses
68837	10.585786	0.329557	didntLike
13438	1.604501	0.069064	smallDoses
48849	3.679497	0.961466	didntLike
12285	3.795146	0.696694	smallDoses
7826	2.531885	1.659173	smallDoses
5565	9.733340	0.977746	smallDoses
10346	6.093067	1.413798	smallDoses
1823	7.712960	1.054927	smallDoses
9744	11.470364	0.760461	largeDoses
16857	2.886529	0.934416	smallDoses
39336	10.054373	1.138351	largeDoses
65230	9.972470	0.881876	didntLike
2463	2.335785	1.366145	smallDoses
27353	11.375155	1.528626	largeDoses
16191	0.000000	0.605619	smallDoses
12258	4.126787	0.357501	smallDoses
42377	6.319522	1.058602	didntLike

这里只附上了部分原数据,要全的去这里下载。

2.接下来编写一个函数(与书本上的不同,书本上的笔者用python3.64编译不通过,下面是自己修改的程序)来将数据处理成前面能够拿来训练的数据结构:

from os import listdir
def file2matrix(filename):
    fr = open(filename)
    numberOfLines = len(fr.readlines())         #get the number of lines in the file
    returnMat = zeros((numberOfLines,3))        #prepare matrix to return
    classLabelVector = []                       #prepare labels return   
    fr = open(filename)
    index = 0
    for line in fr.readlines():
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        if listFromLine[3][0]=='l':
            classLabelVector.append(1)
        else:
            if listFromLine[3][0]=='s':
                classLabelVector.append(2)
            else:
                classLabelVector.append(3)                
        index += 1
    return returnMat,classLabelVector

然后使用这个函数处理该数据文本,就能得到数据矩阵和标签集了,接下来就可以使用算法进行分类了

然而仅进行这一步可能结果会不那么准确,我们对算法加以改进

3.特征归一化

从上面的数据我们可以看出,由于计算距离的公式对各个特征的处理都是一样的,所以差值越大的特征对结果的影响更大,而差值在不同的数量级往往是由于特征数值的不同造成的,比如这个例子中的飞行里程数相对另两个就显得大得多,从而使得飞行里程数对于结果的影响更大,而我们也希望各个特征都更加“平等”的对待,所以我们使用下面的数学方法来处理各个特征数值:

newValue = (OldValue-min)/(max-min)

通过这个公式,各个数值都将被修改成[0,1]内的数值,这样就使得各个特征等权重

编写一个函数来实现上述过程:

def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals, (m,1))
    normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide
    return normDataSet, ranges, minVals

通过这个函数对file2matrix的处理结果进行进一步的加工(归一化),再将得到的数据集和标签集作为分类函数classify0()的输入参数来对新数据进行分类,将得到更好的效果(希望是三个特征都平等考虑的情况下)。

4.测试算法

最好将收集的数据(已标注)分出一部分来用作测试数据,在算法完成后用这部分数据来测试,看看不同的k值对应的准确率如何。

5.编写函数前端

这里说的不是具体的可视化界面,而是说最好编写一个函数,提示你输入一个约会对象的这三个特征,然后给出结果的python程序。当然,做一个可视化界面更好;)

五、小结

KNN算法作为《机器学习实战》这本书入门的第一个算法,讲出了分类就是机器学习的一种,还是比较好理解的。这个算法就是不断计算未标记向量和已有向量集中的向量之间的距离,找出距离最近的k个向量对应的标签,最多的标签就贴给这个新的未标记变量。

k值的选取和距离计算的方法都必须好好地设计一番,配合特征归一化,用测试集进行测试,来达到更好的分类效果。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值