1. 程式人生 > >機器學習經典演算法詳解及Python實現--K近鄰(KNN)演算法

機器學習經典演算法詳解及Python實現--K近鄰(KNN)演算法

轉載http://blog.csdn.net/suipingsp/article/details/41964713

(一)KNN依然是一種監督學習演算法

KNN(K Nearest Neighbors,K近鄰 )演算法是機器學習所有演算法中理論最簡單,最好理解的。KNN是一種基於例項的學習,通過計算新資料與訓練資料特徵值之間的距離,然後選取K(K>=1)個距離最近的鄰居進行分類判斷(投票法)或者回歸。如果K=1,那麼新資料被簡單分配給其近鄰的類。KNN演算法算是監督學習還是無監督學習呢?首先來看一下監督學習和無監督學習的定義。對於監督學習,資料都有明確的label(分類針對離散分佈,迴歸針對連續分佈),根據機器學習產生的模型可以將新資料分到一個明確的類或得到一個預測值。對於非監督學習,資料沒有label,機器學習出的模型是從資料中提取出來的pattern(提取決定性特徵或者聚類等)。例如聚類是機器根據學習得到的模型來判斷新資料“更像”哪些原資料集合。KNN演算法用於分類時,每個訓練資料都有明確的label,也可以明確的判斷出新資料的label,KNN用於迴歸時也會根據鄰居的值預測出一個明確的值,因此KNN屬於監督學習。
KNN演算法的過程為:
  1. 選擇一種距離計算方式, 通過資料所有的特徵計算新資料與已知類別資料集中的資料點的距離
  1. 按照距離遞增次序進行排序,選取與當前距離最小的k個點
  1. 對於離散分類,返回k個點出現頻率最多的類別作預測分類;對於迴歸則返回k個點的加權值作為預測值

(二)KNN演算法關鍵

KNN演算法的理論和過程就是那麼簡單,為了使其獲得更好的學習效果,有下面幾個需要注意的地方。
1、資料的所有特徵都要做可比較的量化。
若是資料特徵中存在非數值的型別,必須採取手段將其量化為數值。舉個例子,若樣本特徵中包含顏色(紅黑藍)一項,顏色之間是沒有距離可言的,可通過將顏色轉換為灰度值來實現距離計算。另外,樣本有多個引數,每一個引數都有自己的定義域和取值範圍,他們對distance計算的影響也就不一樣,如取值較大的影響力會蓋過取值較小的引數。為了公平,樣本引數必須做一些scale處理,最簡單的方式就是所有特徵的數值都採取歸一化處置。
2、需要一個distance函式以計算兩個樣本之間的距離。
距離的定義有很多,如歐氏距離、餘弦距離、漢明距離、曼哈頓距離等等,關於相似性度量的方法可參考‘漫談:機器學習中距離和相似性度量方法’。一般情況下,選歐氏距離作為距離度量,但是這是隻適用於連續變數。在文字分類這種非連續變數情況下,漢明距離可以用來作為度量。通常情況下,如果運用一些特殊的演算法來計算度量的話,K近鄰分類精度可顯著提高,如運用大邊緣最近鄰法或者近鄰成分分析法。
3,確定K的值
K是一個自定義的常數,K的值也直接影響最後的估計,一種選擇K值得方法是使用 cross-validate(交叉驗證)誤差統計選擇法交叉驗證的概念之前提過,就是資料樣本的一部分作為訓練樣本,一部分作為測試樣本,比如選擇95%作為訓練樣本,剩下的用作測試樣本。通過訓練資料訓練一個機器學習模型,然後利用測試資料測試其誤差率。 cross-validate(交叉驗證)誤差統計選擇法就是比較不同K值時的交叉驗證平均誤差率,選擇誤差率最小的那個K值。例如選擇K=1,2,3,... ,   對每個K=i做100次交叉驗證,計算出平均誤差,然後比較、選出最小的那個

(三)KNN分類

訓練樣本是多維特徵空間向量,其中每個訓練樣本帶有一個類別標籤(喜歡或者不喜歡、保留或者刪除)。分類演算法常採用“多數表決”決定,即k個鄰居中出現次數最多的那個類作為預測類。“多數表決”分類的一個缺點是出現頻率較多的樣本將會主導測試點的預測結果,那是因為他們比較大可能出現在測試點的K鄰域而測試點的屬性又是通過K領域內的樣本計算出來的。解決這個缺點的方法之一是在進行分類時將K個鄰居到測試點的距離考慮進去。例如,若樣本到測試點距離為d,則選1/d為該鄰居的權重(也就是得到了該鄰居所屬類的權重),接下來統計統計k個鄰居所有類標籤的權重和,值最大的那個就是新資料點的預測類標籤。
舉例,K=5,計算出新資料點到最近的五個鄰居的舉例是(1,3,3,4,5),五個鄰居的類標籤是(yes,no,no,yes,no)
若是按照多數表決法,則新資料點類別為no(3個no,2個yes);若考慮距離權重類別則為yes(no:2/3+1/5,yes:1+1/4)。
下面的Python程式是採用KNN演算法的例項(計算歐氏距離,多數表決法決斷):一個是採用KNN演算法改進約會網站配對效果,另一個是採用KNN演算法進行手寫識別。
約會網站配對效果改進的例子是根據男子的每年的飛行里程、視訊遊戲時間比和每週冰激凌耗量三個特徵來判斷其是否是海倫姑娘喜歡的型別(類別為很喜歡、一般和討厭),決策採用多數表決法。由於三個特徵的取值範圍不同,這裡採用的scale策略為歸一化。
使用KNN分類器的手寫識別系統 只能識別數字0到9。需要識別的數字使用圖形處理軟體,處理成具有相同的色 彩和大小 :寬髙是32畫素X32畫素的黑白影象。儘管採用文字格式儲存影象不能有效地利用記憶體空間,為了方便理解,這裡已經將將影象轉換為文字格式。訓練資料中每個數字大概有200個樣本,程式中將影象樣本格式化處理為向量,即一個把一個32x32的二進位制影象矩陣轉換為一個1x1024的向量。
[python] view plain copy  print?
  1. from numpy import *  
  2. import operator  
  3. from os import listdir  
  4. import matplotlib  
  5. import matplotlib.pyplot as plt  
  6. import pdb  
  7. def classify0(inX, dataSet, labels, k=3):  
  8.     #pdb.set_trace()
  9.     dataSetSize = dataSet.shape[0]  
  10.     diffMat = tile(inX, (dataSetSize,1)) - dataSet  
  11.     sqDiffMat = diffMat**2
  12.     sqDistances = sqDiffMat.sum(axis=1)  
  13.     distances = sqDistances**0.5
  14.     sortedDistIndicies = distances.argsort() #ascend sorted,
  15.     #return the index of unsorted, that is to choose the least 3 item    
  16.     classCount={}            
  17.     for i in range(k):  
  18.         voteIlabel = labels[sortedDistIndicies[i]]  
  19.         classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1# a dict with label as key and occurrence number as value
  20.     sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)  
  21.     '''''descend sorted according to value, '''
  22.     return sortedClassCount[0][0]  
  23. def file2matrix(filename):  
  24.     fr = open(filename)  
  25.     #pdb.set_trace()
  26.     L = fr.readlines()  
  27.     numberOfLines = len(L)         #get the number of lines in the file
  28.     returnMat = zeros((numberOfLines,3))        #prepare matrix to return
  29.     classLabelVector = []                       #prepare labels return       
  30.     index = 0
  31.     for line in L:  
  32.         line = line.strip()  
  33.         listFromLine = line.split('\t')  
  34.         returnMat[index,:] = listFromLine[0:3]  
  35.         classLabelVector.append(int(listFromLine[-1]))  
  36.         #classLabelVector.append((listFromLine[-1]))
  37.         index += 1
  38.     fr.close()  
  39.     return returnMat,classLabelVector  
  40. def plotscattter():  
  41.     datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #load data setfrom file
  42.     fig = plt.figure()  
  43.     ax1 = fig.add_subplot(111)  
  44.     ax2 = fig.add_subplot(111)  
  45.     ax3 = fig.add_subplot(111)  
  46.     ax1.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels))  
  47.     #ax2.scatter(datingDataMat[:,0],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
  48.     #ax2.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
  49.     plt.show()  
  50. def autoNorm(dataSet):  
  51.     minVals = dataSet.min(0)  
  52.     maxVals = dataSet.max(0)  
  53.     ranges = maxVals - minVals  
  54.     normDataSet = zeros(shape(dataSet))  
  55.     m = dataSet.shape[0]  
  56.     normDataSet = dataSet - tile(minVals, (m,1))  
  57.     normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide
  58.     return normDataSet, ranges, minVals  
  59. def datingClassTest(hoRatio = 0.20):  
  60.     #hold out 10%
  61.     datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #load data setfrom file
  62.     normMat, ranges, minVals = autoNorm(datingDataMat)  
  63.     m = normMat.shape[0]  
  64.     numTestVecs = int(m*hoRatio)  
  65.     errorCount = 0.0
  66.     for i in range(numTestVecs):  
  67.         classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)  
  68.         print"the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])  
  69.         if (classifierResult != datingLabels[i]): errorCount += 1.0
  70.     print"the total error rate is: %.2f%%" % (100*errorCount/float(numTestVecs))  
  71.     print'testcount is %s, errorCount is %s' %(numTestVecs,errorCount)  
  72. def classifyPerson():  
  73.     ''''' 
  74.     input a person , decide like or not, then update the DB 
  75.     '''
  76.     resultlist = ['not at all','little doses','large doses']  
  77.     percentTats = float(raw_input('input the person\' percentage of time playing video games:'))  
  78.     ffMiles = float(raw_input('flier miles in a year:'))  
  79.     iceCream = float(raw_input('amount of iceCream consumed per year:'))  
  80.     datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')  
  81.     normMat, ranges, minVals = autoNorm(datingDataMat)  
  82.     normPerson = (array([ffMiles,percentTats,iceCream])-minVals)/ranges  
  83.     result = classify0(normPerson, normMat, datingLabels, 3)  
  84.     print'you will probably like this guy in:', resultlist[result -1]  
  85.     #update the datingTestSet
  86.     print'update dating DB'
  87.     tmp = '\t'.join([repr(ffMiles),repr(percentTats),repr(iceCream),repr(result)])+'\n'
  88.     with open('datingTestSet2.txt','a') as fr:  
  89.         fr.write(tmp)  
  90. def img2file(filename):  
  91.     #vector = zeros(1,1024)
  92.     with open(filename) as fr:  
  93.         L=fr.readlines()  
  94.     vector =[int(L[i][j]) for i in range(32for j in range(32)]  
  95.     return array(vector,dtype = float)  
  96. def handwritingClassTest():  
  97.     hwLabels = []  
  98.     trainingFileList = listdir('trainingDigits')           #load the training set
  99.     m = len(trainingFileList)  
  100.     trainingMat = zeros((m,1024))  
  101.     for i in range(m):  
  102.         fileNameStr = trainingFileList[i]  
  103.         fileStr = fileNameStr.split('.')[0]     #take off .txt
  104.         classNumStr = int(fileStr.split('_')[0])  
  105.         hwLabels.append(classNumStr)  
  106.         trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)  
  107.     testFileList = listdir('testDigits')        #iterate through the test set
  108.     errorCount = 0.0
  109.     mTest = len(testFileList)  
  110.     for i in range(mTest):  
  111.         fileNameStr = testFileList[i]  
  112.         fileStr = fileNameStr.split('.')[0]     #take off .txt
  113.         classNumStr = int(fileStr.split('_')[0])  
  114.         vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)  
  115. 相關推薦

    機器學習經典演算法Python實現--K近鄰(KNN)演算法

    轉載http://blog.csdn.net/suipingsp/article/details/41964713 (一)KNN依然是一種監督學習演算法 KNN(K Nearest Neighbors,K近鄰 )演算法是機器學習所有演算法中理論最簡單,最好理解的。KNN

    機器學習經典演算法Python實現--線性迴歸(Linear Regression)演算法

    (一)認識迴歸 迴歸是統計學中最有力的工具之一。機器學習監督學習演算法分為分類演算法和迴歸演算法兩種,其實就是根據類別標籤分佈型別為離散型、連續性而定義的。顧名思義,分類演算法用於離散型分佈預測,如前

    機器學習經典演算法Python實現--決策樹(Decision Tree)

    (一)認識決策樹 1,決策樹分類原理 決策樹是通過一系列規則對資料進行分類的過程。它提供一種在什麼條件下會得到什麼值的類似規則的方法。決策樹分為分類樹和迴歸樹兩種,分類樹對離散變數做決策樹,迴歸樹對連續變數做決策樹。 近來的調查表明決策樹也是最經常使用的資料探勘演算法,它

    小白之KMP演算法python實現

    在看子串匹配問題的時候,書上的關於KMP的演算法的介紹總是理解不了。看了一遍程式碼總是很快的忘掉,後來決定好好分解一下KMP演算法,算是給自己加深印象。 ------------------------- 分割線-------------------------------

    k-means演算法python程式碼

    K-means演算法原理     K-means聚類屬於原型聚類(基於原型的聚類,prototype-based clustering)。原型聚類演算法假設聚類結構能夠通過一組原型進行刻畫,在現實聚類任務中極為常用。通常情況下,原型聚類演算法對原型進行初始化,然後對原型進行

    迪克斯特拉演算法C++實現

    演算法步驟如下: G={V,E} 1. 初始時令 S={V0},T=V-S={其餘頂點},T中頂點對應的距離值 若存在<V0,Vi>,d(V0,Vi)為<V0,Vi>弧上的權值

    遺傳演算法Java實現

    遺傳演算法的起源 ========== 20世紀60年代中期,美國密西根大學的John Holland提出了位串編碼技術,這種編碼既適合於變異又適合雜交操作,並且他強調將雜交作為主要的遺傳操作。遺傳演算法的通用編碼技術及簡單有效的遺傳操作為其廣泛的應用和成功

    常見9大排序演算法python3實現

    穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面; 不穩定:如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面; 內排序:所有排序操作都在記憶體中完成; 外排序:由於資料太大,因此把資料放在磁碟中,而排序通過磁碟和記憶體的資料傳輸才能進行;

    最小生成樹-MST演算法程式碼實現

    師兄發了一篇CCF-C類的文章,但是那個會議在澳洲排名屬於B類,他說他在CVPR的某一篇文章的基礎之上用了MST演算法,避免了局部最優解,找到了全域性最優解,實驗結果比原文好很多,整個文章加實驗前後僅僅做了2周。真是羨煞旁人也。。其實在機器學習當中,經常會遇到區域性最優解的

    100天搞定機器學習|Day23-25 決策樹Python實現

    演算法部分不再細講,之前發過很多: 【算法系列】決策樹 決策樹(Decision Tree)ID3演算法 決策樹(Decision Tree)C4.5演算法 決策樹(Decision Tree)CART演算法 ID3、C4.5、CART三種決策樹的區別 實驗: 匯入需要用到的python庫 import

    AdaBoost演算法python實現

    1. 概述 1.1 整合學習 目前存在各種各樣的機器學習演算法,例如SVM、決策樹、感知機等等。但是實際應用中,或者說在打比賽時,成績較好的隊伍幾乎都用了整合學習(ensemble learning)的方法。整合學習的思想,簡單來講,就是“三個臭皮匠頂個諸葛亮”。整合學習通過結合多個學習器(例如同種演算法但是

    Q-Q圖原理Python實現

    【導讀】在之前的《資料探勘概念與技術 第2章》的文章中我們介紹了Q-Q圖的概念,並且通過呼叫現成的python函式, 畫出了Q-Q圖, 驗證了Q-Q圖的兩個主要作用,1. 檢驗一列資料是否符合正態分佈 2. 檢驗兩列資料是否符合同一分佈。本篇文章將更加全面的為大家介紹QQ圖的原理以及自己手寫函式實現畫圖過程

    C#實現K-近鄰(KNN)演算法

    KNN(k-nearest-neighbor)演算法的思想是找到在輸入新資料時,找到與該資料最接近的k個鄰居,在這k個鄰居中,找到出現次數最多的類別,對其進行歸類。 Iris資料集是常用的分類實驗資料集,由Fisher, 1936收集整理。Iris也稱鳶尾花卉資料集,是一類多重變數分析的資料

    五大常用演算法——貪心演算法經典例子

    貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,但對範圍相當廣泛的許多問題他能產生整體最優解或者是整體最優解的近似解。基本

    機器學習筆記----Fuzzy c-means(FCM)模糊聚類matlab實現

    前言:這幾天一直都在研究模糊聚類。感覺網上的文件都沒有一個詳細而具體的講解,正好今天有時間,就來聊一聊模糊聚類。 一:模糊數學 我們大家都知道計算機其實只認識兩個數字0,1。我們平時寫程式其實也是這樣if 1 then do.永遠這種模式,在這種模式中,一個元素要麼屬

    機器學習——隨機森林演算法randomForest——原理python實現

    參考: http://blog.csdn.net/nieson2012/article/details/51279332 http://www.cnblogs.com/wentingtu/archive/2011/12/22/2297405.html http://www.

    五大常用演算法——分支限界演算法經典例題

    import static org.junit.Assert.*; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; import javax.management.Query; import o

    Liblinear機器學習庫教程(基於Python API)

    前言 Liblinear機器學習庫主要實現SVM演算法,在處理大規模資料時速度快,但也有缺點,就是太吃記憶體,部落格 https://blog.csdn.net/roguesir/article/details/79793569 中介紹了在Mac Python

    五大常用演算法——分治演算法經典例題

    一、基本概念    在電腦科學中,分治法是一種很重要的演算法。字面上的解釋是“分而治之”,就是把一個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。這個技巧是很多高效演算法的基礎,如排

    動態規劃演算法經典例題

    動態規劃 什麼是動態規劃? 動態規劃的大致思路是把一個複雜的問題轉化成一個分階段逐步遞推的過程,從簡單的初始狀態一步一步遞推,最終得到複雜問題的最優解。 基本思想與策略編輯: 由於動態規劃解決的問題多數有重疊子問題這個特點,為減少重複計算,對每一個子問題只解一次,將其不同階段的不同狀態儲存在一個二維陣列中。