kNN算法原理与实战
2017-12-01 20:53
176 查看
kNN简单数据分类实践
<比如:计算地理位置的相似度>……
有以下先验数据,使用knn算法对未知类别数据分类
属性1 | 属性2 | 类别 |
---|---|---|
1.0 | 1.0 | A |
0.1 | 0.2 | B |
0.0 | 0.1 | B |
属性1 | 属性2 | 类别 |
---|---|---|
1.2 | 1.0 | ? |
0.1 | 0.3 | ? |
python实现
# _*_ coding: utf-8 _*_ from numpy import * import operator ''' kNN:k近邻 Input: inX: 待分类向量 (1xN) dataSet: 先验数据集 (NxM) labels: 先验数据分类标签 (1xM vector) k: 参数:k个近邻 (should be an odd number) Output: 分类标签 ''' # 创建一个数据集,包含2个类别共4个样本 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 # KNN分类器 def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # shape[0]表示行数 ## step 1: 计算距离 diffMat = tile(inX, (dataSetSize, 1)) - dataSet # 按元素求差值 tile sqDiffMat = diffMat**2 # 将差值平方 sqDistences = sqDiffMat.sum(axis=1) # 按行累加 distences = sqDistences**0.5 #将差值平方和求开方,即得距离 ## step 2: 对距离排序 sortedDistIndicies = distences.argsort() # 排序后的索引 argsort() 返回排序后的索引值 ## step 3: 选择k个最近邻 classCount = {} for i in range(k): voteLable = labels[sortedDistIndicies[i]] ## step 4: 计算k个最近邻中各类别出现的次数 classCount[voteLable] = classCount.get(voteLable, 0) + 1 ## step 5: 返回出现次数最多的类别标签 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] if __name__ == '__main__': # kNN分类器测试 group, labels = createDataSet() res = classify0([3,3], group, labels, 3) print(res)
输出结果为 A
运行过程中各个变量的值:
约会对象分类
婚恋网站数据: data/datingTestSet2.txt属性:
每年的飞行里程
玩游戏所花时间百分比
每年吃几升冰激凌
标签:
3 -> 喜欢 2 -> 一般 1 -> 不喜欢
dating.py
# _*_ coding: utf-8 _*_ import kNN from numpy import * # # Author: yz # Date: 2017-12-01 # ''' 约会对象分类 婚恋网站数据:datingTestSet2.txt 每年的飞行里程 玩游戏所花时间百分比 每年吃几升冰激凌 3 -> 喜欢 2 -> 一般 1 -> 不喜欢 验证结果: 前50%作为测试集,后50%作为训练集: 错误的数量为33 错误率为0.066 前50%作为训练集,后50作为测试集: 错误的数量为19 错误率为0.038 ''' # 文件转换成矩阵 def file2matrix(filename): file = open(filename) numOfLines = len(file.readlines()) # 文件的行数 returnMat = zeros((numOfLines, 3)) # 初始化要return的矩阵,numOfLines行,3列 classLabelVector = [] # 初始化要return的标签向量 index = 0 file = open(filename) for line in file.readlines(): line = line.strip() listFromLine = line.split('\t') returnMat[index, :] = listFromLine[0:3] classLabelVector.append(int(listFromLine[-1])) index += 1 return returnMat, classLabelVector # 归一化 # 每列的range = 每列的最大值 - 每列的最小值 # 每个元素归一化后的值 = (原来的值 - 该列的最小值) / 该列的最大值 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(maxVals, (m, 1)) return normDataSet # 用50%数据来做测试,统计分类结果错误率 总共1000行数据 def datingClassTest(): ratio = 0.50 # 训练和测试的比例 datingDataMat, datingLabels = file2matrix('data/datingTestSet2.txt') normMat = autoNorm(datingDataMat) m = normMat.shape[0] # 行数 numTestVecs = int(m * ratio) errorCount = 0 for i in range(numTestVecs): classifyRes = kNN.classify(normMat[i, :], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m], 3) print("kNN分类器分类结果为:{}, 真实的类别为:{}".format(classifyRes, datingLabels[i]) ) if (classifyRes != datingLabels[i]): errorCount += 1 print("错误的数量为%d" % errorCount) print("错误率为{}".format(str(errorCount/numTestVecs))) # 图形化展现 def graphicalDisplay(): import matplotlib.pyplot as plt datingDataMat, datingLabels = file2matrix('data/datingTestSet2.txt') fig = plt.figure() ax = fig.add_subplot(111) # ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels)) # ax.scatter(datingDataMat[:, 0], datingDataMat[:, 2], 15.0 * array(datingLabels), 15.0 * array(datingLabels)) ax.scatter(datingDataMat[:, 0], datingDataMat[:, 1], 15.0 * array(datingLabels), 15.0 * array(datingLabels)) plt.show() if __name__ == '__main__': # 约会对象分类效果测试 datingClassTest() # 图形化展现 graphicalDisplay()
kNN实现手写数字识别
需求利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别;
先验数据(训练数据)集:
数据维度比较大,样本数比较多。
数据集包括数字0-9的手写体。
每个数字大约有200个样本。
每个样本保持在一个txt文件中。
手写体图像本身的大小是32x32的二值图,转换到txt文件保存后,内容也是32x32个数字,0或者1,如下:
模型分析:
- 1、手写体因为每个人,甚至每次写的字都不会完全精确一致,所以,识别手写体的关键是“相似度”
- 2、既然是要求样本之间的相似度,那么,首先需要将样本进行抽象,将每个样本变成一系列特征数据(即特征向量)
- 3、手写体在直观上就是一个个的图片,而图片是由上述图示中的像素点来描述的,样本的相似度其实就是像素的位置和颜色之间的组合的相似度
- 4、因此,将图片的像素按照固定顺序读取到一个个的向量中,即可很好地表示手写体样本
- 5、抽象出了样本向量,及相似度计算模型,即可应用KNN来实现
handWriting.py
# _*_ coding: utf-8 _*_ import kNN from numpy import * from os import listdir # # Author: yz # Date: 2017-12-01 # ''' 利用分类器进行手写数字识别测试 识别结果: 错误的数量为10 错误率为0.010570824524312896 ''' def img2vector(filePath): returnVect = zeros((1, 1024)) file = open(filePath) for i in range(32): line = file.readline() for j in range(32): returnVect[0,32*i+j] = int(line[j]) return returnVect def handwritingClassTest(): trainingFilePath = "data/digits/trainingDigits/" testFilePath = "data/digits/testDigits/" hwLabels = [] trainingFileList = listdir(trainingFilePath) m = len(trainingFileList) # 1934 trainingMat = zeros((m, 1024)) for i in range(m): fileNameStr = trainingFileList[i] # 0_10.txt fileName = fileNameStr.split(".")[0] # 0_10 classNum = int(fileName.split("_")[0]) # 0 hwLabels.append(classNum) trainingMat[i, :] = img2vector(trainingFilePath + fileNameStr) testFileList = listdir(testFilePath) errorCount = 0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileName = fileNameStr.split(".")[0] classNum = int(fileName.split("_")[0]) testVector = img2vector(testFilePath + fileNameStr) classifyRes = kNN.classify(testVector, trainingMat, hwLabels, 3) print("kNN分类器分类结果为:{}, 真实的数字为:{}".format(classifyRes, classNum)) if (classifyRes != classNum): errorCount += 1 print("错误的数量为%d" % errorCount) print("错误率为{}".format(str(errorCount / mTest))) if __name__ == '__main__': handwritingClassTest()
ps: 本文所有代码和数据集已上传到我的github: MachineLearning/kNN/
相关文章推荐
- KNN算法原理简介
- 机器学习实战:KNN算法
- 深度学习之神经网络(CNN/RNN/GAN) 算法原理+实战
- 机器学习实战笔记——基于KNN算法的手写识别系统
- 机器学习实战 kNN算法
- 机器学习笔记--KNN算法2-实战部分
- KNN(k-nearest neighbor的缩写)最近邻算法原理详解
- 机器学习实战_kNN算法python3.6实现与理解
- Python 学习笔记(Machine Learning In Action)K-近邻算法(KNN)机器学习实战
- kNN算法——python(机器学习实战)
- 机器学习实战第二章——KNN算法(源码解析)
- [置顶] Hadoop伪分布安装详解+MapReduce运行原理+基于MapReduce的KNN算法实现
- Spark 随机森林算法原理、源码分析及案例实战
- 机器学习实战——python实现knn算法
- 机器学习实战(①)——KNN算法改进约会网站的配对效果和手写字识别系统
- 机器学习实战之kNN算法
- 机器学习实战之KNN算法
- 机器学习实战-KNN 算法
- 机器学习实战之KNN算法识别手写数字_代码注释
- 步步学习之用python实战机器学习1-kNN (K-NearestNeighbors)算法(a)