《机器学习实战》----k-近邻算法
来源:互联网 发布:mysql不支持emoji表情 编辑:程序博客网 时间:2024/06/03 22:39
一、KNN分类思想
二、例子一
1.情景
如下图,这里共有四个点,两个B类,两个A类。[1,1.1]-A 、[1,1]-A 、[0,0]-B 、[0,0.1]-B。现在我们输入点[0,0],要求KNN分类器帮我们分类,判断点[0,0]是A类还是B类。算法中设置K=3,表示在该图中,计算输入点[0,0]到图中已经分好类的点间的距离,然后按照距离递增次序排序,选取与输入点[0,0]距离最小的k个点(就是已经排好序的前k个节点),计算该k个点中哪个类别的点最多,出现频率最高的类别作为输入点[0,0]的预测分类。
2.所用函数
''' createDataSet(): 共有四个点,两个B类,两个A类。[1,1.1]-A 、[1,1]-A 、[0,0]-B 、[0,0.1]-B, 将它们有序的返回到gourp,labels group= [[ 1. 1.1] [ 1. 1. ] [ 0. 0. ] [ 0. 0.1]] labels= ['A', 'A', 'B', 'B']'''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''' classify0(inX, dataSet, labels, k): inX=需要进行预测分类的向量;dataSet=已经分好类的数据集;labels=对应dataSet中各个对象的分类标签。 将向量[inX]归类到与其距离最近的k个向量中所属标签出现频率最高的那一个标签'''def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] #dataSet矩阵的列对应的是一个对象的属性,行对应的是某一个对象; #这句返回dataSet矩阵第0列的长度(dataSet矩阵的行数,也是对象总数) #dataSetSize = dataSet矩阵的行数 diffMat = tile(inX, (dataSetSize,1)) - dataSet #tile(inX, (dataSetSize,1)),创造具有 #dataSetSize行1列的矩阵,矩阵每个元素都为向量[inX]。 #diffMat=dataSet中每个对象与向量[inX]的距离 sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) #sqDistances=sqDiffMat的所有列相加 distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() #返回distances中元素大小是递增排序对应的下标 #sortedDistIndicies = 与[inX]距离递增排列的点的下标 classCount={} for i in range(k): # 0<=i<k voteIlabel = labels[sortedDistIndicies[i]] #返回与[inX]距离最近的第i个点的标签 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #遍历完k次后,该句可以统计与[inX]距离 #最近的k个点中,各个标签出现的次数 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] #sortedClassCount = 将classCount={}的标签频率递增排列返回的序列
3.运行结果
三、例子二
1.情景
海伦收集了自己的1000条约会信息(datingTestSet.txt),每条信息对应的属性是:
[ 每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数,海伦喜欢这个男生的程度 ]
该例子要进行两个实验:
1. 取datingTestSet.txt中90%的数据作为训练集、10%的数据作为验证集,并计算分类的错误率
2.根据海伦提供的一条男生的信息【每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数】,判断海伦是否喜欢这个男生
2.从文本解析数据
以下函数将从datingTestSet.txt中读取数据,并将海伦喜欢这个男生的程度进行转换:
[ largeDoses,smallDoses,disntLike ]->[ 3,2,1 ]
代码:
''' 读取文件filename,将原数据集拆分为两个数据结构returnMat矩阵、classLabelVector数组 并返回returnMat(returnMat是由原数据集除去最后一列的矩阵) 并返回classLabelVector(数组中第i个元素就是原数据集中第i行的最后一列的属性,且存入 数组前已将最后一列的属性映射到3,2,1三个数字中的一个)'''def file2matrix(filename): fr = open(filename) numberOfLines = len(fr.readlines()) #numberOfLines = 数据集的行数 returnMat = zeros((numberOfLines,3)) #returnMat = numberOfLines行3列的零矩阵 classLabelVector = [] fr = open(filename) index = 0 int = {'largeDoses': 3, 'smallDoses': 2, 'didntLike': 1} #创建名为int的字典,将并将海伦喜欢这个男生的程度进行转换: #[ largeDoses,smallDoses,disntLike ]->[ 3,2,1 ] for line in fr.readlines(): line = line.strip() #去除当前一行字符串头尾的空格 listFromLine = line.split('\t') #将当前字符串按照'\t'进行分割,例如第一行数据这里会返回一个数组为: #['40920', '8.326976', '0.953952', 'largeDoses'] returnMat[index,:] = listFromLine[0:3] #将一行数据中的前三个属性放入零矩阵的第index行,例如这里 #将'40920', '8.326976', '0.953952'放入零矩阵的第0行 classLabelVector.append(int[listFromLine[-1]]) #将listFromLine的最后一个元素(即'largeDoses')按照字典转化 #为3 并添加到数组classLabelVector index += 1 return returnMat,classLabelVector
结果:
3.画出散点图
使用returnMat,classLabelVector画出散点图,其中横坐标x=每年获取的飞行常客里程数,纵坐标y=玩视频游戏所耗时间百分比。
代码:
''' returnMat,classLabelVector=file2matrix('datingTestSet.txt') 使用returnMat,classLabelVector画出散点图, 其中横坐标x=每年获取的飞行常客里程数,纵坐标y=玩视频游戏所耗时间百分比。 s为datingDataMat对应第i行数据点的size,size的数值等于classLabelVector数组中第i个 元素([ largeDoses,smallDoses,disntLike ]->[ 3,2,1 ],3、2、1中的一个)乘以15。 c为datingDataMat对应第i行数据点的color,color的数值等于classLabelVector数组中第i个 元素([ largeDoses,smallDoses,disntLike ]->[ 3,2,1 ],3、2、1中的一个)乘以15。'''def painting(datingDataMat, datingLabels): #从datingDataMat,datingLabels=file2matrix('datingTestSet.txt')获取参数,并画出散点图 import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) # ax.scatter(datingDataMat[:,1],datingDataMat[:,2]) ax.scatter(datingDataMat[:, 0], datingDataMat[:, 1], s=15 * array(datingLabels), c=15 * array(datingLabels)) plt.show()
结果:
4.数据准备:归一化数据
代码:
''' 这里的参数dataSet使用经过函数file2matrix(filename)返回的returnMat矩阵,其中 returnMat矩阵只包含'datingTestSet.txt'的0~2共3列的数据。 函数autoNorm(dataSet)将returnMat矩阵进行归一化处理(即将returnMat矩阵中的所有数据转化为0~1之间), 并将结果返回到normDataSet,而返回的 数组ranges=[(第一列元素极差),(第二列元素极差),(第三列元素极差)]'''def autoNorm(dataSet): minVals = dataSet.min(0) #返回当min()的参数为0时,返回dataSet每列的最小值 maxVals = dataSet.max(0) ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) #构建与dataSet矩阵相同大小的零矩阵 m = dataSet.shape[0] # m=dataSet矩阵的行数 normDataSet = dataSet - tile(minVals, (m,1)) normDataSet = normDataSet/tile(ranges, (m,1)) return normDataSet, ranges, minVals
结果:
5.取’datingTestSet.txt’中的第0~10%的数据作为待分类集,取第10%~100%的数据作为已经分好类的数据集。并计算kNN分类器的错误率
代码:
''' 取'datingTestSet.txt'中的第0~10%的数据作为待分类集,取第10%~100%的数据作为已经分好类的数据集。 并计算kNN分类器的错误率'''def datingClassTest(): hoRatio = 0.10 # hold out 10% datingDataMat, datingLabels = file2matrix('datingTestSet.txt') # load data setfrom file normMat, ranges, minVals = autoNorm(datingDataMat) m = normMat.shape[0] numTestVecs = int(m * hoRatio) errorCount = 0.0 for i in range(numTestVecs): #这个for循环中取normMat的第0~10%的数据作为待分类集,取第10%~100%的数据作 #为已经分好类的数据集。 classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) #classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)中,例如i=0是,则 #取normMat矩阵的第0行在已经分好类的normMat矩阵的第numTestVecs到m行的数据中进行分类,计算前3个最接近【normMat矩阵第0行数据的特征】的 #数据所对应的标签出现次数,将normMat矩阵的第0行数据归类为出现频率最高的标签 if classifierResult == datingLabels[i]: print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])) else: errorCount += 1.0 print("\33[1;35m the classifier came back with: %d, the real answer is: %d \33[0m" % ( classifierResult, datingLabels[i])) print("the total error rate is: %f" % (errorCount / float(numTestVecs))) print("errorCount= ",errorCount)
结果:
6.通过海伦输入某男生的信息【每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数】,使用该程序判断海伦是否喜欢这个男生
代码:
''' 通过海伦输入某男生的信息【每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数】,使用 该程序判断海伦是否喜欢这个男生'''def classifyPerson(): resultList = ['disntLike' ,'smallDoses','largeDoses'] percentTats = float(input("percentage of time spent playing video games?")) ffMiles = float(input("frequent flier miles earned 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:", resultList[classfierResult-1])
结果:
四、例子三
1.情景
现在我们要构建一个手写识别系统。
(训练集的格式与测试集相同)
目前我们有一堆训练数据集(手写数字及其标签,例如文件名0_14.txt表示这个第14个手写数字’0’的样本,0同时也是该样本的标签。),具体如下图:
2.代码
''' 图像用txt文件表示,是一个32*32的矩阵。该函数将这个矩阵放入一个1*1024的向量里面。 例如,矩阵中第一行放入向量的0~31号位置,矩阵中的第二行放入向量的32~63号位置。'''def img2vector(filename): returnVect = zeros((1,1024)) fr = open(filename) for i in range(32): lineStr = fr.readline() for j in range(32): returnVect[0,32*i+j] = int(lineStr[j]) return returnVect''' 将目录“trainingDigits”的全部文件放进一个矩阵trainingMat中,矩阵trainingMat的行数等于文件数,列数等于每个文件的长度; 函数handwritingClassTest()将目录“testDigits”中的全部测试集进行kNN分类,并与测试集原本自带的标签进行比较,得出分类的错误率'''def handwritingClassTest(): hwLabels = [] trainingFileList = listdir('trainingDigits') #listdir函数将返回目录中的所有文件名 m = len(trainingFileList) trainingMat = zeros((m,1024)) for i in range(m): fileNameStr = trainingFileList[i] fileStr = fileNameStr.split('.')[0] #以“.”进行划分,获取第0号划分元素 classNumStr = int(fileStr.split('_')[0]) #以“_”进行划分,获取第0号划分元素 hwLabels.append(classNumStr) #将当前样本的标签存放到数组hwLabels的尾部 trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr) testFileList = listdir('testDigits') errorCount = 0.0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) vectorUnderTest = img2vector('testDigits/%s' % fileNameStr) classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) print( "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr)) if (classifierResult != classNumStr): errorCount += 1.0 print( "\nthe total number of errors is: %d" % errorCount) print ("\nthe total error rate is: %f" % (errorCount/float(mTest)))
3.运行结果
阅读全文
0 0
- 机器学习实战之K-近邻算法
- 机器学习实战笔记 K近邻算法
- 《机器学习实战》之K-近邻算法
- 机器学习实战-k近邻算法
- 机器学习实战 k-近邻算法
- 【机器学习实战】-k近邻算法
- 《机器学习实战》—K-近邻算法
- 【机器学习实战一:K-近邻算法】
- 机器学习实战(k-近邻算法)
- 机器学习实战笔记:K近邻算法
- 机器学习实战笔记 k-近邻算法
- 机器学习实战之k-近邻算法
- 机器学习实战--k近邻算法
- 机器学习实战:K近邻算法(kNN)
- 【机器学习实战02】k-近邻算法
- 机器学习实战-K-近邻算法
- 机器学习实战之K近邻算法
- 【机器学习实战-python3】k-近邻算法
- MyCat是什么?
- android 验证URL是否合法
- ionic2 url不安全问题 caused by: unsafe value used in a resource URL context
- Qt之Windows下禁用和启用中文输入法
- Android Hook PackageManager
- 《机器学习实战》----k-近邻算法
- ZM学习笔记——虚拟机VMware+centos6.5静态ip可上网配置
- omapl138-linux-IP
- UNIX高级环境编程-环境搭建
- Unity 对象颜色梯形渐变Shader,可调节
- javascript实现一个自制网页音乐播放器
- Squeeze-and-Excitation Networks论文翻译——中文版
- 求数列的和
- Android学习路线指南