kNN算法代码注释,约会网站

这篇博客适合初学者,通过numpy库解释kNN算法,并以约会网站为例,展示了如何使用算法进行数据处理和画图。博主提出将kNN应用于MMO游戏的结婚系统,通过筛选和归一化玩家数据,提高匹配成功率和玩家体验。
摘要由CSDN通过智能技术生成

#coding=utf8
#KNN.py
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):                  #inX是你要输入的要分类的“坐标”,dataSet是上面createDataSet的array,就是已经有的,分类过的坐标,label是相应分类的标签,k是KNN,k近邻里面的k
	dataSetSize=dataSet.shape[0]                     #dataSetSize是sataSet的行数,用上面的举例就是4行
	diffMat=tile(inX,(dataSetSize,1))-dataSet         #前面用tile,把一行inX变成4行一模一样的(tile有重复的功能,dataSetSize是重复4遍,后面的1保证重复完了是4行,而不是一行里有四个一样的),然后再减去dataSet,是为了求两点的距离,先要坐标相减,这个就是坐标相减 [(x1-x2),(y1-y2)]
	sqDiffMat=diffMat**2                              #上一行得到了坐标相减,然后这里要(x1-x2)^2,要求乘方 [(x1-x2)^2,(y1-y2)^2]
	sqDistances=sqDiffMat.sum(axis=1)                 #axis=1是列相加,,这样得到了(x1-x2)^2+(y1-y2)^2
	distances=sqDistances**0.5                        #开根号,这个之后才是距离
	sortedDistIndicies=distances.argsort()            #argsort是排序,将元素按照由小到大的顺序返回下标,比如([3,1,2]),它返回的就是([1,2,0]),返回的是坐标。也就是说返回的是距离哪个点最近的index。如果距离第三个点最近,那么就是[3,*,*,*]
	classCount={}
	for i in range(k):
		voteIlabel=labels[sortedDistIndicies[i]] #取到距离最近点的lables,如果是3,那么就是'B'
		classCount[voteIlabel]=classCount.get(voteIlabel,0)+1            #get是取字典里的元素,如果之前这个voteIlabel是有的,那么就返回字典里这个voteIlabel里的值,如果没有就返回0(后面写的),这行代码的意思就是算离目标点距离最近的k个点的类别,这个点是哪个类别哪个类别就加1
	soredClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)         #key=operator.itemgetter(1)的意思是按照字典里的第1个排序,classCount的第0个是label,第1个是label对应的数量。reverse=True是降序排序
	return soredClassCount[0][0]             #返回类别最多的类别

def file2matrix(filename):
	fr = open(filename)
	arrayOfLines = fr.readlines() #文件读取
	numberOfLines = len(arrayOfLines) #计算行数
	returnMat = zeros((numberOfLines,3)) #将数据拆分成矩阵 m行3列
	classLabelVector = []
	index = 0
	for line in arrayOfLines:
		line = line.strip() #出去列头尾的多余字符比如\t
		listFromLine = line.split('\t')
		returnMat[index,:] = listFromLine[0:3] #取出头三数, returnMat[index,:]等价于returnMat[index], listFromLine[0:3] 等价于取出从0到3列
		classLabelVector.append(int(listFromLine[-1])) #取出最后个数
		index +=1
	return returnMat, classLabelVector

def autoNorm(dataSet):
	minVals = dataSet.min(0)#取出每一列的最小值
	maxVals = dataSet.max(0)#取出每一列的最大值
	ranges = maxVals-minVals#算出每一列中最大值-最小值
	normDataSet = zeros(shape(dataSet))#加入dataSet有m行n列,会初始化为m行n列的0矩阵
	m = dataSet.shape[0]#取出dataSet有多少行
	normDataSet = dataSet - tile(minVals,(m,1))#矩阵进行减法(当前值-最小值)
	normDataSet = normDataSet/tile(ranges,(m,1))#矩阵进行除法(除以最大差值)
	return normDataSet, ranges, minVals

def datingClassTest():
	hoRatio = 0.1#取出10%的数据作为测试数据
	datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')#将数据进行分类
	normMat,ranges,minVals = autoNorm(datingDataMat)#归一化数据
	m = normMat.shape[0]#算出数据的从行数
	numTestVecs = int(m*hoRatio)#算出测试数据个数
	errorCount = 0.0#错误数量
	for i in range(numTestVecs):
		classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m],datingLabels[numTestVecs:m],3)#normMat[i],第i个测试数据,normMat[numTestVecs:m]取出剩下的90%作为训练数据,和训练标签,以前三个中最多的作为结果
		print("the classifier came back with: %d, the real answer is: %d" %(classifierResult, datingLabels[i]))
		if(classifierResult!=datingLabels[i]):#如何和标准的不一致,那么就认为错误。
			errorCount+=1.0
	print("the total error rate is : %f" %(errorCount/float(numTestVecs)))#计算错误率

def classifyPersion():
	resultList = ['not at all', 'in small doses', 'in large doses']
	percentTats = float(raw_input('percentage of time spend playing video games?'))
	ffMiles = float(raw_input('frequent flier miles earned per year'))
	iceCreate = float(raw_input('liters of ice cream consumed per year?'))
	datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
	normMat, ranges, minVals = autoNorm(datingDataMat)
	inArr = array([ffMiles, percentTats, iceCreate])
	classifierResult = classify0(inArr-minVals/ranges, normMat, datingLabels, 3)#对输入数据进行归一化,然后通过classify0分类器进行分类,得出结果
	print classifierResult
	print('You will probably like this person:',resultList[classifierResult])
		

有人说初学者,啥也不会就不要进入这行,我倒要看看,能不能进!啥不会我就学啥,有啥不一样的,你有脑袋我就没有啊!

numpy 数学库参数

.shape[0] 取行数 .shape[1]取列数

tile(A,(x,n)) 将A重复x行,n列

**2 平方 **0.5 开方

argsort 有小到大排序返回下标

operator.itemgetter(1) 按照第几个参数排列

调用matplotlib画图的流程是:调用figure()得到fig对象 -> 调用fig.add_subplot(111)得到axis对象 -> 调用plt.plot绘制 -> plt.show()显示出figure

>>> import matplotlib
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111) 
>>> ax.scatter(datingDataMat[:,1], datingDataMat[:,2])

fig.add_subplot(111) 是把整个画布拆分成1行1列,将画布分割成1行1列,图像画在从左到右从上到下的第1块

书上让加入颜色:

ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0*numpy.array(datingLabels), 15.0*numpy.array(datingLabels))

书上的方式行不通哇,然后改成了这种方式,但是需要import numpy

经过本人对游戏行业的考虑,针对MMO类型的游戏,我们可以应用此算法,应用到游戏的结婚系统中,但是具体数据的获取,需要针对数据库进行筛选,然后取出相应的数据。如在线时长,上线时间,经常做的任务,等级等一系列字段,进行筛选,归一化,按照kNN算法,进行推荐,这样推荐成功的概率会很大。并且很容易增加玩家上线时长,以及配对的符合度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值