机器学习Task01--K邻近算法(knn)

算法原理

KNN算法采用测量不同特征之间的距离方法进行分类,通俗的讲就是:给定一个样本数据集,并且样本集中每个数据都存在标签,即我们知道样本集中每个数据与所属分类的对应关系。对新输入没有标签的实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。

对于每一个在数据集中的数据点:
   计算目标的数据点(需要分类的数据点)与该数据点的距离
   将距离排序:从小到大
   选取前K个最短距离
   选取这K个中最多的分类类别
   返回该类别来作为目标数据点的预测值

项目实例1:优化约会网站的配对效果

项目概述
海伦使用约会网站寻找约会对象。经历一段时间后,他发现曾交往过三种类型的人:

1:不喜欢的人
2:魅力一般的人
3:极具魅力的人
她希望:
1.不喜欢的人直接排除掉
2.工作日与魅力一般的人约会
3.周末与极具魅力的人约会
现在她收集到了一些约会网站上未曾记录的数据信息,这更有助于匹配对象的归类。
开发流程
Step1:收集数据
海伦把这些约会对象的数据存放在文本文件datingTestSet.txt中,总共有1000行。海伦约会的对象主要包含以下三种特征:
Col1:每年获得的飞行常客里程数
Col2:玩视频游戏所耗时间百分比
Col3:每周消费的冰淇淋公升数
文本文件数据格式如下:

40920     8.326976     0.953952	3
14488     7.153469     1.673904	2
26052     1.441871     0.805124	1
75136     13.147394   0.428964	1
38344     1.669788     0.134296	1

Step2:准备数据
使用Python解析文本文件。将文本记录转换为Numpy的解析程序如下所示:

import numpy as np
def file2matrix(filename):
    """
    Desc:
    	导入训练数据
    parameters:
    	filename:数据文件路径
    return:
    	数据矩阵 returnMat和对应的类别 classLabelVector
    """
    fr=open(filename)
    #获得文件中数据行的行数
    lines=fr.readlines()
    numberOfLines=len(lines) #type:int
    #生成对应的空矩阵
    returnMat=np.zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    for line in lines:
    	line=line.strip()
    	listFromLine=line.split('\t')
    	returnMat[index,:]=listFromLine[0:3]
    	classLabelVector.append(int(ListFromLine[-1]))
    	index+=1
    return returnMat,classLabelVector

Step3:分析数据
使用Matplotlib化二维散点图

import matplotlib.pyplot as plt
if __name__=='__main__':
	datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
	color=['r','g','b']
	fig=plt.figure()
	ax=fig.add_subplot(311)
	for i in range(1,4):
		index=np.where(np.array(datingLabels)==i)
		ax.scatter(datingDataMat[index,0],datingDataMat[index,1],c=color[i-1],label=i)
	plt.xlabel('Col.0')
	plt.ylabel('Col.1')
	plt.legend()
	bx=fig.add_subplot(312)
	for i in range(1,4):
		index=np.where(np.array(datingLabels)==i)
                bx.scatter(datingDataMat[index,0],datingDataMat[index,1],c=color[i-1],label=i)
        plt.xlabel('Col.0')
        plt.ylabel('Col.2')
        plt.legend()
        cx=fig.add_subplot(313)
        for i in range(1,4):
  index=np.where(np.array(datingLabels)==i)
                cx.scatter(datingDataMat[index,0],datingDataMat[index,1],c=color[i-1],label=i)
        plt.xlabel('Col.1')
        plt.ylabel('Col.2')
        plt.legend()
        plt.show()

Step4:训练算法
此步骤不适用于K邻近算法。因为测试数据每一次都要与全部的训练数据进行比较,所以这个过程是没有必要的。

import opertor
def classfiy0(inX,dataSet,labels,k):
	dataSetSize=dataSet.shape[0]
	#距离度量 度量公式为欧氏距离
	diffMat=np.tile(inX,(dataSetSize,1))-dataSet
	sqDiffMat=diffMat**2
	sqDistances=np.sum(sqDiffMat,axis=1)
	distances=sqDistances**0.5
	#将距离排序:从小到大
	sortedDistIndicies=distances.argsort()
	classCount={}
	for i in range(k):
		voteIlabel=labels[sortedDistIndicies[i]]
		classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
	sortedClassCount=sorted(classCount.items(),key=opertor.itemgetter(1),reverse=True)
	return sortedClassCount[0][0]

Step:测试算法
计算错误率,使用海伦提供的部分数据作为测试样本。如果预测分类与实际类别不同,则标记为一个错误。

def datingClassTest():
	"""
	Desc:
		对约会网站的测试方法
	paramters:
		none
	return:
		错误数
	"""
	#设置测试数据的一个比例
	hoRatio=0.1#测试范围,一部分测试仪一部分作为样本
	#从文件中加载数据
	datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
	#归一化数据
	normMat,ranges,minVals=autoNorm(datingDataMat)
	m=normMat.shape[0]
	numTestVecs=int(m*hoRatio)
	print('numTestVecs=',numTestVecs)
	errorCount=0.0
	for i in range(numTestVecs):
		classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],			 		    	  
	datingLabels[numTestVecs:m],3)
	print("错误率:%f”%(errorCount/float(numTestVecs)))
	print(errorCount)

Step6:使用算法
产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型
约会网站预测函数如下:

def classifyPerson():
	resultList=['不喜欢的人‘,’魅力一般的人‘,’极具魅力的人‘】
	ffMiles = float(input("每年获得的飞行常客里程数?"))
        percentTats = float(input("玩视频游戏所耗时间百分比?"))
        iceCream = float(input("每周消费的冰淇淋公升数?"))
    	datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
    	normMat, ranges, minVals = autoNorm(datingDataMat)
    	inArr = np.array([ffMiles, percentTats, iceCream])
    	intX = (inArr - minVals) / ranges
    	classifierResult = classify0(intX, normMat, datingLabels, 3)
    	print("这个人属于: ", resultList[classifierResult - 1])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值