kNN學習筆記

kNN學習筆記


一、kNN基礎
二、什麼是機器學習
三、超參數
四、數據歸一化
五、總結

一、kNN基礎

實現簡單
使用的數學知識少
適合入門
  • 簡單的來講,KNN算法就是找出x最近鄰的k個樣本,k個樣本中,找出與之特徵相似樣本的數量最多的類別,然後將x分入該類別。
    在這裏插入圖片描述
  • 以上圖爲例,設k = 3,即找出與藍色的點最詳盡的三個點,很顯然,最近的三個點都爲紅色的點,那麼該藍色的點就位紅色這一類。相應的,如果藍色點的最近的三個點中有兩個點爲紅色,一個爲藍色,則仍然歸類爲紅色一類,反之亦然。

二、什麼是機器學習

  • 輸入訓練數據集,在機器學習算法訓練生成模型,輸入樣例到模型之後得到預測的輸出結果
    *在這裏插入圖片描述
  • knn是一個不需要訓練過程的算法
  • knn是特殊的,是沒有模型的算法
  • 爲了和其它算法統一,可以說訓練集本身就是模型
  • 訓練數據集、測試數據集
  •   訓練得到的模型能夠直接在真實環境中使用
    
  • 問題:
  •   模型如果很差會造成真實損失
    
  •   真實環境中不能拿到真實的label(target)
    
  • 因此需要訓練數據集合測試數據集分離:
  •   使用封裝好的train_test_split,或者十折交叉驗證(10-fold cross validation)
    
# 一個demo
# 導入封裝好了knn算法
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
knn_clf = KNeighborsClassifier(n_neighbors = 3)  #這裏的n_neighbors = 3即前面講到的k = 3
iris = datasets.load_iris() #獲取鳶尾花的數據
#用X、y來接受鳶尾花的特徵值和類別
X = iris.data
y = iris.target
#將數據分爲訓練集和測試集
X_train, x_test, y_train, y_test = train_test,split(X, y, test_size = 0.2)
#做模型訓練
knn_clf.fit(X_train, y_train)
#數據預測
y_predict = knn_clf.predict(X_test)
#滿足預測結果與實際結果相同的率,即預測成功率
rate = sum(y_predict == y_test)/y_test
#同上一列所達到的目的一樣

knn_clf.score(X_test, y_test)

#也可以使用accuracy_score來評價預測成功率
from sklearn.metrics import accuracy_score

accuracy_score(y_predict, y_test)

三、超參數

在機器學習的上下文中,超參數是在開始學習過程之前設置值的參數,而不是通過訓練得到的參數數據。通常情況下,需要對超參數進行優化,給學習機選擇一組最優超參數,以提高學習的性能和效果。

  • 簡單的來說,超參數就是爲了來提高學習的性能和效果。

  • 超參數:在算法運行前需要決定的參數

  • 模型參數:算法過程中學習的參數

    尋找好的參數:
    領域知識
    經驗數值

  1. 這就涉及了一些問題,怎麼找到最好的超參數呢?以尋找最好的k爲例:
# 可以寫在上一個代碼示例後面
best_score = 0.0
best_k = -1
# 在1-11之間尋找最好的k
for k in range(1, 11):
    knn = KNeighborsClassifier(n_neighbors = k)
    knn.fit(X_train, y_train)
    score = knn.score(X_test, y_test)
    if score > best_score:
        best_score = score
        best_k = k

        
print("best_k = ", best_k)
print("best_k = ", best_score)
  1. 上例只考慮了k的最好值,還有其它的超參數類型:例如:下圖中的sample最近鄰的三個點都有相應的weight,三個點中,有兩個爲藍色一類的,一個綠色,但是綠色的權重100 > 50+40,所以算上權重的話,sample應該歸爲綠色一類。代碼可以試着自己寫一下。
    在這裏插入圖片描述

  2. 曼哈頓距離:每個維度上的差值的絕對值之和
    歐拉距離:每個維度上的差值的平方之和的平方根
    閔可夫斯基距離: 每個維度上的距離絕對值的p次方之和的p次方根

  • 你可以思考一下閔可夫斯基距離中的p可否作爲一個超參數
  1. 事實上,在尋找各超參數或者模型參數的過程中,不需要自己不斷地遍歷。可以使用網格搜索(Grid Search)
param_grid = [
    {
        'weights':['uniform'],
        'n_neighbors':[i for i in range(1,11)]
    },
    {
        'weights':['distance'],
        'n_neighbors': [i for i in range(1,11)],
        'p': [i for i in range(1,6)]
    }
]

from sklearn.model_selection import GridSearchCV
grid_search = GridSearchCV(knn, param_grid)
gsCV = grid_search.fit(X_train , y_train)
print(gsCV)

#

四、數據歸一化

爲什麼要進行數據歸一化呢?以下圖所示:(該圖的數據爲我現場寫的,僅作爲解釋,可能會有誤解)對如下數據做處理,X2的參數中數據明顯偏大,分類過程受到X2的影響明顯會更大,但是其中一項數據對結果的影響更大,肯定會影響到最終預測的準確率,所以做標準歸一化操作很重要,要避免某一項或某幾項會明顯影響結果的情況。

X1 X2 y
7 100 1
9 76 0
8 83 1
  • 這裏給出以下兩種方式:
  1. 最值歸一化: 把所有的數據映射到0-1之間
    使用於分佈有明顯邊界的情況;受到outlier影響較大
    缺點不能解決數據偏值很大的數據
    例如:大部分的數據的值都在100以內,有小部分的重要數據在500以上,最值歸一化就難以處理,即若在預測時需要預測500以上的數據,那麼由於數據量少,預測結果就不準確

  2. 均值方差歸一化:將所有數據歸一到均值爲0方差爲1的分佈中
    數據分佈沒有明顯的邊界;有可能存在極端數據值

    真實環境很有可能無法得到所有測試數據的均值和方差
    對數據的歸一化也是算法的一部分,所以測試數據進行歸一化時,需要用到測試數據的均值和方差,(X_test - mean_train)/std_train, 要保存測試數據值的均值和方差,給測試訓練集使用

  • 於是引入scikit-learn中的standardScaler方法:
from sklearn.preprocessing import StandardScaler
stand = StandardScaler()
stand.fit(X_train)
#打印出均值和方差
print(stand.mean_)
print(stand.scale_)
#將X_train轉化爲均值爲0,方差爲1的形式
X_train = stand.transform(X_train)
print(X_trian)
X_test_t = stand.transform(X_test)
#對現在的數據進行訓練並看最終的預測成功率
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, y_train)
knn.score(X_test, y_test)

五、總結

  1. knn 可以解決分類問題,天然地可以解決多分類問題且思想簡單
  2. knn也可以解決迴歸問題:可以瞭解KNeighborsRegressor方法
  3. 缺點:
    • 最大缺點:效率低下。如果訓練集有m個樣本,n個特徵,則預測一個新的數據,需要O(m*n)。優化:使用KD-Tree,Ball-Tree
    • 高度數據相關
    • 預測結果具有不可解釋性
      * (維數災難)隨着維度的增加,看似很近的兩個點之間的距離越來越大
      * 解決方法:降維 PCA方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章