概述
时间:20180723-20180729
Machine Learning in Action 第二章
下方为kNN算法:
from numpy import * import operator from os import listdir import matplotlib.pyplot as plt def createDataSet(): # 给定4组数据 group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]]) # 点的集合 labels = ['A', 'A', 'B', 'B'] # 点标签 return group, labels def classify(inX,dataSet,labels,k):#kNN算法:4个输入参数:{(分类输入向量,inX(分类坐标)),(输入训练样本集,dataSet(createDataSet的array,已经分类过的坐标)),(标签向量(分类标签),labels),(最近邻居的数目,k)} dataSetSize=dataSet.shape[0] #dataSetSize是dataSet的行数 shape是用来取矩阵维度的长度的函数 diffMat=tile(inX,(dataSetSize,1))-dataSet #diffMat得到了目标与训练数组的差值 # tile函数是在numpy。lib。shape_base里的,作用是重复某个数组 # 比如tile(A,n),功能是将数组A重复n次,构成一个新的数组 # 前面用tile,把一行inX变成4行一模一样的 # tile有重复的功能,dataSetSize是重复4遍,后面的1保证重复完了是4行,而不是一行里有四个一样的 # 然后再减去dataSet,是为了求两点的距离,先要坐标相减,这个就是坐标相减 sqDiffMat = diffMat**2 #元素平方 sqDistances = sqDiffMat.sum(axis=1) # axis=1是列相加,,这样得到了(x1-x2)^2+(y1-y2)^2 distances = sqDistances**0.5 # 开方求距离 sortedDistances = distances.argsort() # 升序排序,将元素按照由小到大的顺序返回下标,比如([3,1,2]),它返回的就是([1,2,0] classCount = {} for i in range(k): # 选择距离最小的k个点 voteIlabel = labels[sortedDistances[i]] classCount[voteIlabel]=classCount.get(voteIlabel, 0)+1 # get是取字典里的元素 # 如果之前这个voteIlabel是有的,那么就返回字典里这个voteIlabel里的值 # 如果没有就返回0(后面写的),这行代码的意思就是算离目标点距离最近的k个点的类别 # 这个点是哪个类别哪个类别就加1 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # key=operator.itemgetter(1)的意思是按照字典里的第一个排序 # {A:1,B:2},要按照第1个(AB是第0个),即‘1’‘2’排序。 # reverse=True是降序排序 return sortedClassCount[0][0] # 返回类别最多的类别 def file2matrix (filename): fr = open(filename) # 打开文件名为filename的文件 arrayOLines = fr.readlines() # 按行读取文本数据,自动生成一个列表。 # 一次读取整个文本数据,并且自动将文件内容分析成一个行的列表,比readline()快 # 后面的img2vector就是使用的readline(),因为要逐行逐个读取,可以对比一下 # 每个样本数据占据一行 numberOfLines = len(arrayOLines) # 样本数据的个数 returnMat = zeros((numberOfLines, 3)) # 创建一个矩阵numberOfline行3列 classLabelvector = [] index = 0 for line in arrayOLines: # 循环处理文件 # print(line) line = line.strip() # 去掉回车符,pre(使上下的数据紧凑在一起), # 括号里面是之前不太对的理解,是去掉那个超级大的一行的列表中的回车符“n” ,然后一行一行的处理,才得到所看到的上下的数据紧凑在一起的数据 # 也就是说,不是一次就得到的,是迭代出来的,所显示的是最终迭代完成之后的结果print line很多 # strip() 方法用于移除字p符串头尾指定的字符(默认为空格或换行符)或字符序列 listFromLine = line.split('t') # python split()默认以空格分割成列表,split(t)是按tab分割 # 分成了4列数据,得到了4个列表 returnMat[index, :] = listFromLine[0:3] # 将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵 classLabelvector.append(int(listFromLine[-1])) # 将不喜欢,极具魅力,一般魅力填到分类标签 index += 1 # 继续迭代 return returnMat, classLabelvector # 返回样本数据和特征矩阵和分类标签 def autoNorm(dataSet): # 归一化特征值 # X' = ( X - Xmin) / ( Xmax - Xmin) 归一化特征值的求解 minVals = dataSet.min(0) # 取出数据集中每一列的最小值 maxVals = dataSet.max(0) # 取出数据集中每一列的最大值 # 可以指定关键字参数axis来获得行最大(小)值或列最大(小)值 # print(minVals) # axis=0 行方向最大(小)值,即获得每列的最大(小)值 # axis=1 列方向最大(小)值,即获得每行的最大(小)值 ranges = maxVals-minVals # 计算差值 normDataSet = zeros(shape(dataSet)) # 初始化一个矩阵,该矩阵和所给数据集维度相同,用于存放归一化之后的数据 m = dataSet.shape[0] # 取出数据集的行数 normDataSet = dataSet - tile(minVals, (m, 1)) # 这里tile()函数创建了一个以min_value为值的m行列向量,然后计算oldValue-min_value normDataSet = normDataSet/tile(ranges, (m, 1)) # 特征值相除得到归一化后的数值 return normDataSet, ranges, minVals # 返回归一化后的数据,差值,最小值 def img2vector(filename): # 将图像转换为向量 returnVect = zeros((1, 1024)) # 创建1*1024的numpy数组 fr = open(filename) # 打开给定文件 for i in range(32): # 循环读出文件的前32行,并且将每行的头32个字符值存储在numpy数组中,最后返回数组 lineStr = fr.readline() for j in range(32): returnVect[0, 32*i+j] = int(lineStr[j]) return returnVect def handwritingClassTest(): # 手写数字识别系统的测试代码 hwLabels = [] # 类别标签 trainingFileList = listdir('digits/trainingDigits') # 获取文件夹目录 m = len(trainingFileList) # 获取文件夹下文件数目 trainingMat = zeros((m, 1024)) # 定义一个m*1024的矩阵,填充为0 for i in range(m): #遍历目录,截取文件名,获得真正的数字标签 fileNameStr = trainingFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) hwLabels.append(classNumStr) trainingMat[i, :]=img2vector('digits/traingDigits/%s' % fileNameStr) #将图片fileNameStr转化为向量 testFileList =listdir('digits/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('digits/testDigits/%s' % fileNameStr) classifierResult = classify(vectorUnderTest, trainingMat, hwLabels, 3) print("the classifier came bake with: %d,the real answer is: %d" % (classifierResult, classNumStr)) if (classifierResult != classNumStr): errorCount +=1.0 print("the total number of errors is: %d" % errorCount) print("the total error rate is: %f" % (errorCount/float(mTest)))
测试kNN算法。
from kNN import * import matplotlib import numpy as np import matplotlib.pyplot as plt # group,labels= kNN.createDataSet() # print(kNN.classify([0.5, 1], group, labels, 3)) # datingDataMat,datingLabels=file2matrix('datingTestSet2.txt') # print(datingDataMat) # print(datingLabels) # # fig = plt.figure() # ax = fig.add_subplot(111) #画图 看线性关系 # ax.scatter(datingDataMat[:, 0],datingDataMat[:, 1]) # plt.show() # normMatch, ranges, minVals = autoNorm(datingDataMat) # print(normMatch) # print(ranges) # print(minVals) def datingClassTest(): # 分类器针对约会网站的测试代码 hoRatio = 0.10 # 测试样本比率 datingDataMat, datingLabels=file2matrix('datingTestSet2.txt') # 取样本的特征矩阵,特征标签 normMat, ranges, minVals = autoNorm(datingDataMat) # 特征矩阵归一化 m = normMat.shape[0] # 取矩阵的行数 numTestVecs = int(m*hoRatio) # 测试的个数 erroCount = 0.0 # 出错的个数 for i in range(numTestVecs): # 遍历测试集 classifierResult = classify(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) # 分类器(需要测试的向量,训练样本集(90%),标签集合,K) # {(分类输入向量,inX(分类坐标)),(输入训练样本集,dataSet(createDataSet的array,已经分类过的坐标)),(标签向量(分类标签),labels),(最近邻居的数目,k)} # 输出最接近的结果和原始数据进行比较 print("the classifier came back with: %d, the real answer is: %d" % (classifierResult,datingLabels[i])) if (classifierResult != datingLabels[i]): erroCount +=1.0 print("the total error rate is: %f" % (erroCount/float(numTestVecs))) datingClassTest() def classifyPerson(): # 约会网站预测函数 resultList = ['not at tall', 'in small doses', 'in large doses'] # 输出结果列表 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('datingTestSet2.txt') # 取特征矩阵和吧特征标签 norMat, ranges, minVals = autoNorm(datingDataMat) # 特征矩阵归一化 inArr = np.array([ffMiles, percentTats, iceCream]) # 将输入的三个数据形成列表形式 clasifierResult = classify((inArr - minVals)/ranges, norMat, datingLabels, 3) # 求出最接近的类别标号 print("You will probably like this person:", resultList[clasifierResult - 1]) classifyPerson() testVector = img2vector('digits/testDigits/0_13.txt') print(testVector[0, 0:31]) print(testVector[0,32:63])
数据集在网上自己下载
最后
以上就是害怕电源为你收集整理的菜鸟初学者第三周之k近邻算法 及测试的全部内容,希望文章能够帮你解决菜鸟初学者第三周之k近邻算法 及测试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复