機器學習 第5篇:knn迴歸

悅光陰發表於2020-11-02

基於最鄰近演算法的分類,本質上是對離散的資料標籤進行預測,實際上,最鄰近演算法也可以用於對連續的資料標籤進行預測,這種方法叫做基於最鄰近資料的迴歸,預測的值(即資料的標籤)是連續值,通過計算資料點最臨近資料點平均值而獲得預測值。

一,sklearn的knn迴歸

scikit-learn實現了兩個不同的最鄰近迴歸模型:

  • KNeighborsRegressor:根據每個查詢點的最鄰近的k個資料點的均值作為預測值,其中,k是使用者指定的整數。
  • RadiusNeighborsRegressor:基於查詢點的固定半徑內的資料點的均值作為預測值,其中r是使用者指定的浮點值。

迴歸模擬器的定義如下,該定義只列出最重要的引數,詳細引數請參考sicikit-learn 官網:

sklearn.neighbors.KNeighborsRegressor(n_neighbors=5, weights='uniform', algorithm='auto', metric='minkowski',...)
sklearn.neighbors.RadiusNeighborsRegressor(radius=1.0, weights='uniform', algorithm='auto', metric='minkowski',...)

引數註釋:

  • radius:尋找最鄰近資料點的半徑
  • n_neighbors:最鄰近的鄰居數量
  • algorithm:尋找最鄰近的資料點的演算法,有效值是['auto','ball_tree','kd_tree','brute']
  • metric:計算距離的度量,詳細資訊請檢視:DistanceMetric 
  • weights:權重,預設值weights ='uniform',為每個鄰居分配統一的權重。 weights ='distance'分配的權重與距查詢點的距離成反比。用於也可以提供定義函式來計算權重。在某些情況下,最好對鄰居加權,以使較近的鄰居對擬合的貢獻更大,這可以通過weights關鍵字完成。

最基本的最鄰近迴歸使用統一的權重,也就是說,在特定範圍中的每個資料點對查詢點的分類(迴歸)的作用是相同的。在某些情況下,對權重點進行加權可能會比較有利,以使鄰近的點比遠離的點對迴歸的貢獻更大,這可以通過weights關鍵字完成。預設值weights ='uniform',為所有點分配相等的權重。 weights ='distance'分配的權重與距查詢點的距離成反比。

二,基於最鄰近的資料點的數量來預測

當使用knn計算某個資料點的預測值時,模型會從訓練資料集中選擇離該資料點最近的k個資料點,並且把它們的y值取均值,把該均值作為新資料點的預測值:

from sklearn.neighbors import KNeighborsRegressor

對於knn分類,使用score方法評估模型,對於迴歸的問題,返回的是R^2分數,R^2分數也叫做決定係數,是迴歸模型預測的優度度量,位於0到1之間,R^2等於1對應完美預測,R^2等於0對應於常數模型,即總是預測訓練集響應(y_train)的均值。

from sklearn.datasets import make_regression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split

kng=KNeighborsRegressor(n_neighbors=5)

x_data,y_data=make_regression(n_features=1,n_informative=1,noise=50,random_state=1)
x_train,x_test,y_train,y_test=train_test_split(x_data,y_data,random_state=1)

kng.fit(x_train,y_train)
prediction=kng.predict(x_test)

kng_test_score=kng.score(x_test,y_test)
kng_train_score=kng.score(x_train,y_train)
print('test data score:{:.2f}'.format(kng_test_score))

三,knn迴歸模型的優缺點

knn迴歸有兩個重要的引數:最鄰近資料點的數量k,資料點之間距離的度量方法。

在實踐中,通常使用較小的k值,在knn分類中通常把k值設定為奇數,便於找到多數鄰居的標籤。預設的距離度量是歐式距離,它在多數情況下的效果都很好,除此之外,還有曼哈頓距離等,詳細資訊,請閱讀《Scipy 學習第3篇:數字向量的距離計算》。

在確定knn迴歸或knn分類的k值時,可以通過摺疊交叉驗證來尋找最佳的k值,示例程式碼如下:

from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV  #通過網路方式來獲取引數

# 匯入iris資料集
iris2=datasets.load_iris()
X2=iris2.data
y2=iris2.target
print(X2.shape,y2.shape)

# 設定需要搜尋的K值,'n_neightbors'是sklearn中KNN的引數
parameters={'n_neightbors':[1,3,5,7,9,11,13,15]}
knn=KNeighborsClassifier()#注意:這裡不用指定引數

# 通過GridSearchCV來搜尋最好的K值。這個模組的內部其實就是對每一個K值進行評估
clf=GridSearchCV(knn,parameters,cv=5)  #5折
clf.fit(X2,y2)

# 輸出最好的引數以及對應的準確率
print("最終最佳準確率:%.2f"%clf.best_score_,"最終的最佳K值",clf.best_params_)

knn迴歸模型的優點之一是模型很容易理解,通常不需要過多的調參就可以得到不錯的效能,並且構建模型的速度通常很快。但是使用knn演算法時,對資料進行預處理是很重要的,對特徵很多的資料集、對於大多數特徵值都為0的資料集,效果往往不是很好。

雖然k鄰近演算法很容易理解,但是由於預測速度慢,且不能處理具有很多特徵的資料集,所以,在實踐中往往不會用到。

 

 

參考文件:

sklearn.neighbors.KNeighborsRegressor

 

相關文章