機器學習之算法KNN(K-近鄰)

KNN(K近鄰)算法

前言

因爲自己準備數據集耗時耗力還不一定真實,所以小編在此採用scikit-learn數據集

什麼是KNN?

如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。

小編的理解是:根據你的“鄰居”判斷你的類別

k近鄰(KNN)算法是一種簡單,易於實現的有監督的機器學習算法,可用於解決分類和迴歸問題。

舉例

在這裏插入圖片描述
如上圖所示,我們將打鬥鏡頭、接吻鏡頭當作你的特徵值,那麼電影類型就是你的目標值。那麼對於電影名稱爲“?”,我們怎麼判斷電影類型?

在這裏插入圖片描述
如果在表中在添加如下一列“與目標電影的距離”,我們可以發現電影名稱“?”與“He‘s not Really into dues”的距離最近,那麼我們就能以此爲依據判斷“?”的電影類型了。

這個距離怎麼計算呢?

兩個樣本的距離可以通過如下公式計算,又叫歐式距離。

比如說,a(a1,a2,a3),b(b1,b2,b3)

在這裏插入圖片描述
那麼對於上述示例而言,以“California Man”舉例,其距離爲:
在這裏插入圖片描述
細心的讀者一定可以發現,如果根號下兩個平方數值差距特別大,(例:根號((100-3)^2 +(14-13)^2),我們會發現這個距離是被(100-3)這部分數值所主導

如何避免這個問題?

KNN算法需要進行標準化!!!

當然,KNN算法中K的取值也會影響最終分類的結果

假設k=1,則取距離最近的1個電影類型來判斷“?”的類型
假設k=2,則取距離最近的2個電影類型來判斷“?”的類型
假設k=3,則取距離最近的3個電影類型來判斷“?”的類型

但是這個k不是越大越好

知識儲備

sklearn k-近鄰算法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方法的值來決定最合適的算法。(不同實現方式影響效率)

代碼演示

這是一個簡單的KNN算法流程


from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

def knn_alg():
    '''
    classfied iris
    :return:None
    '''
    # 加載數據集
    iris_data = load_iris()

    #將數據劃分爲訓練集和測試集
    #test_size是劃分的比例
    x_train,x_test,y_train,y_test = train_test_split(iris_data["data"],iris_data["target"],test_size=0.25)

    #對特徵工程進行標準化
    std = StandardScaler()

    #對測試集和訓練集的特徵值進行標準化
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)

    #進行KNN算法流程
    knn =KNeighborsClassifier()

    #構造這個模型
    knn.fit(x_train,y_train)

    #得出預測結果
    y_predict = knn.predict(x_test)
    print("預測結果", y_predict)

    #得出準確率
    score = knn.score(x_test,y_test)
    print("準確率",score)
    return None


if __name__ == "__main__":
    knn_alg();

優化

前面小編說過K的取值也會影響KNN算法,所以我們可以對以上流程再做一部分改進。

網格搜索

通常情況下,有很多參數是需要手動指定的(如k-近鄰算法中的K值),這種叫超參數。但是手動過程繁雜,所以需要對模型預設幾種超參數組合。每組超參數都採用交叉驗證來進行評估。最後選出最優參數組合建立模型。

GridSearchCV

sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)對估計器的指定參數值進行詳盡搜索

  • estimator:估計器對象
  • param_grid:估計器參數(dict){“n_neighbors”:[1,3,5]}
  • cv:指定幾折交叉驗證
  • fit:輸入訓練數據
  • score:準確率
    結果分析:
  • best_score_:在交叉驗證中測試的最好結果
  • best_estimator_:最好的參數模型
  • cv_results_:每次交叉驗證後的測試集準確率結果和訓練集準確率結果

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

def knn_alg():
    '''
    classfied iris
    :return:None
    '''
    # 加載數據集
    iris_data = load_iris()

    #將數據劃分爲訓練集和測試集
    #test_size是劃分的比例
    x_train,x_test,y_train,y_test = train_test_split(iris_data["data"],iris_data["target"],test_size=0.25)

    #對特徵工程進行標準化
    std = StandardScaler()

    #對測試集和訓練集的特徵值進行標準化
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)

    #進行KNN算法流程
    knn =KNeighborsClassifier()

    # #構造這個模型
    # knn.fit(x_train,y_train)
    #
    # #得出預測結果
    # y_predict = knn.predict(x_test)
    # print("預測結果", y_predict)
    #
    # #得出準確率
    # score = knn.score(x_test,y_test)
    # print("準確率",score)

    # 構造一些參數的值進行搜索
    param = {"n_neighbors": [3, 5, 10]}

    # 進行網格搜索
    gc = GridSearchCV(knn, param_grid=param, cv=2)

    gc.fit(x_train, y_train)

    # 預測準確率
    print("在測試集上準確率:", gc.score(x_test, y_test))

    print("在交叉驗證當中最好的結果:", gc.best_score_)

    print("選擇最好的模型是:", gc.best_estimator_)

    print("每個超參數每次交叉驗證的結果:", gc.cv_results_)
    return None

if __name__ == "__main__":
    knn_alg();

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章