使用Peter的机器学习实战学习了knn算法
算法流程:
1.算出测试点与所有训练点直接的距离(两点直接的距离公式,如果是多个点参照两点直接的距离公式)
2.为所有距离进行升序排列
3.取排序完毕的前k个点对其标签进行统计,最多的那个则为对应的标签
使用书上0-9数据集(每个数字都有接近200个样本)进行训练和测试的时候发现,k为3时最佳,k变大时错误率会上升,越大错的越多
因为数据的某两个属性的差值可能很大,会对欧式公式的距离计算造成很大影响,所以应该先进行数据的归一化
作者使用了max-min方法进行数据归一化,使所有的数值都落在[0,1]之间其公式为
注意:这里的max和min为整个数据集中每列(每种特征)的最大值和最小值,也就是说每种特征的最大值和最小值要单独计算
k近邻可以进行分类:投票法(取k个中值最多的那个分类作为结果)
可以处理回归任务:平均法(取k个值的平均数)
改良:根据距离远近进行加权投票和加权平均
kNN三要素:k值,距离的度量方法,决策规则的选择
代码:
def autoNorm(dataSet): #数据归一化
minValue = dataSet.min(0)
maxValue = dataSet.max(0)
ranges = maxValue - minValue
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minValue, (m, 1))
normDataSet = normDataSet/tile(ranges, (m, 1))
return normDataSet, ranges, minValue
def classify0(inX , dataSet , lables , k): #计算特征点的距离,排序并将其分类
dataSetSize = dataSet.shape[0] #用来查看矩阵的维数,即行数和列数
diffMat = tile(inX,(dataSetSize,1))-dataSet
sqDiffmat = diffMat ** 2
sqDistancs = sqDiffmat.sum(axis=1)
distances = sqDistancs ** 0.5
sortedDistIndicies = distances.argsort() #对测试点于训练集点中的距离进行排序
classcount = {}
for i in range(k): #选取前k的最近的距离,并对其类别进行统计
voteIlabel = lables[sortedDistIndicies[i]]
classcount[voteIlabel] = classcount.get(voteIlabel,0)+1
sortedClasscont = sorted(classcount.items(), key=operator.itemgetter(1),reverse = True)
return sortedClasscont[0][0] #类别最多的即为测试样本的类别