机器学习算法一——k-近邻算法(1)
采用测量不同特征值之间的距离方法进行分类。
kNN工作原理:训练样本集中每个数据有一个一一对应的所属分类的标签。需要分类的新数据没有标签,将新数据的每个特征与样本集中数据对应的特征进行比较,然后将样本集中与其特征最相似(最近邻)的数据标签作为新数据的标签。
一般来说,我们选择样本集中前k个最相似的数据(通常k<=20)中,出现次数最多的,作为新数据的分类。
使用python导入数据
from numpy import * #科学运算包
import operator #运算符模块
def createDataSet(): #定义了四组数据和相应的标签
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels =['A','A','B','B']
return group,labels
#从文本文件中解析数据
def classify0(inX,dataSet,labels,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={} #初始化classCount
for i in range(k): #选择欧式距离最小的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]
(1)tile()
将inX二维数组化,变成dataSetSize行1列
(2)sum()函数
sum(axis=1)表示矩阵中行之间数的求和;
sum(axis=0)表示矩阵中对列求和
(3)argsort()函数
argsort()函数的具体功能如下:
import numpy as np
x = np.array([1,4,3,-1,6,9])
y = x.argsort()
>>>y=array([3,0,2,1,4,5])
发现argsort()函数是将x中的元素从小到大排列,输出其对应的index(索引)。
例如:x[3]=-1最小,所以y[0]=3;x[5]=9最大,所以y[5]=5。
(4)classCount.get()函数
检测并生成新元素,0只做初始化作用,计数,遇到相同的加1
for i in range(k): #选择欧式距离最小的k个点
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
令k=3
假设labels = [‘A’,‘A’,‘A’,‘B’,‘B’,‘B’]
假设sortedDistIndicies = [1,3,0]
那么
-------------------------、
当k=0,
voteIlabel = labels[sortedDistIndicies[0]]
= labels[1] = 'A'
classCount['A'] = classCount.get('A',0) + 1
>>>classCount = {'A':1}
当k=1,
voteIlabel = labels[sortedDistIndicies[1]]
= labels[3] = 'B'
classCount['B'] = classCount.get('B',0) + 1
>>>classCount = {'B':1}
当k=2,
voteIlabel = labels[sortedDistIndicies[2]]
= labels[0] = 'A'
classCount['A'] = classCount.get('A',0) + 1
>>>classCount = {'A':2}
>>>classCount = {'A':2,'B':1}
(5)sorted()函数
sorted(iterable, key=None, reverse=False)
iterable为排序对象
key表示按什么要素排序
reverse默认False表示升序
sortedClassCount = sorted(classCount.items(),
key=operator.itemgetter(1),reverse=True)
classCount.items()返回的是dict_items,将classCount字典分解为元组列表
注意:python2的iteritems()转为python3的items()
operator.itemgetter(1)表示对classCount的第2个域进行排序(即标签频次)
reverse=True表示是升序排列
至此,分类器建成,测试结果如下