從零開始 用Python實現KNN演算法

2021-07-13 13:28:09 字數 3576 閱讀 5145

目錄

python

2023年6月15日

k-nearest neighbors演算法(簡稱knn演算法)的邏輯很簡單,它易於理解和實現,是你可以使用的有力工具。

通過學習這個教程,你將能夠用python從0開始實現乙個knn演算法。這個實現主要用來處理分類問題,我們將使用鳶尾花分類問題來演示這個例子。

這個教程的學習要求是你能夠使用python編碼,並且對實現乙個knn演算法感興趣。

什麼是k-nearest neighbors?

knn的模型是整個訓練資料集。當我們需要**乙個新例項的某個屬性a時,knn演算法會搜尋訓練資料集找到k個最相似的例項。這些相似例項的a屬性會被總結歸納,作為新例項a屬性的**。

如何判斷例項之間的相似程度,這需要具體看資料的型別。對於實數資料,我們可以使用歐式距離。對於分類或者二進位制資料,我們可以使用漢明距離。

對於回歸問題,可以使用**值的平均值。對於分類問題,可以返回最普遍的一類。

knn演算法是如何工作的?

knn演算法屬於基於例項的、競爭學習與懶惰學習演算法。

基於例項的演算法是演算法模型使用資料例項(或者說資料行),並依據這些例項做出**的演算法。knn演算法是基於例項演算法中的乙個極端例子,因為所有的訓練資料都成了演算法模型的一部分。

它是乙個競爭學習邏輯,因為它內部使用模型元素(資料例項)之間的競爭來作出**。資料例項之間的相似性計算導致每乙個資料例項都競爭去「贏」,或者說競爭去和需要**的元素相似,再或者說競爭為**結果做貢獻。

說它是懶惰學習演算法是因為一直到需要進行**操作了,它才會建立乙個**模型,它總是最後需要出結果的時候才開始幹活。

它的優勢是只有跟需要**元素相似的資料例項才會其作用,可以稱之為乙個區域性模型。劣勢是計算成本很高,因為它在乙個很大的訓練集上重複做著相似的搜尋。

最後,knn很有用,因為它不對資料做任何的假設,同時使用一致的規則在任意兩個資料例項之間計算距離。也因為如此,它被稱作非引數,或者非線性演算法,因為它沒有假設乙個模型函式。

使用測量來分類花朵

本教程使用的練習問題是分類鳶尾花。

已有的資料集由對3個不同品種的鳶尾花的150組觀察資料組成。對於這些花有4個測量維度:萼片長度、萼片寬度、花瓣長度、花瓣寬度,所有的數值都以厘公尺為單位。需要**的屬性是品種,品種的可能值有:清風藤、雲芝、錦葵。

我們有乙個標準資料集,在這個資料集中品種是已知的。我們可以把這個資料集切分成訓練資料集和測試資料集,然後用測試結果來評估演算法的準確程度。在這個問題上,好的分類演算法應該有大於90%的正確率,通常都會達到96%甚至更高。

如何用python實現knn

這個教程把實現步驟分為如下6布。

處理資料:從csv中讀取資料,並把它們分割成訓練資料集和測試資料集。

相似度:計算兩個資料例項之間的距離。

臨近:確定最相近的n個例項。

結果:從這些實力中生成**結果。

準確度:總結**的準確度。

主程式:把這些串起來

1、處理資料

我們要做的第一件事是載入我們的資料檔案。資料檔案是csv格式的,並且沒有標題行和備註。我們可以使用open方法開啟檔案,並用csv模組讀取資料:

接下來我們要把資料集切分成用來做**的訓練資料集和用來評估準確度的測試資料集。

首先,我們要把載入進來的特徵資料從字串轉換成整數。然後我們隨機地切分訓練資料集和測試資料集。訓練資料集資料量/測試資料集資料量的比值取67/33是乙個常用的慣例。

把這些邏輯放在一起,我們得到下面這個函式loaddataset:

2、相似度

為了作出**,我們需要計算兩個資料例項之間的相似度。有了計算相似度的函式,我們後面才能獲取最相似的n個例項來做出**。

因為有關花的四個測量維度的資料都是數字形式的,並且具有相同的單位。我們可以直接使用歐式距離來測量。歐式距離就是兩列數中對應數做差的平方和,之後再開方。(類似於二維平面的距離公式,擴充套件到多維)。

另外,我們要確定哪些維度參與計算。在這個問題裡,我們只需要包含測量好的4個維度,這4個維度放在陣列的前幾個位置。限制維度的乙個辦法就是增加乙個引數,告訴函式前幾個維度需要處理,忽略後面的維度。

把這些邏輯放在一起,得到計算歐式距離的函式:

我們可以用一些假資料來測試這個函式,像這樣:

3、鄰近元素

現在我們有了相似度計算的方法,我們可以獲取跟需要**資料最接近的n個資料例項了。

最直接的方法就是計算待**資料到所有資料例項的距離,取其中距離最小的n個。

這個邏輯可以由下面函式表示:

我們可以像下面這樣測試這個函式

4、結果

接下來的任務就是基於最近的幾個例項來得到**結果了。

我們可以讓這些近鄰元素來對**屬性投票,得票最多的選項作為**結果。

下面這個函式實現了投票的邏輯,它假設需**的屬性放在資料例項(陣列)的最後。

我們可以用一些測試資料測試一下:

如果投票結果是平局,這個函式還是返回了乙個**結果。不過你可以有你自己的處理方式,比如平局時返回none,或者平局時隨機選擇乙個結果。

5、準確度

做**的部分已經都寫完了,接下來是評估這個演算法的準確度。

乙個簡單的評估方法是,計算在測試資料集中演算法正確**的比例,這個比例叫分類準確度。

下面這個函式可以計算分類準確度。

我們可以用下面這個例子來測試它:

6、主程式

好了,我們已經有了這個演算法需要的所有函式,剩的就是把它們串起來了。

下面是完整的**:

執行這個程式,你就會看到每個**資料和實際資料的對比。在程式的最後,你能看到這個**模型的準確度。在這個例子中,準確度略高於98%。

有關擴充套件的想法

這一部分我們講講一些對本教程給出的python**的做擴充套件的想法。

你可以發掘更多擴充套件的邏輯。比如投票的時候不同距離的例項有不同的權重,或者你可以用乙個樹形結構來進行最近例項的搜尋。

從零開始學Python

第三章 字典 1.建立字典 book 其中值可以是任意型別,可以是元組或者字典.2.dict函式建立字典 通過對映建立 book d book.dict 輸出d book 通過關鍵字建立 d dict name zq age 1 輸出d 3.字典的格式化字串 鍵 s 字典名 book name is...

從零開始學Python

第十一章 檔案操作 1.開啟檔案 用open 函式,直接用就可以。open name mode buffering 呼叫open 之後會返回乙個檔案物件,mode 模式,buffering 緩衝都是可以選擇的。f open r 檔案路徑 2.檔案模式 r 讀模式 w 寫模式 a 追加模式 b 二進位...

Python從零開始(1)

學習一門程式語言首先要從計算機基礎常識開始,畢竟程式語言是跟計算機交流的語言。計算機分為硬體系統和軟體系統,從硬體系統說起,硬體系統就是大家可以看得到摸得著的計算機系統,大部分都藏在主機箱中,硬體系統有很多,這裡就說一些主要的 1.cpu,這個就是 處理器,計算機的運算核心,控制核心,是計算機最重要...