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