第一个给出的是一个非常简单的例子:给出四个训练集数据(0,0)(0,0.1)【A类】(1,1)(1,1.1)【B类】
然后让你输入一个数字判断从属于A类还是B类
方法也很简单粗暴,离这个点的距离近的3个【k个】点,属于标签A的多,就判给A,B的多就判给B
问题:距离怎么算?
方法很简单:欧氏距离。
好了。所以我们代码的核心就是写出这个欧氏距离,
涉及到几点注意点:1.要根据训练集有多少个数据(比如4个)然后把待判数据也复制成这么多行的矩阵【目的:方便一会儿整个矩阵相减,不用循环了】
2.相减平方直接把矩阵平方即可
3.求和的时候,要按照行求和,毕竟要求每个【分量】或者说特征,的差异,加在一块儿求和是总差异
4.最后,把所有差异的数值从小到大排个序。得到【索引】
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] #确定有几行
diffMat = tile(inX, (dataSetSize,1)) - dataSet#把输入复制n条
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]]#距离从小到大的标签 比如录入第一个,这里是A
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#应该是统计A和B和各种的数量
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #AK:按字典的键值排序?
return sortedClassCount[0][0]#然后返回的是最大的那个数量的值?
附:各个代码中的函数的注解:
axis=0意味着从列开始往下走,axis=1意味着从行开始【叠加或计数或what】
operator.itemgetter函数
operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),下面看例子。
a = [1,2,3]
>>> b=operator.itemgetter(1) //定义函数b,获取对象的第1个域的值
>>> b(a)
2
>>> b=operator.itemgetter(1,0) //定义函数b,获取对象的第1个域和第0个的值
>>> b(a)
(2, 1)
要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值
argsort函数
返回的是数组值从小到大的索引值 Examples -------- >>> x = np.array([3, 1, 2]) >>> np.argsort(x) array([1, 2, 0])
tile的用法
首先要记住Python里面是0列1行 也就是0代表按列来↓↓↓ 1代表按行来→→→→
所以说dataset.min(0)代表的是每列的最小值,那么这个应该是一个行向量【1,2,3】
dataset.min(1)代表的是每行的最小值,那么这个应该是一个一维列向量【1】
【2】
【1】这种
tile的用法是比如b = [1,2] 那么tile(b,(3,1))代表复制三行,一列b的值 【1,2】
【1,2】
【1,2】这种