knn算法预测约会对象是否符合条件 发表于 2018-05-03 | 分类于 MachineLearning 使用knn算法进行分类预测123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105from numpy import *import operator # 运算符操作模块import osfrom collections import Counter # 快速计数工具# inx 自定义用于分类的输入向量 - 标准向量 即计算数据集到标准向量的"距离"# dataset 训练数据集 lables 标签# 最近邻的特征数量def classify(inx, dataset, lables, k): dataSetSize = dataset.shape[0] # tile(A,(2,3)) 表示第一个维度重复三次,第二个维度重复两次 tile(A,(2,3)) => array([[1, 2, 1, 2, 1, 2],[1, 2, 1, 2, 1, 2]]) diffMat = tile(inx, (dataSetSize, 1)) - dataset # 计算训练集的数据与标准向量的距离 - 欧氏距离 => [[1,2,3],[1,2,3]]-[[1,2,3],[1,2,0]] sqDiffMat = diffMat ** 2 # 计算平方和 再开方 => (A1-A2)^2+(B1-B2)^2+(c1-c2)^2 sqDistances = sqDiffMat.sum(axis = 1) distances = sqDistances ** 0.5 # 按照距离从小到大排序 并获取其对应索引放入数组中 => y=array([3,0,2,1,4,5]) x[3]距离最小 x[5]最大 sorteDistIndicies = distances.argsort() # 从距离排序中选取最小距离的k个向量 classCount = {} for i in range(k): voteIlable = lables[sorteDistIndicies[i]] # 字典的get方法 # 如:list.get(k,d) 其中 get相当于一条if...else...语句,参数k在字典中,字典将返回list[k];如果参数k不在字典中则返回参数d,如果K在字典中则返回k对应的value值 # l = {5:2,3:4} # print l.get(3,0)返回的值是4; # Print l.get(1,0)返回值是0; classCount[voteIlable] = classCount.get(voteIlable,0) + 1 # 排序选取 出现次数最多的标签 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]# 数据归一化 0,1矩阵def autoNorm(dataset): # 计算数据集中的最小最大特征值 minVals = dataset.min(0) maxVals = dataset.max(0) rangs = maxVals - minVals # 转为同维度的零矩阵 normDataset = zeros(shape(dataset)) m = dataset.shape[0] # 生成与最小值之差的矩阵 normDataset = dataset - tile(minVals,(m,1)) # 将最小值除以极差组成的矩阵 normDataset = normDataset / tile(rangs, (m,1)) return normDataset, rangs, minValsdef file2matrix(filename): """ 导入训练数据 :param filename: 数据文件路径 :return: 数据矩阵returnMat和对应的类别classLabelVector """ fr = open(filename, 'r') # 获得文件中的数据行的行数 numberOfLines = len(fr.readlines()) # 生成对应的空矩阵 # 例如:zeros(2,3)就是生成一个 2*3 的矩阵,各个位置上全是 0 returnMat = zeros((numberOfLines, 3)) # prepare matrix to return classLabelVector = [] # prepare labels return fr = open(filename, 'r') index = 0 for line in fr.readlines(): # str.strip([chars]) --返回移除字符串头尾指定的字符生成的新字符串 line = line.strip() # 以 '\t' 切割字符串 listFromLine = line.split('\t') # 每列的属性数据,即 features returnMat[index] = listFromLine[0 : 3] # 每列的类别数据,就是 label 标签数据 classLabelVector.append(int(listFromLine[-1])) index += 1 # 返回数据矩阵returnMat和对应的类别classLabelVector return returnMat, classLabelVector# 约会网站用户数据进行分类 预测 数据在kaggledef datingClassTest(): # 设置测试数据的的一个比例(训练数据集比例=1-hoRatio) hoRatio = 0.1 # 测试范围,一部分测试一部分作为样本 # datingDataMat, datingLabels = file2matrix("https://raw.githubusercontent.com/pbharrin/machinelearninginaction/master/Ch02/datingTestSet2.txt") # load data setfrom file datingDataMat, datingLabels = file2matrix("E:\\python\\MachineLearning\\data\\2.KNN/datingTestSet2.txt") # load data setfrom file # 归一化数据 normMat, ranges, minVals = autoNorm(datingDataMat) # m 表示数据的行数,即矩阵的第一维 m = normMat.shape[0] # 设置测试的样本数量, numTestVecs:m表示训练样本的数量 numTestVecs = int(m * hoRatio) print('numTestVecs=', numTestVecs) errorCount = 0 for i in range(numTestVecs): # 对数据测试 classifierResult = classify(normMat[i], normMat[numTestVecs : m], datingLabels[numTestVecs : m], 3) print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])) errorCount += classifierResult != datingLabels[i] print("the total error rate is: %f" % (errorCount / numTestVecs)) print(errorCount)if __name__ == '__main__': datingClassTest() 感谢你对我的支持 让我继续努力分享有用的技术和知识点. 打赏 微信支付 支付宝 本文作者: rudder 本文链接: https://irudder.github.io/2018-05-03/knn/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!