KNN(K近鄰算法)
基礎理解
面對這個算法需要蹦出來幾個問題:KNN是什麼?可以解決什麼問題?怎麼實現?有什麼優缺點?
首先,KNN我們通常稱之爲K近鄰算法,通俗的理解便是如果我們認爲兩個特徵之間他們足夠相似,我們就有理由認爲他們屬於同一個類別。
豐富上一小節的一張圖以後:
接着,通常情況下我們使用KNN是用來解決分類問題,當然,很少情況下我們也會使用它來解決迴歸問題。
其主要的解決思路爲:
①求出我們需要預測的點與數據集中的點之間的距離,根據初中所學,我們使用歐拉距離來表示。
②將距離進行排序,找前k箇中出現次數最多的便是我們的預測結果。
代碼實現:(Github處於外網,所以我在這裏直接貼上自己封裝的KNN算法)
源碼在源碼中
import numpy as np
from collections import Counter
from math import sqrt
class KNeighborsClassifier:
def __init__(self,k):
'''check'''
assert k>=1,"K must be valid"
self.k = k
'''private'''
self._X_train = None
self._y_train = None
def fit(self,X,y):
'''check'''
assert X.shape[0] == y.shape[0],\
"The data size must be valid"
assert self.k <= y.shape[0],\
"K must be valid"
self._X_train = X
self._y_train = y
'''according to the scikit-learn,we need to return self'''
return self
def predict(self,x_predict):
'''check'''
assert self._X_train.shape[1] == x_predict.shape[1],\
"The size must be valid"
assert self._X_train is not None and self._y_train is not None,\
"The process fit should do before predict"
y_predict = [self._doPredict(x) for x in x_predict]
return y_predict
def _doPredict(self,x):
'''check'''
assert x.shape[1] == self._X_train.shape[1],\
"The size must be valid"
distances = [sqrt(np.sum((x - self._X_train)**2)) for x_train in self._X_train]
sortedIndex = np.argsort(distances)
topK = [self._y_train[i] for i in sortedIndex[:self.k]]
return Counter(topK).most_common(1)[0][0]
def __repr__(self):
return "KNeighborsClassifier()"
1.準備初始數據,並通過matplotlib工具查看圖像
import numpy as np
import matplotlib.pyplot as plt
from myML.Knn import KNeighborsClassifier
raw_x = [[3.3935, 2.3312],
[3.1101, 1.7815],
[1.3438, 3.3684],
[3.5823, 4.6792],
[2.2804, 2.8670],
[7.4234, 4.6965],
[5.7451, 3.5340],
[9.1722, 2.5111],
[7.7928, 3.4241],
[7.9398, 0.7916]]
raw_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
X_train = np.array(raw_x)
y_train = np.array(raw_y)
plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='red')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='blue')
plt.show()
添加點進行預測
#假設下點爲所要預測的點
x = np.array([8.0936, 3.3657])
plt.scatter(x[0],x[1],color='green')
通過上圖看到,綠色的點爲所有預測的點,眼睛直觀看來,綠色應該是和藍色點一個類別。通過使用我們的算法代碼預測後:
#假設下點爲所要預測的點
x = np.array([8.0936, 3.3657]).reshape(1,-1)
Knn_cif = KNeighborsClassifier(k = 5)
Knn_cif.fit(X_train,y_train)
result = Knn_cif.predict(x)
if result[0] == 1:
print("Green")
else:
print("Red")
# 打印結果爲Green,結果預測準確
KNN優缺點
優點:
1.KNN算法不需要訓練過程,也可理解爲這個算法沒有模型或者模型就是數據本身
2.對數學要求少,效果較好。
3.完整的刻畫機器學習的過程,既可以解決分類問題也可以解決迴歸問題,而且可以天然的解決多分類問題。
缺點:
1.運行效率極低,並且高度依賴數據,這在機器學習算法中不可取。如果我們本身的數據產生錯誤,例如在三近鄰算法中,有兩個數據出錯,預測結果就極其容易出錯。
2.通過KNN算法我們得到的預測結果具有不可解釋性。按照KNN算法的實現邏輯,爲什麼離預測點最近的就是它的類型,我們拿到結果後還需要更多的東西,KNN提供不了。
3.維數災難。我們上面所呈現的例子是二維,如果在多維空間下,兩個點之間的歐拉距離十分大,容易造成維數災難。
Scikit-Learn中KNN算法調用:
from sklearn.neighbors import KNeighborsClassifier
sklearnKnn = KNeighborsClassifier(n_neighbors = 5)
sklearnKnn.fit(X_train,y_train)
sklearnKnn.predict(x)
小提示:通過我們自己的封裝以及scikit-learn的調用可以發現,我們在進行機器學習的過程中常常按照實例化->fit->predict的過程來進行預測。