iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 26
1

嗨!今天是第26天,之前介紹完了基本的機器學習概念了,這次要說明一個K-近鄰演算法(K Nearest Neighbor)!

主要內容:

  • 什麼是KNN
  • 如何用sklearn完成KNN
    • 資料切分
    • KNN分類
    • KNN預測

什麼是K-近鄰演算法?

k是一個用戶定義的常數。一個沒有類別標籤的向量(查詢或測試點)將被歸類為最接近該點的k個樣本點中最頻繁使用的一類。

簡單來說,我們要找出和新數據附近的K個鄰居(資料),這些鄰居是哪一類(標籤)的它就是哪一類的啦。

sklearn

那我們就直接開始撰寫程式並說明吧!

from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
  • 2019.01.02 更新 :
    由於 sklearn.cross_validation 方法要被棄用了,所以必須改成 sklearn.model_selection

DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)

我們用鳶尾花的資料集做測試,所以import datasets,用sklearn的其中一個優點就是包含了豐富的函數,所以要用knn演算法只要直接引入(import KNeighborsClassifier)就可以了。

load_iris

要匯入鳶尾花的資料只需要使用datasets.load_iris()函數就可以了:

iris = datasets.load_iris()

可以到安德森鳶尾花卉數據集就可以看到裡面有一個表格(如圖):
Imgur
上面包含了特徵資料(花萼長、寬等等)以及最右邊的標籤也就是屬種。

定義特徵資料:

iris_data = iris.data
iris_label = iris.target

可以印出前三筆資料:

iris_data[0:3]

會看到結果:

array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2]])

跟上面鳶尾花資料表格內的資料是一樣的!

train_test_split

一般來說,我們會將資料分成兩個部分:訓練資料測試資料,訓練資料用在訓練模型的時候,測試則用來測試看看這個模型預測的準確度。
使用train_test_split()函數可以簡單的將資料分開成兩部分:

train_data , test_data , train_label , test_label = train_test_split(iris_data,iris_label,test_size=0.2)

上面就是我們將資料分成兩份的程式碼:一部分是用來訓練電腦的(0.8)、一部份用來測試(0.2)。

KNeighborsClassifier

要使用KNeighbors分類法,直接使用sklearn的KNeighborsClassifier()就可以了:

knn = KNeighborsClassifier()

上面程式碼中我們不改變KNeighborsClassifier()中預設的參數,若你想要自行設定內部參數可以參考:sklearn KNeighborsClassifier

將資料做訓練:

knn.fit(train_data,train_label)

predict

預測我們剛剛切分出來的test_data資料

print(knn.predict(test_data))

結果為:
[2 1 1 1 2 2 0 0 0 1 0 2 2 2 0 2 0 0 1 2 0 0 0 0 2 1 1 0 1 0]

看一下正確答案是否跟預測一樣:

print(test_label)

結果為:
[1 1 1 1 2 2 0 0 0 1 0 2 2 2 0 2 0 0 1 2 0 0 0 0 2 1 1 0 1 0]

哦!發現第一個的結果預測錯誤!不過其他都是一樣的!這是正常的,就像人一樣可能會有出錯誤判的時候,電腦也會有。
Imgur

總結

今天說明了knn演算法,是機器學習中較好理解的一個演算法,是透過找出附近鄰居的分類定義來自己的類別,並用sklearn輕易的完成這個機器學習的演算法。

更多參考資料:
[Machine Learning] kNN分類演算法
最近鄰居法 維基百科
sklearn KNeighborsClassifier


上一篇
[Day25]機器學習:特徵與標籤!
下一篇
[Day27]機器學習:建立線性迴歸資料與預測!
系列文
使用Python進行資料分析30

2 則留言

1
hylin
iT邦新手 5 級 ‧ 2019-01-01 23:04:03

1."sklearn.cross_validation"貌似要改為"sklearn.model_selection"?!
2.定義特徵資料:的部分貌似漏了一行:"iris_label = iris.target"!?

plusone iT邦新手 5 級‧ 2019-01-02 17:04:15 檢舉
  1. 哦!剛測試發現sklearn.cross_validation要被棄用了

DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)

之後要改成 model_selection 沒錯,謝謝你。

  1. 不好意思,沒發現自己少寫了一行iris_label = iris.target
iris = datasets.load_iris()
iris_data = iris.data
iris_label = iris.target
train_data , test_data , train_label , test_label = train_test_split(iris_data,iris_label,test_size=0.2)

定義資料的部分是要寫這樣,非常感謝你!

0
elviselle
iT邦新手 5 級 ‧ 2019-01-22 10:35:38

大大好,
小弟初學python,請教大大一個python問題,
程式碼中印前三筆,得知每組 data 是4個feature。
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]]
但我把iris_data.size與iris_label.size print出來看,發現資料筆數分別為 600 與 150。
iris_data是150x4的matrix,但print(iris_data.size) 為什麼不是 150 筆呢?
另外,打印 print(iris_label[0:3]) iris_label前三筆,輸出為 [0 0 0]。
得知 iris_label 是 1x150,而不是 150x1 的 matrix,矩陣放直的跟放橫的有關係嗎?
還請大大協助。
謝謝。

我要留言

立即登入留言