十三 機器學習之路 k 近鄰演算法(KNN)

2021-08-10 20:33:27 字數 4088 閱讀 7750

有幾天沒寫部落格了,最近工作上的事情比較多,沒抽出時間來看書學習。趁今天有點空,一起學習一下k-近鄰演算法(knn),這個演算法是監督學習裡的分類問題,主要是用來根據資料的特徵,將樣本分為不同類別的演算法,咱們下面慢慢來學習。

knn演算法定義:

knn演算法是比較容易理解的分類演算法,knn是通過測量不同特徵值之間的距離進行分類。它的的思路是:如果乙個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別。k通常是不大於20的整數。knn演算法中,所選擇的鄰居都是已經正確分類的物件。該方法在定類決策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。

knn演算法例子說明:

看了上面的定義是不是有點懵懵的,沒關係我舉乙個簡單的例子來說明如何利用knn演算法來對新的樣本進行分類,讓大家更容易理解,舉的例子有略微不嚴謹之處,不要在意細節。

由於人類dna的延續,我們都長得像自己的爸爸媽媽,甚至爺爺奶奶,所以每乙個大家族的人長得還是都比較相似的。假設我們現在有兩個大家族,王家和李家(樣本的兩大類別,樣本就是每個人的長相),我們外人看到這兩大家族裡的這麼多人,只能通過簡單的長相來分辨哪些人是王大家族的,哪些人是李大家族的,因為我們知道一家人長得都比較相似。假設現在我們已經有了一組訓練集,我們知道10個王大家族的人的長相和10個李大家族人的長相,相當於我們有20個人的長相資料以及他們對應的家族分類。好了,現在打東邊來了乙個喇叭,問,這個喇叭更有可能是哪個家族的人?

在這個例子中,knn演算法的判斷方式就是,將這個喇叭的長相分別和王家、李家10個人的長相作對比,然後計算出喇叭的長相和這20個人長相的差別有多大(這裡為了方便理解,假設我們分不同等級來表示差別:1,2,3,4,5等,最終輸出的差別為乙個數字,即knn裡的「距離」),最後將這些差別值從小到大排列,假設我們認為差別最小的5個人(這裡的5就是knn裡的k值)裡,王家人占多數,那我們認為這個喇叭就是王家人;如果差別最小的5個人裡,李家人占多數,那我們就認為這個喇叭是李家人。這樣就通過knn演算法將**的資料進行了分類,達到了我們的目的。

knn演算法實現:

在《機器學習實戰》這本書裡講到乙個利用knn實現的問題,也是乙個很簡單的例子。我們在網上搜電影的時候,都會分類的搜尋,比如說你喜歡看戰爭片,或者愛情片,或者動作片。可是我們怎麼將這些電影分類呢,什麼樣的電影算是愛情片,什麼樣的電影算是動作片?

假設我們用電影裡出現接吻的次數和打鬥的次數來分類愛情片和動作片,當然愛情片裡可能打鬥和接吻場面都會有,動作片裡打鬥和接吻場面也都會有,那麼我們就用出現的次數來判別電影的種類。如下圖所示(該圖摘自《機器學習實戰》)

在這個電影分類問題裡,每部電影都有兩個特徵值就是(x1

(i) 接吻次數,x2

(i) 打鬥次數),現在我們要給新的一部電影進行分類,這部電影兩個特徵值為(x1

(n) ,x2

(m) )。

1. 首先,knn演算法第一步就是計算這部電影特徵值與訓練資料集中所有電影特徵值的距離。這裡的距離我們可以用曼哈頓距離或者尤拉距離:

歐式距離:di

stan

ce=∑

k1((

x1(i

)−xn

)2+(

x2(i

)−xm

)2)−

−−−−

−−−−

−−−−

−−−−

−−−−

−−−−

−−√

曼哈頓距離:di

stan

ce=∑

k1(|

(x1(

i)−x

n)|+

|(x2

(i)−

xm)|

)−−−

−−−−

−−−−

−−−−

−−−−

−−−−

−−−−

−−−√

2. 計算好**點與樣本點的距離後,將結果從小到大進行排序;

3. 選取距離最近的k個點,確定這k個點資料所在分類的出現頻率;

4. 選擇頻率最高的分類作為**資料的分類輸出;

python實現:

【**參考《機器學習實戰》】

首先生成dataset,即訓練集資料:

import numpy as np

defcreatedataset

():#將樣本的特徵值放入乙個array裡,這裡共4個樣本資料

group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

#對應的分類用list來裝載

labels = ['a','a','b','b']

return group, labels

接下來就是knn的分類器的定義:

#分類器函式共有4個輸入,inx是咱們要**分類的資料,dataset是訓練集的特徵值資料,labels則是訓練集的每個樣本類別,k為knn演算法裡的引數;

defclassify0

(inx, dataset, labels, k):

datasetsize = dataset.shape[0]#計算dataset裡總共有多少樣本

diffmat = tile(inx, (datasetsize,1)) - dataset#利用tile函式擴充套件**資料,與每乙個訓練樣本求距離

sqdiffmat = diffmat**2

sqdistances = sqdiffmat.sum(axis=1)

distances = sqdistances**0.5

#求歐式距離

sorteddistindicies = distances.argsort()#argsort()函式用法見下

classcount={} #定義乙個字典,用於儲存k個最近點對應的分類以及出現的頻次

for i in range(k):

voteilabel = labels[sorteddistindicies[i]]

classcount[voteilabel] = classcount.get(voteilabel,0) + 1

#以下**將不同labels的出現頻次由大到小排列,輸出次數最多的類別

sortedclasscount = sorted(classcount.iteritems(), key=operator.itemgetter(1), reverse=true)

return sortedclasscount[0][0]

#同樣可以用以下**實現

""" maxcount = 0

for key,value in classcount.items():

if value > maxcount:

maxcount = value

classes = key

"""

python 科學計算庫numpy—tile函式,python-numpy函式-tile函式

argsort、sort、sorted函式:淺述python中argsort()函式的用法

item、iteritems函式:【python】字典items返回列表,iteritems返回迭代器,python中dictionary items()系列函式的用法例項

接下來在python shell裡輸入以下**來呼叫knn分類器進行分類:

#-*-coding:utf-8 -*-

import sys

import knn

dataset,labels = knn.createdataset()

input = array([1.1,0.3])

k = 3

output = knn.classify(input,dataset,labels,k)

print("測試資料為:",input,"分類結果為:",output)

最終輸出;

測試資料為: [ 1.1

0.3] 分類為: a

十四 機器學習之路 K 近鄰演算法實戰

使用k 近鄰演算法識別手寫數字 乙個星期沒有更新部落格了,最近在看k 近鄰演算法和決策樹,學習 機器學習實戰 k 近鄰演算法裡的實戰問題 時遇到了些問題,經過幾天的硬啃,終於完成了 話不多說,下面一起看一下如何用k 近鄰演算法實現識別手寫數字。例子與 摘自 機器學習實戰 簡單起見,該演算法只能識別0...

機器學習 k 近鄰演算法

一.k 近鄰演算法概述 簡單地說,k 近鄰演算法採用測量不同特徵值之間的距離方法進行分類。k 近鄰演算法 knn 它的工作原理是 存在乙個樣本資料集,也稱訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸入沒有標籤的新資料後,將資料的每個特徵與樣本集合中資...

機器學習 K近鄰演算法

用例一 from sklearn.neighbors import nearestneighbors import numpy as np x np.array 1,1 2,1 3,2 1,1 2,1 3,2 nbrs nearestneighbors n neighbors 2,algorithm...