(机器学习实战)2.2使用K临近法改进约会网站的配对效果(详细注释)

样本集下载:https://pan.baidu.com/s/1GJoeIRlMLRWbzjsG4EU_RA

编译:python3.6

运行可用:

import operator 
from numpy import *
from scipy import *
from matplotlib import *



"""
	KNN近邻分类思路:
	1,用shape[0]得到行数
	2,把带划分数据用tile扩展成一个矩阵
	3,(用该矩阵-训练数据)平方后开方得到一个列表
	4,对列表按距离升序排列
	5,选取前K个中标签出现次数后按降序排列,[0][0]即为出现最多的标签作为带预测的划分标签
    """
#inx为自己输入要分类的测试数,dataset为训练集,labels为标签集,k为kNN中的K值
#shape[0]得到训练样本多少行
#tile建立inx,dataSetSize行,1列
#sum(axis=1),按行相加
#argsort递增排序
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() #生成的不是距离而是标号列表 
	#print(sortedDistIndicies)
	classCount={}
	for i in range(k):
		#print(sortedDistIndicies[i])               
		voteIlabel=labels[sortedDistIndicies[i]]    
		classCount[voteIlabel]=classCount.get(voteIlabel,0)+1   #这一步是做相同标签的统计(+1),找到键voteIlabel对应的值,如果不存在这样的键则返回默认值0
		#print(classCount.get(voteIlabel,0))
	sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #sorted排序做升序,返回副本,原始输入不变,里面的参数设置请参考https://blog.csdn.net/hshl1214/article/details/40587985
	#print(sortedClassCount[0][0])                                                       #或者参考https://www.cnblogs.com/zhoufankui/p/6274172.html
	return sortedClassCount[0][0]




"""
	从文本中解析数据思路:
	1,读取文件
	2,取得文件所有行,取得行数
	3,建立除标签外同等大小的矩阵returnMat
	4,处理文件前后回车
	5,把处理后的类依次放入矩阵中
	6,把标签放入列表中
	7,返回矩阵和列表
	"""
#open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。
#file.readline() 返回一行
#file.readlines([size]) 返回包含size行的列表,size 未指定则返回全部行
def file2matrix(filename):
	fr=open(filename)
	arrayOlines=fr.readlines()   #返回所有的行
	numberOflines=len(arrayOlines)  #返回所有的行数
	returnMat=zeros((numberOflines,3)) #生成numberOflines行,3列的矩阵  //数组矩阵的区分
	classLabelVector=[]
	index=0
	for line in arrayOlines:
		line=line.strip()             #去掉字符串前后面的回车字符,它返回的是字符串的副本,并删除前导和后缀字符,注意strip()和lstrip和rstrip的区别
		listFromLine=line.split('\t')
		returnMat[index,:]=listFromLine[0:3]   #利用切片returnMat[index,:]存储前三个
		classLabelVector.append(listFromLine[-1])  #利用classLabelVector数列存储标签   #如果训练数据用datingTestSet2.txt,则改为classLabelVector.append(int(listFromLine[-1])) 
		index+=1
	return returnMat,classLabelVector              #返回一个矩阵和数列

#显示一下
#datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
#print(datingDataMat)
#print(datingLabels)




"""
	图片显示思路:
	1,倒入库
	2,建立图片
	3,图片在画布上的放置
	4,scatter依赖特征确定位置和标签来确定颜色
	5,显示
	"""
# ~ print("**********************************************")
# ~ import matplotlib.pyplot as plt
# ~ fig=plt.figure()
# ~ ax=fig.add_subplot(121) #111,参数111的意思是:将画布分割成1行1列,图像画在从左到右从上到下的第1块
# ~ ax.scatter(datingDataMat[:,1],datingDataMat[:,2],10.0*array(datingLabels),10.0*array(datingLabels))      #scatter参考链接https://blog.csdn.net/qiu931110/article/details/68130199
# ~ ax=fig.add_subplot(122) 
# ~ ax.scatter(datingDataMat[:,0],datingDataMat[:,2],5.0*array(datingLabels),5.0*array(datingLabels))     
# ~ plt.show()




"""
	归一化思路:
	1,找列中最小值、最大值
	2,本身值-最小值/(最大值-最小值)
	3,返回归一化值,范围,最小值
	"""
print("**********************************************")
#归一化数值
def autoNorm(dataSet):
	minVals=dataSet.min(0)      #参数0是的从列中取最小值
	maxVals=dataSet.max(0)      
	ranges=maxVals-minVals
	normDataSet=zeros(shape(dataSet))
	m=dataSet.shape[0]
	normDataSet=dataSet-tile(minVals,(m,1))
	normDataSet=normDataSet/tile(ranges,(m,1))
	return normDataSet,ranges,minVals
#显示一下
# ~ normDataSet,ranges,minVals=autoNorm(datingDataMat)
# ~ print(normDataSet)
# ~ print("**********************************************")
# ~ print(ranges)
# ~ print(minVals)




"""
	分类器构建思路:
	1,找到文档的数据集和标签
	2,归一化
	3,取百分之10作为测试集
	4,用分类函数分类
	5,统计分类错误率
	"""
def datingClassTest():
	hoRatio=0.10
	datingDataMat,datingLabels=file2matrix('datingTestSet.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)
		print ("the classfier come back with: %s,the real answer is :%s"\
			%(classifierResult,datingLabels[i]))#如果用datingTestSet2.txt的数据则s改成d
		if(classifierResult!=datingLabels[i]):errorCount+=1
	print ("the total error rate is :%f" %(errorCount/float(numTestVecs)))

# ~ datingClassTest()


"""
	约会网站预测函数:
	1,输入特征值
	2、建立特征值数组
	3、归一化特征值
	4、预测
	"""
def classifyPerson():
	resultList=['not at all','in small doses','in large doses'] #如果用datingTestSet2.txt就需要这行、这里添加也没事
	percentTats=float(input(\
		'percentage of time spent playing video games?'))
	ffMiles=float(input(\
		'frequent filer miles eared per year?'))
	iceCream=float(input(\
		'liters of ice cream consumed per year?'))
	datingDataMat,datingLabels=file2matrix('datingTestSet.txt')
	normMat,ranges,minVals=autoNorm(datingDataMat)
	inArr=array([ffMiles,percentTats,iceCream])
	classfierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
	print('you will probably like this person:%s'%classfierResult)
classifyPerson()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值