理想環(huán)境下的kNN
計(jì)算距離 ->取最近的K個(gè)值 -> 選取占比高的類別
1. 計(jì)算距離

原始數(shù)據(jù):9條數(shù)據(jù),2個(gè)屬性,2個(gè)類別
對于待分類的點(diǎn)**(61,20) **, 可以得到對于每個(gè)點(diǎn)的距離,使用曼哈頓距離公式.我不是為了偷懶,就是用這個(gè)
| 項(xiàng)目 | X1 | X2 | X3 | X4 | X5 | X6 | X7 | X8 | X9 |
|---|---|---|---|---|---|---|---|---|---|
| 距離 | 11 | 20 | 6 | 14 | 3 | 81 | 68 | 86 | 71 |
| 類別 | A | A | A | A | B | B | B | B | B |
2. 最近k個(gè)
最近的三個(gè)依次是X5-B,X3-A,X1-A
3. 判斷類別
A占66%,B占33%
所以待分類點(diǎn)**(61,20) **是A類別
4. 簡單py實(shí)現(xiàn)
計(jì)算機(jī)負(fù)責(zé)計(jì)算,可以舍棄曼哈頓距離了,用最經(jīng)典的歐幾里得距離
# -*- coding: utf-8 -*-
__author__ = 'Matter-YYF'
from numpy import *
import operator
def createDataSet():
# numpy的array可以初始化矩陣
group = array([[50.0,20.0],[53.0,32.0],[60.0,25.0],
[65.0,30.0],[58.0,20.0],[10.0,50.0],
[20.0,47.0],[15.0,60.0],[25.0,55.0]])
label = ['A','A','A','A','B','B','B','B','B',]
return group,label
def classify0(inX, dataSet, labels, k):
# shape屬性是行列數(shù)
dataSetSize = dataSet.shape[0]
# 用tile創(chuàng)建重復(fù)數(shù)組,此處用于創(chuàng)建矩陣 tile([61.0,20.0],(9,1))
diffMat = tile(inX,(dataSetSize,1))-dataSet
sqDiffMat = diffMat ** 2
# 矩陣每行相加
sqDistance = sqDiffMat.sum(axis=1)
distance = sqDistance ** 0.5
# 字典key排序
sortedDistIndex = distance.argsort()
classCount = {}
for i in range(k):
voteLabel = labels[sortedDistIndex[i]]
# XX.get(a,b):有key=a的則取對應(yīng)value,沒有則為b
classCount[voteLabel] = classCount.get(voteLabel,0)+1
# 前k個(gè)類別的排序
sortedClassCount = sorted(classCount.iteritems(),
key=operator.itemgetter(1),
reverse=True)
# 返回占比例最高的類別
return sortedClassCount[0][0]
dataSet,label = createDataSet()
resultKNN = classify0([61.0,20.0],dataSet,label,3)
print resultKNN
歡迎回到現(xiàn)實(shí)世界
1. 手輸數(shù)據(jù)是有多蛋疼...

勞資是程序猿,不干low活
得從文件讀數(shù)據(jù)啊
def file2matrix(filename):
fr = open(filename)
arrayOfLines = fr.readlines()
numberOfLines = len(arrayOfLines)
returnMat = zeros((numberOfLines,3)) # 生成一個(gè)空白矩陣,3列
classLabelVector = []
index = 0
for line in arrayOfLines:
line = line.strip() # 刪除空白符:'\n','\r','\t',' '
listFromLine = line.split('\t') # 以制表符為分割生成列表
returnMat[index,:] = listFromLine[0:3] # 前三個(gè)項(xiàng)目是數(shù)據(jù)屬性
classLabelVector.append(int(listFromLine[-1])) # 最后是類別標(biāo)簽
index+=1
return returnMat, classLabelVector
2. 數(shù)據(jù)怎么跨度這么大...

10w和25在一起,好別扭
歸歸歸歸一化

線性函數(shù)歸一化(Min-Max scaling)
def autoNorm(dataSet):
minVals = dataSet.min(0) # 所有列里各自最小值
maxVals = dataSet.max(0) # 所有列里各自最大值
ranges = maxVals -minVals # 歸一化計(jì)算公式分母
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0] # 數(shù)據(jù)行數(shù)
normDataSet = dataSet-tile(minVals,(m,1)) # 分子
normDataSet = normDataSet/tile(ranges,(m,1)) #計(jì)算結(jié)果
return normDataSet, ranges, minVals