机器学习实战 k-近邻算法

来源:互联网 发布:bt python源代码下载 编辑:程序博客网 时间:2024/04/29 23:58

边看书边看代码,结合自己的理解总结。
概括:
1.思想:计算测试样本与训练集对应特征值之间的距离(文中用的是欧式距离),认为与测试样本距离最近的k个样本可以用来描述这个测试样本,取这k个训练样本中出现最多次的类别,作为这个测试样本的类别。
2.优点:精度高,对异常值不敏感
3.缺点:复杂度高
4.适用范围:数值型和标称型
(数值型主要是指它的目标变量可以从无限的数值集合中取值,标称型指的是在有限目标机中取值)

算法分析:
0.训练集必须是已标记的样本,首先对训练集样本的特征值归一化
1.计算测试样本(测试样本同样要归一化)与所有训练样本的欧氏距离
2.按照距离递增排序,选择前k个样本点
3.确定这k个样本所在类别的出现频率,出现频率最高的类别即为测试样本的类别
4.文中给的评判分类器的标准是错误率=测试集中分类错误的个数/测试集样本数

#python 使用前安装numpyfrom numpy import *import operatorfrom os import listdirdef classify0(inX, dataSet, labels, k):# kNN分类# 输入测试集inX 训练集dataSet 训练集标签labels 前k个近邻,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):#选前k个样本        voteIlabel = labels[sortedDistIndicies[i]]        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1    #存储出现的类别的次数    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)    #类别排序,选择出现次数最多的作为测试样本的类别    return sortedClassCount[0][0]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))    #归一化=(原-最小值)/(最大值-最小值)    #element wise divide    return normDataSet, ranges, minValsdef datingClassTest():#对分类器的测试    hoRatio = 0.20#选择样本的10%当做测试集,参数可调    datingDataMat,datingLabels = file2matrix('测试集.txt')    #从文件中读取数据       #load data setfrom file    normMat, ranges, minVals = autoNorm(datingDataMat)#归一化    m = normMat.shape[0]#样本总数    numTestVecs = int(m*hoRatio)#测试集总数    errorCount = 0.0    for i in range(numTestVecs):        classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)                                    #每次输入测试集,训练集总样本,训练集标签,近邻k        #得到测试结果和测试集标签        if (classifierResult != datingLabels[i]): errorCount += 1.0        #如果预测错误,则错误个数加一    print "the total error rate is: %f" % (errorCount/float(numTestVecs))#最后算出错误率    print errorCount

从代码中也可以看出,knn的确是简单有效,但是算法必须保存全部的数据集,每一次测试时必须与所有样本计算距离,并且也无法给出数据的基础结构信息(比如特征具有什么样的特点)。

0 0
原创粉丝点击