机器学习实战:k-临近算法(一)

工作原理:存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最邻近)的分类标签。一般来说,我们只选择样本数据集中前k个最相似数据,这就是k-临近算法的出处,通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。


算法流程:

(1)收集数据

(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。

(3)分析数据

(4)训练算法:此步骤不适用于k-临近算法

(5)测试算法:计算错误率

(6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-临近算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。


来看一个例子:


假如有一组数据已经做好了分类,(1,1.1)和(1,1)属于A类,(0,0)(0,0.1)属于B类

现在有一点(1,0),它应该属于哪一类?

思路:

(1)求出(1,0)到四个点之间的距离

(2)找出距离最近的k个点

(3)找出k个点中分类出现次数最多的那个


用到的python知识:

# -*- coding:utf-8 -*-
from numpy import *
import operator

#1.shape函数
group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
print(group.shape[0])#输出4,数组行数
print(group.shape[1])#输出2,数组列数
print(group)

#2.tile函数
test=[1,0]
print(tile(test,(4,1)))
#输出
#[[1 0]
# [1 0]
# [1 0]
# [1 0]]

#3.sum函数
arr=array([[1,2,3],[4,5,6]])
print(arr.sum(axis=1))#将矩阵的每一行相加
#输出[ 6 15]
print(arr.sum(axis=0))#将矩阵的每一列相加
#输出[5 7 9]

#4.argsort函数:返回的是数组值从小到大的索引值
array1=([1,3,2,7])
print(argsort(array1))
#输出[0 2 1 3]

#5.sorted
#sorted(iterable, cmp=None, key=None, reverse=False) 
#iterable:迭代对象,要排序的对象
#cmp:比较函数
#key:指定取待排序元素的哪一项进行排序,operator.itemgetter(1)获取对象的第1个域的值,此处是按value值排序
#reverse:是否反转,表示是否从高到低排序
dict={'A':10,'B':5,'C':20,'D':15}
print(sorted(dict.items(),key=operator.itemgetter(1)))
#结果:[('B', 5), ('A', 10), ('D', 15), ('C', 20)]
#reverse=true结果:[('C', 20), ('D', 15), ('A', 10), ('B', 5)]


python3代码:

# -*- coding:utf-8 -*-
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

#intX:分类的输入向量
#dataSet:训练样本
#labels:标签向量
#k:选择最近邻居的数目
def classify0(intX,dataSet,labels,k):
	dataSetSize=dataSet.shape[0]#数组行数
	#距离计算
	diffMat=tile(intX,(dataSetSize,1))-dataSet#将输入向量转为行数为dataSetSize的二维数组,并计算与训练样本的差
	sqDiffMat=diffMat**2#求数组的2次方
	sqDistances=sqDiffMat.sum(axis=1)#将矩阵的每一行相加
	distances=sqDistances**0.5#求数组的0.5次幂,也就是求平方根
	#选择距离最小的k个点
	sortedDistIndicies=distances.argsort()#根据距离将数组的下标排序
	classCount={}
	#求出前距离最近的前K个点中出现最多的分类
	for i in range(k):
		voteIlabel=labels[sortedDistIndicies[i]]#遍历前k个点,获取每个点所属分类
		classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#将类别作为key,出现的次数作为value,计算每个类别出现的次数
	#排序
	sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
	return sortedClassCount[0][0]		
	

#测试
group,labels=createDataSet()
result=classify0([1,0],group,labels,3)
print(result)



距离计算:

(1)求两个矩阵的差

输入的数据为[1,0]:

训练样本集为:

[[1.0,1.1],

 [1.0,1.0],

 [0, 0],

 [0,0.1]],是一个二维数组,也可以看作为一个行为4列为2的矩阵,为了两个矩阵可以相减,首先需要将输入向量[1,0]转换为一个行数为4的二维数组

经过tile(intX,(dataSetSize,1))后输入向量变为

[[1  0],
 [1  0],
 [1  0],
 [1  0]]

然后减去训练样本集,求出两个矩阵的差,差值为

[[ 0.  -1.1]
 [ 0.  -1. ]
 [ 1.   0. ]
 [ 1.  -0.1]]


(2)使用欧氏距离公式,计算两个向量点之间的距离

首先求差值的2次方,结果为:

[[ 0.    1.21]
 [ 0.    1.  ]
 [ 1.    0.  ]
 [ 1.    0.01]]

然后将矩阵的每一行相加得到:

[ 1.21  1.    1.    1.01]

然后开根

[ 1.1   1.    1.    1.00498756]


根据距离最近点排序

值  :  1     1    1.00498756  1.1
下标:  1     2       3         0
得到:

[1 2 3 0]


(3)选择距离最小的k个点,此处k=3,也就是前3个点

从上一步得到排序后的下标,取前三个值,然后从lables标签中取下标为1  2  3 的值,分别是A  B  B

求出出现频率最高的类别,B出现两次,A出现1次,因此推测[1,0]的分类结果是B


来自:机器学习实战


python知识参考:

http://blog.csdn.net/sunny2038/article/details/9002531

http://www.cnblogs.com/chamie/p/4847332.html

http://blog.csdn.net/iboxty/article/details/44975575

http://www.cnblogs.com/100thMountain/p/4719503.html

http://www.cnblogs.com/kellyseeme/p/5525052.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值