k近邻算法(KNN)之python代码实战

1.算法概述(略)

2.从文件中解析数据

伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定前K个点所在类别出现的频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。

def knn(inx,dataset,labels,k):#inx输入向量,dataset输入的训练样本集,labels标签向量,k为最近邻数
	#距离计算
	dataset_size = dataset.shape[0]
	diffmat = tile(inx,(dataset.size,1))-dataset
	sqdiffmat = dffmat**2
	sqdistances = sqdiffmat.sum(axis=1)
	distances = sqdistances**0.5
	sorted_distances = distances.argsort()
	class_count = {}
	for i in range(k):
		vote_label = labels[sorted_distances[i]]
		#选择距离最小的k个点
		calss_count[vote_label] = class_count.get(vote_label,0)+1
		#排序
	sorted_class_count = sorted(class_count.items(),key = operator.itemgetter(1),reverse = True)
	return sorted_class_count[0][0]
	#距离公式为欧氏距离
	

3.实例:使用K近邻算法改进约会网站配对效果

过程
(1)收集数据:提供文本文件
(2)准备数据:使用python解析文本文件
(3)分析数据:使用matplotlib画二维扩散图
(4)训练算法:此步骤不适用于KNN
(5)测试算法:测试样本是已经完成分类的数据,如果预测与实际类别不同,则标记为一个错误
(6)使用算法:产生简单的命令行程序,然后输入一些特征数据来判断对方的类型
代码如下:

def file2matrix(filename):
	fr = open(filename)
	array_lines = fr.readlines()
	lines_num = len(array_lines)#得到文件行数
	mat = zeros((lines_num,3))#创建以零填充的矩阵,为了简化处理,将矩阵的另一维度设置为固定值3
	class_label = []
	index = 0
	for line in array_lines:
		line = line.strip()#截取掉所有的回车字符
		line_list = line.split('\t')#将上一步得到的整行数据分割成一个元素列表
		mat[index,:] = line_list[0:3]#选取前3个元素,将他们存储到特征矩阵中。
		class_label.append(int(line_list[-1]))#将列表的最后一列存储到向量class_label,列表中存储的元素值为整型,否则会将这些元素作为字符串处理
		index +=1
	return mat,class_label
import numpy as np  # 科学计算包Numpy
import operator  # 运算符模块
import os
import matplotlib as mpl
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
datingdatamat,datinglabels = file2matrix('datingTestSet.txt')
ax.scatter(datingdatamat[:,1],datingdatamat[:,2])
plt.show()
ax.scatter(datingdatamat[:.1],datingdatamat[:,2],15.0*array(datinglabels),15.0*array(datinglabels))
#归一化
def norm(dataset):
	minvals = dataset.min(0)
	maxvals = dataset.max(0)
	ranges = maxvals - minvals
	norm_dataset = zeros(shape(dataset))
	m = dataset.shape[0]
	norm_dataset = dataset-tile(minvals,(m,1))
	norm_dataset = normdataset/tile(ranges,(m,1))
	return norm_dataset,ranges,minvals
#将最小值放在minvals中,最大值放在maxvals,函数计算取值范围,创建新的返回矩阵,
#(当前值-最小值)/取值范围。需要注意的是,特征值矩阵1000*3,而minvals,ranges都是1*3,
#因此使用tile()函数将变量内容复制成输入矩阵同样大小的矩阵。
def datingClassTest():
    hoRatio = 0.10  # 测试集比例
    datingDataMat, datingLabels = file2matrix('datas/datingTestSet.txt')  # 读取数据
    normMat = norma(datingDataMat)  # 归一化处理
    m = normMat.shape[0]  # 样本数目
    numTestVecs = int(m * hoRatio)  # 用于测试的数据
    errorCount = 0
    for i in range(numTestVecs):
    	# normMat[i, :]待分类的输入数据,normMat[numTestVecs:m, :]训练数据,datingLabels[numTestVecs:m]标签数据,k=3
        classifierResult = knn(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)  # 分类函数
        print("预测结果为 : %d, 真实值为 : %d" % (classifierResult, datingLabels[i]))
        if (classifierResult != datingLabels[i]):
            errorCount += 1
    print("错误率为 : %f" % (errorCount / float(numTestVecs)))
    # 针对新数据的预测
def classifyPerson():
    resultList = ['不喜欢的人', '魅力一般的人', '极具魅力的人']
    percentTats = float(input("玩视频游戏所耗时间百分比:"))
    ffMiles = float(input("每年获得的飞行常客里程数:"))
    iceCream = float(input("每年消费冰淇淋公升数:"))
    datingDataMat, datingLabels = file2matrix("datas/datingTestSet.txt")
    normMat, ranges, minVals = normal(datingDataMat)
    inArr = np.array([ffMiles, percentTats, iceCream])
    classifierResult = knn((inArr - minVals) / ranges, normMat, datingLabels, 3)
    print("你对这个人的印象是:", resultList[classifierResult - 1])


# 测试
classifyPerson()

END

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值