K-近鄰算法
優(yōu)點:精度高感憾、對異常值不敏感、無數(shù)據(jù)輸入假定
缺點:計算復雜高磕诊、空間復雜度高
適用數(shù)據(jù)范圍:數(shù)值型和標稱型
一般流程
收集數(shù)據(jù):可以使用任何方法
準備數(shù)據(jù):距離計算所需要的數(shù)值哮兰,最好是結構化的數(shù)據(jù)結構
分析數(shù)據(jù):可以使用任何方法
訓練算法:此步驟不適用于K-近鄰算法
測試算法:計算錯誤率
使用算法:首先需要輸入樣本數(shù)據(jù)和結構化的輸出結果结缚,然后運行K-近鄰算法判定輸入數(shù)據(jù)分別屬于哪個分類竿痰,最后應用對計算出的分類執(zhí)行后續(xù)的處理脆粥。
def createDataset():
????group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])? ? #我覺得可以這樣理解砌溺,每一種方括號都是一個維度(秩),這里就是二維數(shù)組变隔,最里面括著每一行的有一個方括號抚吠,后面又有一個,就是二維弟胀,四行
????labels=['A','A','B','B']
????return group,labels
createDataset()函數(shù)創(chuàng)造數(shù)據(jù)集和標簽
K-近鄰算法偽代碼
計算已知類別數(shù)據(jù)集中的點與當前點之間的距離
按照距離遞增次序排序
選取與當前點距離最小的k個點
確定前k個點所在類別的出現(xiàn)頻率
返回前k個點出現(xiàn)頻率最高的類別作為當前點的預測分類
def classify0(inX,dataSet,labels,k):? ?#inX是你要輸入的要分類的“坐標”,dataSet是上面createDataSet的array喊式,就是已經(jīng)有的孵户,分類過的坐標,label是相應分類的標簽岔留,k是KNN夏哭,k近鄰里面的k
????dataSetSize=dataSet.shape[0]? ? #dataSetSize是dataSet的行數(shù),用上面的舉例就是4行
????diffMat=tile(inX,(dataSetSize,1))-dataSet????#前面用tile献联,把一行inX變成4行一模一樣的(tile有重復的功能竖配,dataSetSize是重復4遍,后面的1保證重復完了是4行里逆,而不是一行里有四個一樣的)进胯,然后再減去dataSet,是為了求兩點的距離原押,先要坐標相減胁镐,這個就是坐標相減
????sqDiffMat=diffMat**2????#上一行得到了坐標相減,然后這里要(x1-x2)^2诸衔,要求乘方
? ? sqDistance=sqDiffMat.sum(axis=1)????#axis=1是列相加盯漂,這樣得到了(x1-x2)^2+(y1-y2)^2
????distances=sqDistance**0.5????#開根號,這個之后才是距離
? ? sortedDistIndicies=distances.argsort()???? #argsort是排序笨农,將元素按照由小到大的順序返回下標就缆,比如([3,1,2]),它返回的就是([1,2,0])
????classCount={}
????for i in range(k):
????????voteIlabel=labels[sortedDistIndicies[i]]
????????classCount[voteIlabel]=classCount.get(voteIlabel,0)+1???? #get是取字典里的元素,如果之前這個voteIlabel是有的谒亦,那么就返回字典里這個voteIlabel里的值竭宰,如果沒有就返回0(后面寫的),這行代碼的意思就是算離目標點距離最近的k個點的類別诊霹,這個點是哪個類別哪個類別就加1
? ? sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)????#key=operator.itemgetter(1)的意思是按照字典里的第一個排序羞延,{A:1,B:2},要按照第1個(AB是第0個),即‘1’‘2’排序脾还。reverse=True是降序排序
????return sortedClassCount[0][0]????#返回類別最多的類別