
一、什么是K近鄰算法?
定義:
如果一個樣本在特征空間中的k個最相似(即特征空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。
來源:
KNN算法最早是由Cover和Hart提出的一種分類算法.
計算距離公式:
兩個樣本的距離可以通過如下公式計算,又叫歐式距離。
比如說,a(a1,a2,a3),b(b1,b2,b3)

歐式距離
二、K近鄰算法的實現
sk-learn近鄰算法API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto') n_neighbors:int,可選(默認= 5),k_neighbors查詢默認使用的鄰居數 algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可選用於計算最近鄰居的算法:‘ball_tree’將會使用 BallTree,‘kd_tree’將使用 KDTree。‘auto’將嘗試根據傳遞給fit方法的值來決定最合適的算法。 (不同實現方式影響效率)
近鄰算法實例
案例背景:(kaggle地址:https://www.kaggle.com/c/facebook-v-predicting-check-ins/overview)

預測入住
數據下載地址:train.csv
數據格式:
row_id x y accuracy time place_id 0 0 0.7941 9.0809 54 470702 8523065625 1 1 5.9567 4.7968 13 186555 1757726713 2 2 8.3078 7.0407 74 322648 1137537235 3 3 7.3665 2.5165 65 704587 6567393236 4 4 4.0961 1.1307 31 472130 7440663949 ... ... ... ... ... ... ... 29118016 29118016 6.5133 1.1435 67 399740 8671361106 29118017 29118017 5.9186 4.4134 67 125480 9077887898 29118018 29118018 2.9993 6.3680 67 737758 2838334300 29118019 29118019 4.0637 8.0061 70 764975 1007355847 29118020 29118020 7.4523 2.0871 17 102842 7028698129 [29118021 rows x 6 columns]
實現思路:
1、數據集的處理(縮小數據集范圍,處理日期數據,增加分割的日期數據,刪除沒用的日期數據,將簽到位置少於n個用戶的刪除)
2、分割數據集
3、對數據集進行標准化
4、estimator流程進行分類預測
具體代碼如下:
import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 讀取數據 data = pd.read_csv("./data/FBlocation/train.csv") # 處理數據 # 1、縮小數據,查詢數據集范圍 data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75") # 處理時間的數據 time_value = pd.to_datetime(data['time'], unit='s') # 把日期格式轉換成 字典格式 time_value = pd.DatetimeIndex(time_value) # 構造一些特征 data['day'] = time_value.day data['hour'] = time_value.hour data['weekday'] = time_value.weekday # 把時間戳特征刪除 data = data.drop(['time'], axis=1) # 把簽到數量少於n個目標位置刪除 place_count = data.groupby('place_id').count() tf = place_count[place_count.row_id > 3].reset_index() data = data[data['place_id'].isin(tf.place_id)] # 取出數據當中的特征值和目標值 y = data['place_id'] x = data.drop(['place_id'], axis=1) # 進行數據的分割訓練集合測試集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 特征工程(標准化) std = StandardScaler() # 對測試集和訓練集的特征值進行標准化 x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 進行算法流程 # 超參數 knn = KNeighborsClassifier() knn.fit(x_train, y_train) y_predict = knn.predict(x_test) print("預測的目標簽到位置為:", y_predict) print("預測的准確率:", knn.score(x_test, y_test))
運行結果:
預測的目標簽到位置為: [8258328058 2355236719 6683426742 ... 5606572086 4932578245 9237487147]
預測的准確率: 0.3959810874704492
思考問題
1、k值取多大?有什么影響?
2、性能問題?
三、K近鄰算法總結
K近鄰算法優缺點
優點:
簡單,易於理解,易於實現,無需估計參數,無需訓練
缺點
- 懶惰算法,對測試樣本分類時的計算量大,內存開銷大
- 必須指定K值,K值選擇不當則分類精度不能保證
使用場景
小數據場景,幾千~幾萬樣本,具體場景具體業務去測試
四、分類模型的評估
評估方法
estimator.score()
一般最常見使用的是准確率,即預測結果正確的百分比
混淆矩陣
在分類任務下,預測結果(Predicted Condition)與正確標記(True Condition)之間存在四種不同的組合,構成混淆矩陣(適用於多分類)

混淆矩陣
精確率(Precision):預測結果為正例樣本中真實為正例的比例(查得准)

精確率(Precision)
召回率(Recall):真實為正例的樣本中預測結果為正例的比例(查的全,對正樣本的區分能力)

召回率(Recall)
其他分類標准, F1-score,反映了模型的穩健型

F1-score
分類模型評估API
評估API :
sklearn.metrics.classification_report
用法:
sklearn.metrics.classification_report(y_true, y_pred, target_names=None) y_true:真實目標值 y_pred:估計器預測目標值 target_names:目標類別名稱 return:每個類別精確率與召回率
鴛鴦花實現:
#coding=utf-8 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report #1.數據獲取 iris = load_iris() print iris.data.shape #2.數據預處理:訓練集測試集分割,數據標准化 X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.25,random_state=33) # 對訓練和測試的特征數據進行標准化 ss = StandardScaler() X_train = ss.fit_transform(X_train) X_test = ss.transform(X_test) # 3.使用K臨近分類器對測試數據進行類別預測 knc = KNeighborsClassifier() knc.fit(X_train,y_train) y_predict = knc.predict(X_test) #4.獲取結果報告 print 'The Accuracy of K-Nearest Neighbor Classifier is', knc.score(X_test,y_test) print classification_report(y_test,y_predict,target_names=iris.target_names)
執行結果:
C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=49271 import sys; print('Python %s on %s' % (sys.version, sys.platform)) sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects']) Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] Type 'copyright', 'credits' or 'license' for more information IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 7.12.0 Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32 runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence') (150, 4) The Accuracy of K-Nearest Neighbor Classifier is 0.8947368421052632 precision recall f1-score support setosa 1.00 1.00 1.00 8 versicolor 0.73 1.00 0.85 11 virginica 1.00 0.79 0.88 19 accuracy 0.89 38 macro avg 0.91 0.93 0.91 38 weighted avg 0.92 0.89 0.90 38