KNN算法
来源:互联网 发布:计数返礼物软件 编辑:程序博客网 时间:2024/06/08 13:53
今天想写一下KNN算法,看完机器学习实战,就来分享一下吧。
原理:存在一个样本数据集合,也叫训练集,并且样本集中每个数据都存在标签,即我们知道样本集中的每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的吗,每个特征与样本集中的数据对应的特征进行比较,然后算法提取样本集中特征最相似数据的分类标签。一般来说,我们只选择样本集中前k个最相似的数据,这也是K-近邻算法中k的出处。通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
优点:精度高,对异常值不敏感,无数据输入假定。
缺点:计算复杂度高,空间复杂度高。
使用数据范围:数值型与标称型
借助机器学习实战书中的一个例子来看下:
使用KNN算法将每组数据划分到某个类中,伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作:
1,计算已知类别数据集中的点与当前点之间的距离;
2,按照距离递增进行排序;
3,选取与当前点距离最小的K个点;
4,确定前K个点所在的类别的出现频率;
5,返回前K个点出现频率最高的类别作为当前点的预测分类。
代码如下:
# -*- coding:utf-8 -*-from numpy import *import operatordef createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) labels = ['A','A','B','B'] return group,labelsdef classify0(inX,dataSet,labels,k): """ :param inX: 用于分类的输入向量 :param dataSet: 输入的训练样本集 :param labels: 标签向量 :param k: 选择最近邻居的数目,其中标签向量的元素数据和矩阵dataset的行数相同 :return: """ 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() classCount={} #选择距离最小的K个点,排序 for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] #将classCount字典分解为元组列表,然后使用operator模块的itemgetter(1)对第二个元素进行排序 classCount[voteIlabel] = classCount.get(voteIlabel,0)+1 sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse=True) return sortedClassCount[0][0]group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels = ['A','A','B','B']print classify0([0,0],group,labels,3)输出结果:B
以上代码计算距离的使用的欧式距离。
再来一个例子,单身汪可以参考一下,使用KNN算法改进约会网站的配对效果
"""使用KNN算法改进约会网站的配对效果"""def file2matrix(filename): fr = open(filename) arrayOLines = fr.readlines() #得到文本行数 numberOfLines = len(arrayOLines) returnMat = zeros((numberOfLines,3)) #创建返回的numpy矩阵 classLabelVector = [] index =0 #解析文件数据到列表 for line in arrayOLines: line = line.strip() listFormLine = line.split('\t') returnMat[index,:]=listFormLine[0:3] classLabelVector.append(int(listFormLine[0])) index+=1 return returnMat,classLabelVectordatingDataMat,datingLabels = file2matrix('datingTestSet.txt')import matplotlib.pyplot as pltfig = plt.figure()ax = fig.add_subplot(111)ax.scatter(datingDataMat[:,1],datingDataMat[:,2])plt.show()
以上数据集中有三个主要的特征:1,每年获得飞行常客里程数;2,玩游戏所耗费的时间半分比;3,每周消费的冰淇淋公升数。
"""有时候数据有严重的不平衡现象,这个时候可以对数据进行归一化,"""#归一化数据,使用的0均值归一法def autoNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals-minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet-tile(minVals,(m,1)) #tile函数将变量内容复制成输入矩阵同样大小的矩阵 normDataSet = normDataSet/tile(ranges,(m,1))#特征值相除 return normDataSet,ranges,minValsnormMat,ranges,minVals= autoNorm(datingDataMat)#print normMat,ranges,minVals#分类器针对约会网站的测试代码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): classiferResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3) print "the classifier came back with:%d,the real answer id:%d" % (classiferResult,datingLabels[i]) if (classiferResult !=datingLabels[i]):errorCount +=1.0 print "the total error rate is :%f" %(errorCount/float(numTestVecs))
#约会网站预测函数def classifyPerson(): resultList = ['not at all','is small doses','in large doese'] percentTats = float(raw_input('percentage of time spent playing video games?')) ffMiles = float(raw_input("frequent fliter miles earned per year?")) iceCream = float(raw_input('liter of ice cream consumed per year?')) datingDataMat ,datingLabels=file2matrix('datingTestSet2.txt') normMat,ranges,minVals=autoNorm(datingDataMat) inArr = array([ffMiles,percentTats,iceCream]) classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3) print "You will probably like this person:",resultList[classifierResult-1]
测试算法:使用KNN算法识别手写数字
#手写识别系统""" 将图像转换为向量,创建一个1*1024的numpy数组,然后打开给定的文件,循环读取文件的前32行 并将每行的头32个字符值存储在numpy数组中,最后返回数组。 :param filename: :return: """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 #手写数字识别系统的测试代码def handwritingClassTest(): hwLabels = [] trainingFileList = listdir('trainingDigits') #load the training set m = len(trainingFileList) trainingMat = zeros((m,1024)) for i in range(m): fileNameStr = trainingFileList[i] fileStr = fileNameStr.split('.')[0] #take off .txt classNumStr = int(fileStr.split('_')[0]) hwLabels.append(classNumStr) trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr) testFileList = listdir('testDigits') #iterate through the test set errorCount = 0.0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileStr = fileNameStr.split('.')[0] #take off .txt 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))
部分结果如下:
the total number of errors is: 11
the total error rate is: 0.011628
None
Process finished with exit code 0
KNN识别手写数字数据集,错误率为1.2%,改变边量K的值,修改函数随机选取训练样本的数目,都会对KNN算法的错误率有影响。
总结:KNN是分类数据最简单最有效的算法,基于实例的学习,使用算法时候我们必须有接近实际数据的训练样本数据。KNN算法必须保存全部数据,如果数据集过大的话,就需要大量的存储空间。除此之外还要计算距离值,会耗费一些时间。另外一个缺陷是它无法给出数据的基础结构信息,因此无法知晓平均市济阳吧和典型实例样本具有什么特征。
- KNN算法
- KNN算法
- KNN算法
- KNN算法
- kNN算法
- KNN算法
- KNN算法
- KNN算法
- KNN算法
- knn算法
- kNN算法
- knn算法
- KNN算法
- KNN算法
- KNN算法
- KNN算法
- kNN算法
- KNN算法
- RxJava2.0&Retrofit2.0+MVP模式---DeMon_MVPRR框架使用及说明
- winform datagridview如何设置datagridview隔行变色
- kmalloc()、kzalloc()、vmalloc() 内存申请
- 丑数
- c++11:智能指针之unique_ptr
- KNN算法
- Android 8.0 7.0 6.0 动态权限管理方案
- 红黑树学习笔记整合
- Qt学习 前章3-Qt-元对象和属性机制
- The last packet sent successfully to the server was 0 milliseconds ago.
- ViewPager的基础使用(一)
- python基础数据处理
- 欢迎使用CSDN-markdown编辑器
- win10 oracle12c 安装教程