【knn近鄰演算法】演算法實現的簡單原理
阿新 • • 發佈:2020-08-05
建議使用jupyter列印一步一步進行理解
上程式碼:
import numpy as np import pandas as pd # 這裡直接引入sklearn裡的資料集,iris鳶尾花 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 切分資料集為訓練集和測試集 from sklearn.metrics import accuracy_score # 計算分類預測的準確率
iris = load_iris() # data:array([[5.1, 3.5, 1.4, 0.2], 基礎資料,矩陣 類似於x軸 'target': array([0, 0,。。 分類值 類似於y軸iris
df = pd.DataFrame(data = iris.data, columns = iris.feature_names) df['class'] = iris.target # 分類 # df['class'] iris.target
df['class'] = df['class'].map({0: iris.target_names[0], 1: iris.target_names[1], 2: iris.target_names[2]}) # 對分類進行轉值 df.head(10) # df.describe()
x = iris.data y= iris.target.reshape(-1,1) # 一唯陣列轉成二唯陣列 列向量 print(y) print(x.shape, y.shape)
# 劃分訓練集和測試集 random_state 隨機劃分個數 stratify 按照y的比例 test_size 1為總數 劃分訓練集與測試集的數量 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=35, stratify=y) print(y_train) print(x_train.shape, y_train.shape)print(x_test.shape, y_test.shape)
2:核心演算法實現 # 距離函式定義 np.abs計算絕對值 sqrt求根 def l1_distance(a, b): return np.sum(np.abs(a-b), axis=1) def l2_distance(a, b): return np.sqrt( np.sum((a-b) ** 2, axis=1) ) # 分類器實現 class kNN(object): # 定義一個初始化方法,__init__ 是類的構造方法 def __init__(self, n_neighbors = 1, dist_func = l1_distance): self.n_neighbors = n_neighbors self.dist_func = dist_func # 訓練模型方法 def fit(self, x, y): self.x_train = x self.y_train = y # 模型預測方法 def predict(self, x): # 初始化預測分類陣列 y_pred = np.zeros( (x.shape[0], 1), dtype=self.y_train.dtype ) # 遍歷輸入的x資料點,取出每一個數據點的序號i和資料x_test for i, x_test in enumerate(x): # x_test跟所有訓練資料計算距離 distances = self.dist_func(self.x_train, x_test) # 得到的距離按照由近到遠排序,取出索引值 nn_index = np.argsort(distances) # 選取最近的k個點,儲存它們對應的分類類別 nn_y = self.y_train[ nn_index[:self.n_neighbors] ].ravel() # 統計類別中出現頻率最高的那個,賦給y_pred[i] y_pred[i] = np.argmax( np.bincount(nn_y) ) return y_pred
3:測試(不理解演算法的人,只要會使用就OK了,sklean其實已經幫我們封裝好了),與一下測試例項呼叫差不多
# 定義一個knn例項 knn = kNN(n_neighbors = 3) # 訓練模型 knn.fit(x_train, y_train) # 傳入測試資料,做預測 y_pred = knn.predict(x_test) print(y_test.ravel()) print(y_pred.ravel()) # 求出預測準確率 accuracy = accuracy_score(y_test, y_pred) print("預測準確率: ", accuracy)
總結:其實sklean裡面的呼叫都是差不多的,將資料分為訓練集資料跟測試資料(測試資料只是驗證測試的x對應的y未知數是否正確),設定臨近數分類為n,將訓練資料放入fit函式進行訓練,計算對應的公式,訓練後再將需要預測的x軸值呼叫predict函式進行計算。最後得出
預測值