欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)

系統 1620 0

目錄

  • 工作原理
  • python實現
  • 算法實戰
    • 約會對象好感度預測
      • 故事背景
      • 準備數據:從文本文件中解析數據
      • 分析數據:使用Matplotlib創建散點圖
      • 準備數據:歸一化數值
      • 測試算法:作為完整程序驗證分類器
      • 使用算法:構建完整可用的系統
    • 手寫識別系統
      • 準備數據:將圖像轉換為測試向量
      • 測試算法:使用k-近鄰算法識別手寫數字
  • 小結
  • 附錄

工作原理

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

舉個例子,現在我們用k-近鄰算法來分類一部電影,判斷它屬于愛情片還是動作片。現在已知六部電影的打斗鏡頭、接吻鏡頭以及電影評估類型,如下圖所示。

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)_第1張圖片

現在我們有一部電影,它有18個打斗鏡頭、90個接吻鏡頭,想知道這部電影屬于什么類型。根據k-近鄰算法,我們可以這么算。首先計算未知電影與樣本集中其他電影的距離(先不管這個距離如何算,后面會提到)。現在我們得到了樣本集中所有電影與未知電影的距離。按照距離遞增排序,可以找到k個距離最近的電影。

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)_第2張圖片

現在假定 k=3 ,則三個最靠近的電影依次是 He's Not Really into Dudes Beautiful Woman California Man

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)_第3張圖片

k-近鄰算法按照距離最近的三部電影的類型,決定未知電影的類型,而這三部電影全是愛情片,因此我們判定未知電影是愛情片。

python實現

首先編寫一個用于創建數據集和標簽的函數,要注意的是該函數在實際用途上沒有多大意義,僅用于測試代碼。

          
            def createDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group, labels
          
        

然后是函數 classify0() ,該函數的功能是使用k-近鄰算法將每組數據劃分到某個類中,其偽代碼如下:

          
            對未知類別屬性的數據集中的每個點依次執行以下操作:
(1)計算已知類別數據集中的點與當前點之間的距離;
(2)按照距離遞增次序排序;
(3)選取與當前點距離最小的k個點;
(4)確定前k個點所在類別的出現頻率;
(5)返回前k個點出現頻率最高的類別作為當前點的預測分類。
          
        

Python代碼如下:

          
            def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]  # shape[0]表示矩陣有多少行 shape[1]表示矩陣有多少列
    diffMat = tile(inX, (dataSetSize,1)) - dataSet  # 計算Ai-Bi
    sqDiffMat = diffMat**2  #計算(Ai-Bi)^2
    sqDistances = sqDiffMat.sum(axis=1) # 計算(A0-B0)^2+...+(Ai-Bi)^2
    distances = sqDistances**0.5    # 計算((A0-B0)^2+...+(Ai-Bi)^2)^0.5 也就是歐式距離
    sortedDistIndicies = distances.argsort()    # 得到數組的值按遞增排序的索引
    classCount = {}
    for i in range (k): #距離最近的k個點
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0)+1    # 如果voteIlabels的key不存在就返回0
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]
          
        

該函數具有4個輸入參數,分別是 待分類的輸入向量inX 輸入的訓練樣本集dataSet 標簽向量labels 選擇距離最近的k個點 。其中距離使用歐式距離,計算公式如下:

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)_第4張圖片

例如,點(0,0)與(1,2)之間的歐式距離計算為:

如果數據集存在4個特征值,則點(1,0,0,1)與(7,6,9,4)之間的歐式距離計算為:

計算完所有點之間的距離后,可以對數據按照從小到大的次序排序。然后,確定前k個距離最小元素所在的主要分類。輸入k總是正整數;最后,將classCount字典分解為元組列表,然后按照從大到小的次序進行排序,最后返回頻率最高的元素標簽。

運行程序后得到如下結果應該是 B

算法實戰

舉兩個例子,一個是約會對象的好感度預測,一個是手寫識別系統。

約會對象好感度預測

故事背景

海倫小姐是一個大齡單身女青年,她一直通過網絡尋找適合自己的另一半。盡管網上會遇到不一樣的約會對象,但是她并不是喜歡每一個人。經過一番總結,她發現她曾和三種類型的人約會過:

  • [ ] 不喜歡的人
  • [ ] 魅力一般的人
  • [ ] 極具魅力的人

她還發現當她歸類約會對象時主要考慮以下三個特征:

  • [ ] 月收入
  • [ ] 顏值
  • [ ] 每周跑步的公里數

她將這些數據保存在文本文件 datingTestSet2.txt 中。

準備數據:從文本文件中解析數據

首先要將待處理數據的格式改變為分類器可以接受的格式。創建名為 file2matrix() 的函數,以此來處理輸入格式問題。該函數的輸入為文件名字符串,輸出為訓練樣本矩陣和類標簽向量。

          
            def file2matrix(filename):
    fr = open(filename,encoding = 'utf-8')
    arrayOfLines = fr.readlines()   #讀取文件的每一行
    numberOfLines = len(arrayOfLines) #獲得文件行數
    returnMat = zeros((numberOfLines,3))
    classLabelVector = []
    index = 0
    for line in arrayOfLines:
        line = line.strip() #去除首尾空格和回車
        listFromLine = line.split() #按照tab鍵分割數據
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return  returnMat,classLabelVector
          
        

打開文件,得到文件的行數。然后創建以零填充的矩陣。循環處理文件中的每行數據,首先使用函數 line.strip() 截取掉所有的回車字符,然后使用tab字符\t將上一步得到的整行數據分割成一個元素列表。接著,選取前3個元素,將它們存到特征矩陣中。利用負索引將列表的最后一列存儲到向量 classLabelVector 中。

分析數據:使用Matplotlib創建散點圖

這一步不過多解釋,創建可視化數據圖。

          
            def drawFig(datingDataMat,datingLabels):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(datingDataMat[:, 1], datingDataMat[:, 2],15.0*array(datingLabels), 15.0*array(datingLabels))
    plt.show()
          
        

機器學習經典分類算法 —— k-近鄰算法(附python實現代碼及數據集)_第5張圖片

準備數據:歸一化數值

因為月收入的數值和其他兩個特征相比大很多,因此對于計算距離的影響遠大于其他兩個特征。但是在海倫看來這是三個等權重的特征,月收入不應該如此嚴重地影響到計算結果。

因此我們需要進行數值歸一化。采用公式 newValue = (oldValue-min)/(max-min) 可以將任意取值范圍的特征值轉化為0到1的區間。其中min和max分別是數據集中最小特征值和最大特征值。

          
            def autoNorm(dataSet):
    minVals = dataSet.min(0)    #參數0可以從選取每一列的最小值組成向量
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals,(m,1))
    normDataSet = normDataSet/tile(ranges,(m,1))
    return normDataSet, ranges, minVals
          
        

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

在數據集中選取10%的數據作為測試數據。

          
            def datingClassTest():
    hoRatio = 0.10  # 10%的數據作為測試集
    datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")  # load data setfrom file
    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)))
          
        

得到結果如下:

          
            the classifier came back with: 3, the real answer is: 3
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 1, the real answer is: 1
...
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 3, the real answer is: 1
the total error rate is: 0.050000
          
        

錯誤率僅為5%左右,基本上可以正確的分類。

使用算法:構建完整可用的系統

          
            def classifyPerson():
    resultList = ["not at all", "in small doses", "in large doses"]
    percentTats = float(input("monthly income?"))
    ffMiles = float(input("level of appearance?"))
    iceCream = float(input("running miles per month?"))
    datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")  # load data setfrom file
    normMat, ranges, minVals = autoNorm(datingDataMat)
    inArr = array([ffMiles, percentTats, iceCream])
    classifierResult = classify0(inArr, datingDataMat, datingLabels, 3)
    print("You will probably like this person:",resultList[classifierResult-1])
          
        

海倫可以將她要約會的對象信息輸入程序,程序會給出她對對方的喜歡誠度的預測值。例如輸入一個月收入為20000、顏值為5、每周運動量為1公里的數據,得到的結果是:

          
            monthly income?20000
level of appearance?5
running miles per month?1
You will probably like this person: in small doses
          
        

手寫識別系統

為了簡單起見,這里只識別數字0-9。數據集分為訓練集和測試集分別存放在兩個文件夾下。

準備數據:將圖像轉換為測試向量

和之前一個例子不一樣的地方在于數據的處理上。我們必須將圖像格式處理為一個向量。我們將32x32的二進制圖像矩陣轉換為1x1024的向量。
編寫函數 img2vector ,將圖像轉換為向量。

          
            def img2vector(filename):
    returnVector = zeros((1,1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVector[0,32*i+j] = int(lineStr[j])
    return returnVector
          
        

測試算法:使用k-近鄰算法識別手寫數字

          
            def handwritingClassTest():
    hwLabels = []
    trainingFileList = listdir("trainingDigits")
    mTrain = len(trainingFileList)
    trainingMat = zeros((mTrain,1024))
    for i in range(mTrain):
        filenameStr = trainingFileList[i]
        fileStr = filenameStr.split('.')[0]
        classNum = int(fileStr.split('_')[0])
        hwLabels.append(classNum)
        trainingMat[i,:] = img2vector("trainingDigits/%s"%filenameStr)
    testFileList = listdir("testDigits")
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        filenameStr = testFileList[i]
        fileStr = filenameStr.split('.')[0]
        classNum = int(fileStr.split('_')[0])
        testVector = img2vector("testDigits/%s"%filenameStr)
        classifierResult = classify0(testVector, trainingMat, hwLabels, 4)
        print("the classifier came back with: %d, the real answer is: %d" %(classifierResult, classNum))
        if(classifierResult != classNum):
            errorCount += 1.0
    print("\nthe total number of errors is: %d" % errorCount)
    print("\nthe total error rate is: %f" % (errorCount / float(mTest)))
          
        

得到結果如下:

          
            the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
...
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9

the total number of errors is: 11

the total error rate is: 0.011628
          
        

小結

k-近鄰算法是分類數據最簡單最有效的算法。k-近鄰是基于實例的學習,使用算法時必須有大量接近實際數據的訓練樣本數據。k-近鄰算法必須保存全部數據集,如果訓練的數據集很大,必須使用大量的存儲空間。此外,由于必須對數據集中的每個數據計算距離值,實際使用時可能非常耗時。

附錄

文中代碼及數據集:https://github.com/Professorchen/Machine-Learning/tree/master/kNN


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产午夜精品久久久久久久蜜臀 | 久久国产亚洲 | 一级观看免费完整版视频 | 男女午夜性爽快免费视频不卡 | 梦中人在线观看免费完整版 | 国产97色在线 | 日韩 | 国产精品毛片久久久久久 | 日韩在线第一 | 欧美日韩一区二区三区在线观看 | 91视频久久 | 成人毛片视频在线播放 | 九九热观看视频 | 日韩精品一区二区三区第95 | 久久999视频 | 亚洲成色www久久网站 | 天天色综合5 | 色综合久久天天综合网 | 夜夜撸日日操 | 欧美日韩网址 | 色图综合 | 免费观看国产大片资源视频 | 草草线在成年免费视频网站 | 亚洲国产成人在线 | 秋霞av电影| 日韩精品毛片 | 激情插插插 | 天堂亚洲网 | 日韩欧美视频在线 | 91中文字幕 | 比比资源先锋影音网 | 波多野结衣免费视频观看 | 亚洲一区二区色情苍井空 | 国产综合亚洲精品一区二 | 波多久久夜色精品国产 | 天天综合亚洲 | 黄工厂精品视频在线观看 | 国产一区二区小早川怜子 | 天堂久久久久久中文字幕 | 午夜影院普通 | 国产色司机在线视频免费观看 | 日本黄色三级网站 |