k-近鄰算法筆記(1)

學習到的第一個機器學習算法是“k-近鄰算法 (kNN) ”, 它的工作原理是:
存在一個樣本數據集合,也稱作訓練樣本集,并且樣本集中每個數據都存在標簽,即我們知道樣本集中每一數據與所屬分類的對應關系。輸人沒有標簽的新數據后,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中特征最相似數據(最近鄰)的分類標簽。一般來說,我們 只選擇樣本數據集中前k個最相似的數據,這就是k-近鄰算法中k的出處,通常k是不大于20的整數。 最后,選擇k個最相似數據中出現次數最多的分類,作為新數據的分類。

準備工作:建立訓練用樣本集group和其標簽集labels

import numpy as np
import operator
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def createDataSet():
    group=np.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]#查看訓練集有多少行,即有多少個實例。
    diffMat=np.tile(inX,(dataSetSize,1))-dataSet
    #將測試數據也重復擴大成訓練集一樣的形式
    #tile函數詳細:http://blog.csdn.net/april_newnew/article/details/44176059
    sqDiffMat=diffMat**2#平方運算
    sqDistances=sqDiffMat.sum(axis=1)
    distances=sqDistances**0.5#開根運算
    sortedDistIndicies=distances.argsort()#argsort返回升序排序后的索引值。
    #關于argsort詳細:http://blog.csdn.net/maoersong/article/details/21875705
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]#將標簽向量按排序索引存儲于voteIlabel中
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#對前k個點所在類別進行出現次數統計。
        #關于get函數:http://www.runoob.com/python/att-dictionary-get.html
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    #iteritems()迭代輸出字典的鍵值對,與item()類似,用法iter = dict.iteritems() iter.next()
    #itemgetter(1)表明按值排序,reverse=True表明降序排序。

函數的四個參數分別為:
inX:需要分類的測試數據。
dataSet:訓練樣本集
labels:訓練樣本集的標簽集
k:需要取的最相近距離的個數。

兩點間距離公式如下:


在約會網站數據上使用kNN算法

  1. 讀取文件
def file2matrix(filename):#文件讀取,提取特征和標簽
    fr=open(filename)
    arrayOLines=fr.readlines()
    numberOfLines=len(arrayOLines)
    returnMat=np.zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    for line in arrayOLines:
        line=line.strip() #移除每行首尾指定字符。參數為空則移除空白符(如/d,/r,/n等)
        listFromLine=line.split('\t')
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index +=1
    return returnMat,classLabelVector
datingDataMat,datingLabels=file2matrix('文件路徑')
  1. 準備數據:歸一化數值
    歸一化公式:newValue = {oldValue-min)/(max-min)
def autoNorm(dataSet):#歸一化特征值函數
    minVals=dataSet.min(0) #axis=0,求每列中的最小值
    maxVals=dataSet.max(0)# 求每列中的最大值。詳細參考:http://blog.csdn.net/qq_18433441/article/details/54743271
    ranges=maxVals-minVals
    normDataSet=np.zeros(np.shape(dataSet))
    m=dataSet.shape[0]#取dataSet的行數 詳細參考:http://blog.csdn.net/u010758410/article/details/71554224
    normDataSet=dataSet-np.tile(minVals,(m,1))
    normDataSet=normDataSet/np.tile(ranges,(m,1))
    return normDataSet,ranges,minVals
normMat,ranges,minVals=autoNorm(datingDataMat)

3.測試算法:作為完整程序驗證分類器

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],5)
        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))
  1. 使用算法構建完整可用系統:??
def classifyPersion():
    resultList=['not at all','in small doses','in large doses']
    persenTats=float(raw_input("percentage of time spent playing video games?"))
    ffMiles=float(raw_input("freguent flier miles earned per year?"))
    iceCream=float(raw_input("liters of ice cream consumed per year?"))
    datingDataMat,datingLabels=file2matrix('文件路徑')
    normMat,ranges,minVals=autoNorm(datingDataMat)
    inArr=np.array([ffMiles,persenTats,iceCream])
    classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
    print "You will probably like this person:",resultList[classifierResult-1]

classifyPersion()

代碼里自己總結的一些小疑問。

  1. shape[0]
    函數中,shape[0]用于查看訓練樣本集有多少行,即有多少實例。

  2. tile函數
    用np.tile函數將測試數據重復,擴大為和訓練數據集一樣的大小。用這個擴大后的測試數據集和訓練樣本集相減,即為diffMat。
    關于tile函數的具體使用參考:http://blog.csdn.net/april_newnew/article/details/44176059

  3. **2運算
    2為平方運算,0.5為開根運算

  4. .sum(axis=1)
    axis=1表示按行相加。axis=0表示按列相加。

  5. argsort()
    distances.argsort()返回升序排序后的索引值。
    關于argsort()詳細用法參考:http://blog.csdn.net/maoersong/article/details/21875705

  6. get函數
    classCount.get(voteIlabel,0)返回計數字典里voteIlabel這個類別的出現次數。即鍵voteIlabel對應的值。還沒被統計過,也就是不存在的話,返回默認值0
    關于get函數的詳細用法參考:http://www.runoob.com/python/att-dictionary-get.html

  7. sorted函數
    sorted函數為用于列表或者iterator的排序函數,其直接返回一個排序后的新數據,而不是對原數據進行操作。
    四個參數:
    classCount.iteritems() :teritems()迭代輸出字典的鍵值對,與item()類似
    key=operator.itemgetter(1):itemgetter(1)表明按值排序,0表明按鍵排序。
    reverse=True:表明降序排序
    itemgetter詳細:http://blog.163.com/wjyydhs810@126/blog/static/162071754201411864324976/
    排序詳解:https://www.douban.com/note/271284737/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容