從零開始用Python實現k近鄰算法(附代碼、數據集)

2021-02-19 數據派THU

作者:Tavish Srivastava

翻譯:王雨桐

校對:丁楠雅

本文約2000,建議閱讀8分鐘

本文將帶領讀者理解KNN算法在分類問題中的使用,並結合案例運用Python進行實戰操作。

注意:本文於2014年10月10日首發,並於2018年3月27日更新

引言

進入數據分析領域的四年來,我構建的模型的80%多都是分類模型,而回歸模型僅佔15-20%。這個數字會有浮動,但是整個行業的普遍經驗值。分類模型佔主流的原因是大多數分析問題都涉及到做出決定。例如一個客戶是否會流失,我們是否應該針對一個客戶進行數字營銷,以及客戶是否有很大的潛力等等。這些分析有很強的洞察力,並且直接關係到實現路徑。在本文中,我們將討論另一種被廣泛使用的分類技術,稱為k近鄰(KNN)。本文的重點主要集中在算法的工作原理以及輸入參數如何影響輸出/預測。

目錄

什麼情況下使用KNN算法?

KNN算法如何工作?

如何選擇因子K?

分解--KNN的偽代碼

從零開始的Python實現

和Scikit-learn比較

什麼情況使用KNN算法?


KNN算法既可以用於分類也可以用於回歸預測。然而,業內主要用於分類問題。在評估一個算法時,我們通常從以下三個角度出發:

讓我們通過幾個例子來評估KNN:

KNN算法在這幾項上的表現都比較均衡。由於便於解釋和計算時間較短,這種算法使用很普遍。

KNN算法的原理是什麼?


讓我們通過一個簡單的案例來理解這個算法。下圖是紅圓圈和綠方塊的分布圖:

現在我們要預測藍星星屬於哪個類別。藍星星可能屬於紅圓圈,或屬於綠方塊,也可能不屬於任何類別。KNN中的「K」是我們要找到的最近鄰的數量。假設K= 3。因此,我們現在以藍星星為圓心來作一個圓,使其恰巧只能包含平面內的3個數據點。參閱下圖:

離藍星星最近的三個點都是紅圓圈。因此,我們可以以較高的置信水平判定藍星星應屬於紅圓圈這個類別。在KNN算法中,參數K的選擇是非常關鍵的。接下來,我們將探索哪些因素可以得到K的最佳值。

如何選擇因子K?


首先要了解K在算法中到底有什麼影響。在前文的案例中,假定總共只有6個訓練數據,給定K值,我們可以劃分兩個類的邊界。現在讓我們看看不同K值下兩個類別的邊界的差異。

仔細觀察,我們會發現隨著K值的增加,邊界變得更平滑。當K值趨於無窮大時,分類區域最終會全部變成藍色或紅色,這取決於佔主導地位的是藍點還是紅點。我們需要基於不同K值獲取訓練錯誤率和驗證錯誤率這兩個參數。以下為訓練錯誤率隨K值變化的曲線:

如圖所示,對於訓練樣本而言,K=1時的錯誤率總是為零。這是因為對任何訓練數據點來說,最接近它的點就是其本身。因此,K=1時的預測總是準確的。如果驗證錯誤曲線也是這樣的形狀,我們只要設定K為1就可以了。以下是隨K值變化的驗證錯誤曲線:

顯然,在K=1的時候,我們過度擬合了邊界。因此,錯誤率最初是下降的,達到最小值後又隨著K的增加而增加。為了得到K的最優值,我們將初始數據集分割為訓練集和驗證集,然後通過繪製驗證錯誤曲線得到K的最優值,應用於所有預測。

分解--KNN的偽代碼


我們可以通過以下步驟實現KNN模型:

加載數據。

預設K值。

對訓練集中數據點進行迭代,進行預測。

STEPS:


從零開始的Python實現


我們將使用流行的Iris數據集來構建KNN模型。你可以從這裡下載(數據集連結:https://gist.githubusercontent.com/gurchetan1000/ec90a0a8004927e57c24b20a6f8c8d35/raw/fcd83b35021a4c1d7f1f1d5dc83c07c8ffc0d3e2/iris.csv)

#Importing libraries

importpandas as pd

importnumpy as np

importmath

importoperator

####Start of STEP 1

#Importing data

data= pd.read_csv("iris.csv")

####End of STEP 1

data.head()

#Defining a function which calculates euclidean distance between twodata points

defeuclideanDistance(data1, data2, length):

   distance= 0

   forx in range(length):

       distance+= np.square(data1[x] - data2[x])

   returnnp.sqrt(distance)

#Defining our KNN model

defknn(trainingSet, testInstance, k):

   distances= {}

   sort= {}

    length= testInstance.shape[1]

   

   ####Start of STEP 3

   #Calculating euclidean distance between each row of training data andtest data

   forx in range(len(trainingSet)):

       

       ####Start of STEP 3.1

       dist= euclideanDistance(testInstance, trainingSet.iloc[x], length)

       distances[x]= dist[0]

       ####End of STEP 3.1

   ####Start of STEP 3.2

   #Sorting them on the basis of distance

   sorted_d= sorted(distances.items(), key=operator.itemgetter(1))

   ####End of STEP 3.2

   neighbors= []

   

   ####Start of STEP 3.3

   #Extracting top k neighbors

   forx in range(k):

       neighbors.append(sorted_d[x][0])

   ####End of STEP 3.3

   classVotes= {}

   

   ####Start of STEP 3.4

   #Calculating the most freq class in the neighbors

   forx in range(len(neighbors)):

       response= trainingSet.iloc[neighbors[x]][-1]

       ifresponse in classVotes:

           classVotes[response]+= 1

       else:

           classVotes[response]= 1

   ####End of STEP 3.4

   ####Start of STEP 3.5

   sortedVotes= sorted(classVotes.items(), key=operator.itemgetter(1),reverse=True)

   return(sortedVotes[0][0],neighbors)

   ####End of STEP 3.5

#Creating a dummy testset

testSet= [[7.2, 3.6, 5.1, 2.5]]

test= pd.DataFrame(testSet)

####Start of STEP 2

#Setting number of neighbors = 1

k= 1

####End of STEP 2

#Running KNN model

result,neigh= knn(data, test, k)

#Predicted class

print(result)

->Iris-virginica

#Nearest neighbor

print(neigh)

->[141]

現在我們改變k的值並觀察預測結果的變化:

#Setting number of neighbors = 3

k= 3

#Running KNN model

result,neigh= knn(data, test, k)

#Predicted class

print(result)-> Iris-virginica

#3 nearest neighbors

print(neigh)

->[141, 139, 120]

#Setting number of neighbors = 5

k= 5

#Running KNN model

result,neigh= knn(data, test, k)

#Predicted class

print(result)-> Iris-virginica

#5 nearest neighbors

print(neigh)

->[141, 139, 120, 145, 144]


和scikit-learn比較


fromsklearn.neighbors import KNeighborsClassifier

neigh= KNeighborsClassifier(n_neighbors=3)

neigh.fit(data.iloc[:,0:4],data['Name'])

#Predicted class

print(neigh.predict(test))

->['Iris-virginica']

#3 nearest neighbors

print(neigh.kneighbors(test)[1])

->[[141 139 120]]

可以看到,兩個模型都預測了同樣的類別(「irisi–virginica」)和同樣的最近鄰([141139 120])。因此我們可以得出結論:模型是按照預期運行的。

尾注


KNN算法是最簡單的分類算法之一。即使如此簡單,它也能得到很理想的結果。KNN算法也可用於回歸問題,這時它使用最近點的均值而不是最近鄰的類別。R中KNN可以通過單行代碼實現,但我還沒有探索如何在SAS中使用KNN算法。

您覺得這篇文章有用嗎?您最近使用過其他機器學習工具嗎?您是否打算在一些業務問題中使用KNN?如果是的話,請與我們分享你打算如何去做。

原文標題:Introduction to k-Nearest Neighbors: Simplified (with implementation in Python)

原文連結:https://www.analyticsvidhya.com/blog/2018/03/introduction-k-neighbours-algorithm-clustering/

王雨桐,統計學在讀,數據科學碩士預備,跑步不停,彈琴不止。夢想把數據可視化當作藝術,目前日常是摸著下巴看機器學習。

工作內容:需要一顆細緻的心,將選取好的外文文章翻譯成流暢的中文。如果你是數據科學/統計學/計算機類的留學生,或在海外從事相關工作,或對自己外語水平有信心的朋友歡迎加入翻譯小組。

你能得到:定期的翻譯培訓提高志願者的翻譯水平,提高對於數據科學前沿的認知,海外的朋友可以和國內技術應用發展保持聯繫,THU數據派產學研的背景為志願者帶來好的發展機遇。

其他福利:來自於名企的數據科學工作者,北大清華以及海外等名校學生他們都將成為你在翻譯小組的夥伴。

點擊文末「閱讀原文」加入數據派團隊~

點擊「閱讀原文」擁抱組織

相關焦點

  • 常見面試算法:k-近鄰算法原理與python案例實現
    DT機器學習  公眾號: datayxk-近鄰(kNN, k-NearestNeighbor)算法是一種基本分類與回歸方法,我們這裡只討論分類問題中的 k-近鄰算法。k 近鄰算法的輸入為實例的特徵向量,對應於特徵空間的點;輸出為實例的類別,可以取多類。k 近鄰算法假設給定一個訓練數據集,其中的實例類別已定。分類時,對新的實例,根據其 k 個最近鄰的訓練實例的類別,通過多數表決等方式進行預測。因此,k近鄰算法不具有顯式的學習過程。k 近鄰算法實際上利用訓練數據集對特徵向量空間進行劃分,並作為其分類的「模型」。
  • 從零開始:用Python實現KNN算法
    通過學習這個教程,你將能夠用Python從0開始實現一個KNN算法。這個實現主要用來處理分類問題,我們將使用鳶尾花分類問題來演示這個例子。這個教程的學習要求是你能夠使用Python編碼,並且對實現一個KNN算法感興趣。
  • 《機器學習實戰》學習筆記:K-近鄰算法入門及實戰|萬字長文
    簡單k-近鄰算法本文將從k-鄰近算法的思想開始講起,使用python3一步一步編寫代碼進行實戰訓練。並且,我也提供了相應的數據集,對代碼進行了詳細的注釋。除此之外,本文也對sklearn實現k-鄰近算法的方法進行了講解。實戰實例:電影類別分類、約會網站配對效果判定、手寫數字識別。
  • 機器學習算法推導&實現——k近鄰和kd樹實現
    KNN算法簡單、直觀,是最著名的「惰性學習」算法,不具有顯示的學習過程。K近鄰推導與kd樹過程我們可以用文字簡單描述下KNN算法:給定一個訓練數據集T,對於新的目標實例x,我們在訓練集T中找到與實例x最鄰近的k個實例,這k個實例大多屬於哪一類,目標實例x就被分為這個類。
  • 【機器學習基礎】數學推導+純Python實現機器學習算法3:k近鄰
    說它獨特,是因為 k 近鄰不像其他模型有損失函數、有優化算法、有訓練過程。對於給定的實例數據和實例數據對應所屬類別,當要對新的實例進行分類時,根據這個實例最近的 k 個實例所屬的類別來決定其屬於哪一類。所以相對於其它機器學習模型和算法,k 近鄰總體上而言是一種非常簡單的方法。
  • 小白學數據:教你用Python實現簡單監督學習算法
    在分類步驟中,分類器對給定的數據進行分類。用於分析的數據集(包含數據和其對應的標籤)被劃分為訓練集和測試集。訓練集從分析用的數據集中隨機抽取。剩下的數據集構成測試集。測試集和訓練集相互獨立,即測試集中的數據不會被構建於分類器。測試集用於評價分類器的預測精度。
  • 從零開始實現穿衣圖像分割完整教程(附python代碼演練)
    AI項目體驗地址 https://loveai.tech數據集最近有一項關於服裝視覺分析和分割的Kaggle比賽。 這是一個非常有趣的比賽,但它並不適合我們。 我們的目標是從圖像中提取連衣裙,因此這個數據集不太適合我們,因為它包含了比較多的冗餘。 我們需要的是包含連衣裙的圖像,因此最好自己來構建數據集。
  • Python:機器學習-k-近鄰算法之影片分類器
    本次將介紹一個機器學習算法:k-近鄰算法,它非常有效而易於握。我們將探討如使用距離測量的方法分類。k-近鄰算法優點:精度高、對異常值不敏感、無數據輸入假定。適用數據範圍:數值型和標稱型。前言:我們大多數人都看過電影是吧,有的人喜歡看愛情片,有的人喜歡看動作片。那麼由誰來定義這些影片的類型呢?
  • 機器學習之KNN分類算法介紹: Stata和R同步實現(附數據和代碼)
    作為機器學習一種入門級算法,KNN的NN雖然和計量經濟學中PSM模型中的NN近鄰匹配字面意思一樣,但兩者的算法原理卻有著本質區別。PSM:NN近鄰匹配的依據是樣本進入「幹預組」的概率或得分(propensity score),通常用logit/Probit函數求出。兩個觀測值相近指的是兩者的概率或得分相近。KNN:近鄰的遠近是通過距離來衡量。
  • K近鄰算法哪家強?KDTree、Annoy、HNSW原理和使用方法介紹
    K近鄰算法(KNN)是一種常用的分類和回歸方法,它的基本思想是從訓練集中尋找和輸入樣本最相似的k個樣本,如果這k個樣本中的大多數屬於某一個類別,則輸入的樣本也屬於這個類別。關於KNN算法,一個核心問題是:如何快速從數據集中找到和目標樣本最接近的K個樣本?本文將從這個角度切入,介紹常用的K近鄰算法的實現方法。具體將從原理、使用方法、時間開銷和準確率對比等方面進行分析和實驗。2、距離度量在介紹具體算法之前,我們先簡單回顧一下KNN算法的三要素:距離度量、k值的選擇和分類決策規則。
  • 哈工大碩士生用 Python 實現了 11 種經典數據降維算法,原始碼庫已...
    所謂降維,即用一組個數為 d 的向量 Zi 來代表個數為 D 的向量 Xi 所包含的有用信息,其中 d<D;通俗來講,即將高維度下降至低維度;將高維數據下降為低維數據。通常,我們會發現大部分數據集的維度都會高達成百乃至上千,而經典的 MNIST,其維度都是 64。
  • 分類算法之K近鄰算法(KNN)
    算法思路K最近鄰(k-Nearest Neighbor)算法是比較簡單的機器學習算法。它採用測量不同特徵值之間的距離方法進行分類。思路: 如果一個樣本在特徵空間中的k個最近鄰(最相似)的樣本中的大多數都屬於某一個類別,則該樣本也屬於這個類別。算法分析這裡我以javaml庫為例分析算法實現步驟。
  • 人工智慧之K近鄰算法(KNN)
    ^_^本文引用地址:http://www.eepw.com.cn/article/201806/381808.htm  K近鄰KNN(k-Nearest Neighbor)算法,也叫K最近鄰算法,1968年由 Cover 和 Hart 提出,是機器學習算法中比較成熟的算法之一。K近鄰算法使用的模型實際上對應於對特徵空間的劃分。
  • 使用K-近鄰算法構建鳶尾屬分類器
    這是因為分類算法受到了離群數據的影響,與黑色數據點近鄰的橙色數據點就是離群數據。可以考慮取黑色數據點近鄰(距離黑色數據點最近)的K(1≤K≤N,N為訓練數據集的長度)個數據點,確定K個數據點中同一類別出現的頻率,把頻率最高的類別作為黑色數據點的類別。
  • Stacking 模型融合詳解(附python代碼)
    訪問AI圖譜 技術分享社區  https://loveai.techStacking的實現  最先想到的方法是這樣的,  1:用數據集D來訓練h1,h2,h3...,  2:用這些訓練出來的初級學習器在數據集D上面進行預測得到次級訓練集。
  • python機器學習之k-means聚類算法(1)
    k-means算法是一種無監督的機器學習算法,雖然是機器學習,但它簡單易於實現。本篇採用python語言,自主編程實現k-menas算法,當然python用專門的庫函數來實現該算法,但本次主要使用該算法闡述編程思想,所以不採用內置函數。採用自主編寫的程序的方式。
  • 實例最簡,帶你輕鬆進階機器學習K最近鄰算法
    不過網上關於K近鄰算法的大多數介紹都非常繁雜且缺乏簡單實用的代碼示例。這樣不免會增加學習負擔,在這篇文章中我們將針對這個問題以最簡單的實例,帶大家來輕鬆地進階掌握K近鄰算法。K近鄰的第一步,是找到x的最近鄰。那麼這個近鄰怎麼衡量呢?一般我們用距離來衡量,常見的有歐氏距離和曼哈頓距離。
  • 教你用Python解決非平衡數據問題(附代碼)
    該算法的模擬過程採用了KNN技術,模擬生成新樣本的步驟如下:採樣最鄰近算法,計算出每個少數類樣本的K個近鄰;從K個近鄰中隨機挑選N個樣本進行隨機線性插值;構造新的少數類樣本;將新樣本與原數據合成,產生新的訓練集;為了使讀者理解SMOTE算法實現新樣本的模擬過程,可以參考下圖和人工新樣本的生成過程:
  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    6-22本章小結 7-1分類評估 混淆矩陣 7-2分類評估 7-3回歸評估 7-4非監督評估 8-1課程回顧與多角度看數據分析 8-2大數據與學習這門課後還能幹什麼 4辦公自動化 1購後必讀 ,學員福利 2python基礎,從零到1 3s1 excel
  • AI產品經理必懂算法:k-近鄰(KNN)算法
    作為想在AI領域長期發展的PM同學來說,對算法有一個初步、通識的了解是非常有必要的。今天我們就從一個最為簡單、易懂的「k-近鄰(KNN)算法」聊起,KNN屬於監督學習算法,即可以用於分類,也可以用於回歸,後續還會逐步為大家介紹一些常用的其他算法。