1、概述python
优势:精度高、对异常值不敏感、无数据输入限定算法
缺点:计算复杂度高、空间复杂度高app
使用数据范围:数值型和标称型。测试
2、原理网站
存在一个样本数据集合(训练样本集合),而且样本集中每个数据都存在标签,即咱们知道样本集中每个数据与所属分类的对应关系。输入没有标签的新数据,将新数据的每一个特征值与样本集中的数据对应的特征进行比较。而后算法提取样本集中特征最类似的分类标签。一般k不大于20的整数。spa
3、例子1:电影分类code
分类爱情片和动做片。统计不少电影中打斗镜头和接吻镜头。orm
电影名称 | 打斗镜头 | 接吻镜头 | 电影类型 |
california man视频 |
3 | 104 | 爱情片 |
he's not really into dudes | 2 | 100 | 爱情片 |
beautiful woman | 1 | 81 | 爱情片 |
kevin longblade | 101 | 10 | 动做片 |
robo slayer 3000游戏 |
99 | 5 | 动做片 |
amped II |
98 | 2 | 动做片 |
? | 18 | 90 | ? |
电影名称 | 与未知电影距离 |
california man |
20.5 |
he's not really into dudes | 18.7 |
beautiful woman | 19.2 |
kevin longblade | 115.3 |
robo slayer 3000 |
117.4 |
amped II |
118.9 |
假定k=3 依次是california man,he's not really into dudes,beautiful woman ===> 断定为爱情片
4、例子2:约会网站的配对效果
玩视频游戏所耗时间百分比 |
每一年得到飞行常客里程数 | 每周消费的冰激凌公升数 | 样本分类 |
0.8 | 400 | 0.5 | 1 |
12 | 134000 | 0.9 | 3 |
0 | 20000 | 1.1 | 2 |
1.收集数据:提供文本文件
==>每一个样本数据占据一行,总共1000行,包含3个特征
a.每一年得到飞行常客里程数
b.玩视频游戏所耗时间百分比
c.每周消费的冰激凌公升数
2.准备数据:数据归一化
kNN使用欧几里得距离公式
[(0.8-12)^2 + (400 - 134000)^2 + (0.5 - 0.9)^2]^0.5
===> 容易看出,数值大的属性对计算结果的影响最大。也就是说“每一年得到飞行常客里程数”的影响要远远大于其余属性的影响。咱们须要等权重特征化。
newValue = (oldValue - min)/(max - min)
$ cat datingTestSet2.txt | head -n 4 40920 8.326976 0.953952 3 14488 7.153469 1.673904 2 26052 1.441871 0.805124 1 75136 13.147394 0.428964 1 # 文本文件转换成数据矩阵 def file2matrix(filename): fr = open(filename) arrayOLines = fr.readlines() ==>读取文档有多少行,要构建矩阵 numberOfLines = len(arrayOLines) returnMat = zeros((numberOfLines,3)) ==>初始0矩阵 classLabelVector= [] index = 0 for line in arrayOLines: line = line.strip() listFromLine = line.split('\t') ==> \t 分隔每一行 returnMat[index,:] = listFromLine[0:3] ==> 每一行特征值组成矩阵的一行 classLabelVector.append(int(listFromLine[-1])) ==> 标签向量 index += 1 return returnMat,classLabelVector #数据归一化 #newValue = (oldValue - min)/(max - min) def autoNorm(dataSet): minVals = dataSet.min(0) ==>计算矩阵每一列最小值 maxVals = dataSet.max(0) ==>计算矩阵每一列最大值 ranges = maxVals - minVals ==>矩阵相减,即对应行向减 m = dataSet.shape[0] ==>矩阵行数 normDataSet = dataSet - tile(minVals, (m,1)) ==>tile(minVals, (m,1))构建行数相同的最小值矩阵 normDataSet = normDataSet / tile(ranges, (m,1)) ==>tile(ranges, (m,1))构建行数相同的差值矩阵 return normDataSet,ranges,minVals def datingClassTest(): hoRatio = 0.1 ==>切分样本,一部分做为训练样本,一部分做为测试样本 datingDataMat,datingLabels = file2matrix('') ==>加载文本文件,并转化为数据矩阵 normMat,ranges,minVals = autoNorm(datingDataMat) ==>数据归一化 m = normMat.shape[0] numTestVecs = int(m*hoRatio) errorCount = 0.0 for i in range(numTestVecs): classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m], 3) ==>对输入的测试集的每一行进行断定 print 'the classifier came back with:%d, the real answer is:%d' % (classifierResult,datingLabels[i]) if(classifierResult != datingLabels[i]): ==>对比计算结果和原始结果,统计错误率 errorCount+=1.0 print 'the total error rate is: %f' % (errorCount/float(numTestVecs)) print errorCount