思路:空間上距離相近的點具備類似的特徵屬性。數據庫
執行流程:app
•1. 從訓練集合中獲取K個離待預測樣本距離最近的樣本數據;
•2. 根據獲取獲得的K個樣本數據來預測當前待預測樣本的目標屬性值 dom
三要素:K值選擇/距離度量(歐式距離)/決策選擇(平均值/加權平均)機器學習
Knn問題:數據量大,計算量較大;解決方案:kd-tree學習
kd-tree:計算方差,根據方差大的劃分測試
僞代碼實現:fetch
import numpy as np from collections import defaultdict class myknn: def fit(self, X, Y, k): self.train_x = X self.train_y = Y self.k = k def predict(self, X): predict_labels = [] for x in X: # 1. 從訓練數據中獲取K個和當前待預測樣本x最類似的樣本 neighbors = self.fetch_k_neighbors(x) # 2. 將這K個最類似的樣本中出現次數最多的類別做爲預測值 predict_label = self.calc_max_count_label(neighbors) # 3. 將當前樣本的預測值添加到臨時的列表中 predict_labels.append(predict_label) return predict_labels def fetch_k_neighbors(self, x): distances = [] for neighbor in self.train_x: dis = np.sqrt(np.sum((np.array(x) - neighbor) ** 2)) distances.append(dis) neighbors_y_distances = [[neighbor, y, dis] for neighbor, y, dis in zip(self.train_x, self.train_y, distances)] k_neighbors_y = sorted(neighbors_y_distances, key=lambda x: x[2])[:self.k] return k_neighbors_y def calc_max_count_label(self, neighbors): y_count = defaultdict(int) for neighbor, y, _ in neighbors: y_count[y] += 1 max_count_label = sorted(y_count.items(), key=lambda x: x[1], reverse=True)[0][0] return max_count_label a = myknn() X = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [1, 2, 3], [4, 5, 6], [7, 8, 9], ] Y = [1, 2, 3, 2, 1, 2, 3] k = 3 a.fit(X, Y, k) print(a.predict([[7, 8, 9], ]))
sklearn 實現:
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import os if not os.path.exists('models'): os.mkdir('models') base_path = './models/' #模型保存路徑 from sklearn.datasets import load_iris #load 鳶尾花數據 from sklearn.model_selection import train_test_split #數據分割 from sklearn.neighbors import KNeighborsClassifier #knn分類器 from sklearn.externals import joblib #持久化 data = pd.read_csv('iris.data', header=None) print(data.head()) X = data.loc[:, :3] #前4列爲特徵數據 Y = data[4] #最後一列爲目標數據 print(X.head()) X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=22) ''' def __init__(self, n_neighbors=5, #鄰居數目 weights='uniform', #uniform 等權重/distance algorithm='auto', #暴力計算和kd-tree leaf_size=30, #構建kd-tree 容許的最大葉子節點 p=2, #距離公式 metric='minkowski', #默認歐式距離 metric_params=None, n_jobs=None, #開啓多少個線程計算 **kwargs):''' algo = KNeighborsClassifier(n_neighbors=3) algo.fit(X_train, Y_train) print('準確率:{}'.format(algo.score(X_train, Y_train))) # 持久化 joblib.dump(value=algo, filename=base_path + 'knn.pkl')
機器學習開發流程:spa
# 1. 數據加載 # 2. 數據的清洗、處理 # 3. 訓練數據和測試數據的劃分 # 4. 特徵工程 # 5. 模型對象構建 # 6. 模型訓練 # 7. 模型效果評估 # 8. 模型持久化 持久化的方式主要三種: -1. 將模型持久化爲二進制的磁盤文件。 -2. 將模型參數持久化到數據庫中。 -3. 使用模型對全部數據進行預測,並將預測結果保存到數據庫中。