4.1 K近鄰算法
- 思想極度簡單
- 應(yīng)用數(shù)學(xué)知識少
- 可以解釋機器學(xué)習(xí)算法使用過程中的很多細節(jié)問題
- 更完整的刻畫機器學(xué)習(xí)的應(yīng)用流程
??K近鄰算法的本質(zhì)其實是認為兩個樣本如果足夠相似篙悯,就有更高的概率屬于同一個類別随橘。兩個樣本的相似性就是由在空間上兩個樣本的距離來決定的。</br>
??K近鄰算法可以解決監(jiān)督學(xué)習(xí)的分類問題,也可以解決回歸問題。
import numpy as np
import matplotlib.pyplot as plt
# 模擬樣本數(shù)據(jù)集
raw_data_x = [[3.423749247, 2.334567896],
[3.110073483, 1.745697878],
[1.347946498, 3.368464565],
[3.582294042, 4.679565478],
[2.280364646, 2.866699256],
[7.423454548, 4.696522875],
[5.745051465, 3.533989946],
[9.172456464, 2.051111010],
[7.792783481, 3.424088941],
[7.939820184, 0.791637231]
]
raw_data_y = [0,0,0,0,0,1,1,1,1,1]
X_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)
plt.scatter(X_train[y_train==0, 0], X_train[y_train==0, 1], color='g')
plt.scatter(X_train[y_train==1, 0], X_train[y_train==1, 1], color='r')
plt.show()
image
# 此時來了新的樣本
x = np.array([8.093607318, 3.3657315144])
plt.scatter(X_train[y_train==0, 0], X_train[y_train==0, 1], color='g')
plt.scatter(X_train[y_train==1, 0], X_train[y_train==1, 1], color='r')
plt.scatter(x[0], x[1], color='b')
plt.show()
image
由此可以看出新的樣本點應(yīng)該是和紅色點是一類咏花。
KNN過程
歐拉距離:
\sqrt{(x^(a)-x^(b))^2 + (y^(a)-y^(b))^2}
\sqrt{(x^(a)-x^(b))^2 + (y^(a)-y^(b))^2 + (z^(a)-z^(b))^2}
\sqrt{(X_1^(a)-X_1^(b))^2 + (X_2^(a)-X_2^(b))^2 + ... + (X_n^(a)-X_n^(b))^2}
\sqrt{\sum_{i=1}^n(X_i^(a)-X_i^(b))^2}
from math import sqrt
distances = []
for x_train in X_train:
d = sqrt(np.sum((x_train -x)**2))
distances.append(d)
distances
# 等價于下面這行代碼
distances = [sqrt(np.sum((x_train -x)**2)) for x_train in X_train]
distances
運行結(jié)果如下:
image
計算完距離之后還不夠,因為我們主要想知道距離樣本點最近的點。
np.argsort(distances)
運行結(jié)果:
array([8, 5, 7, 6, 9, 3, 0, 1, 4, 2])贼急,我們可以看出距離最近的是索引為為8的點,距離第二近的是索引為5的點捏萍。
# 設(shè)置k值太抓,找出離樣本點最近的k個點的y值
k = 6
nearest = np.argsort(distances)
topK_y = [y_train[i] for i in nearest[:k]]
運行結(jié)果:[1, 1, 1, 1, 1, 0]我們可以看出,距離樣本點最近的6個點中令杈,前5個點的y值均為1.
# 計算不同類的點的個數(shù)走敌,統(tǒng)計頻數(shù)
from collections import Counter
Counter(topK_y)
運行結(jié)果:Counter({1: 5, 0: 1})這就表示值為1的元素有5個,值為0的元素只有1個逗噩。
# 就像投票一樣掉丽,我們選出票數(shù)最多的一位
votes = Counter(topK_y)
votes.most_common(1)
# 由上面我們得到的是一個列表跌榔,但是我們只關(guān)心新樣本所屬的類別,因此只需要取出的類別值即可捶障。
votes.most_common(1)[0][0]
image
由此我們可以看出僧须,新的樣本最有可能是1這一類。