1. 程式人生 > >python機器學習-k近鄰(KNN)演算法例項

python機器學習-k近鄰(KNN)演算法例項

機器學習-k近鄰(KNN)
本篇主要是自己複習和總結機器學習演算法中最基礎入門的——k近鄰(KNN)演算法,內容由網上百度與摘抄唐宇迪老師的講義。

k近鄰介紹

——K最近鄰(k-Nearest Neighbor,KNN),k近鄰演算法可以應用於分類場景與迴歸場景,是一個理論上比較不成熟的方法,也是最簡單的機器學習演算法之一。該方法的思路是:如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。
——用官方的話來說,所謂K近鄰演算法,即是給定一個訓練資料集,對新的輸入例項,在訓練資料集中找到與該例項最鄰近的K個例項(也就是上面所說的K個鄰居), 這K個例項的多數屬於某個類,就把該輸入例項分類到這個類中。

: 看圖舉例:
這裡寫圖片描述
圖形中有2種已知的圖形,分別是藍色的方塊和紅色的三角,綠色的未知圖形。通過K近鄰演算法去判斷未知的綠色圖形是什麼,取決於它周圍距離最近的圖形。
比如把K近鄰的近鄰引數設定成3(圖中實線圓圈),那麼未知的綠色圖形就是三角。如果近鄰引數設定成5(圖中虛線圓圈),那麼未知的綠色圖形就是方塊。

所以在K近鄰演算法中,設定近鄰引數是會決定最後預測的結果準確性,那麼怎麼設定引數是多少呢?這個後面會給大家再進行介紹,本篇K近鄰演算法的實現主要是通過經典的機器學習庫(sklearn)來完成。

K近鄰在sklearn裡面的API為sklearn.neighbors,在該模組下由細分了13個小的模組。本文主要使用neighbors.KNeighborsRegressor

基於k-最近鄰居的迴歸來進行說明官方教程連結

型別 描述
neighbors.BallTree BallTree用於快速廣義N點問題
neighbors.DistanceMetric DistanceMetric類
neighbors.KDTree KDTree用於快速廣義N點問題
neighbors.KernelDensity([bandwidth, …]) 核密度估計
neighbors.KNeighborsClassifier([…]) 實現k近鄰的分類器投票
neighbors.KNeighborsRegressor([n_neighbors, …]) 基於k-最近鄰居的迴歸
neighbors.LocalOutlierFactor([n_neighbors, …]) 使用區域性異常因子(LOF)的無監督異常值檢測
neighbors.RadiusNeighborsClassifier([…]) 在給定半徑內的鄰居之間實施投票的分類器
neighbors.RadiusNeighborsRegressor([radius, …]) 基於固定半徑內的鄰居的迴歸
neighbors.NearestCentroid([metric, …]) 最近的質心分類器
neighbors.NearestNeighbors([n_neighbors, …]) 用於實現鄰居搜尋的無監督學習者
neighbors.kneighbors_graph(X, n_neighbors[, …]) 計算X中點的k-鄰居的(加權)圖
neighbors.radius_neighbors_graph(X, radius) 計算X中各點的鄰居(加權)圖

k近鄰引數

sklearn.neighbors.KNeighborsRegressor預設引數:

sklearn.neighbors.KNeighborsRegressor(n_neighbors = 5,weights =‘uniform’,algorithm =‘auto’,leaf_size = 30,p = 2,metric =‘minkowski’,metric_params = None,n_jobs = 1,** kwargs )

引數說明:
n_neighbors:int, optional (default = 5)

使用預設的鄰居數量kneighbors查詢,預設是5

weights : str or callable

權函式用於預測,可能的值
‘uniform’ :統一的重量。權重分在每個社群都是一樣的
‘distance’ :重量分距離的倒數。在這種情況下,接近鄰居查詢的點會有一個更大的影響力遠比鄰居
[callable] :一個使用者定義的函式接受一個數組的距離,並返回一個數組包含權重相同的形狀

algorithm : {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, optional

演算法用於計算最近的鄰居
‘ball_tree’將使用BallTree
‘kd_tree’將使用KDTree
'brute’將使用蠻力搜尋
‘auto’將試圖確定最合適的演算法基於價值觀傳遞給合適的方法

leaf_size : int, optional (default = 30)

葉大小BallTree或KDTree傳遞。這可能影響施工和查詢的速度,以及所需的記憶體儲存樹。最優值取決於問題的性質。

metric : string or callable, default ‘minkowski’

指標用於樹的距離。預設度量是閔可夫斯基,p = 2相當於歐幾里得度量的標準。看到的DistanceMetric類的文件的列表可用指標。

metric_params : dict, optional (default = None)

額外的關鍵字引數的度量函式

n_jobs : int, optional (default = 1)

並行工作的數量的鄰居搜尋。如果1,那麼就業人數將CPU核的數量。不影響健康的方法。

官網例子

X=[[0],[1],[2],[3]] #建一個List
y=[0,0,1,1] #建一個List
from sklearn.neighbors import KNeighborsRegressor #匯入K近鄰迴歸模組
neigh=KNeighborsRegressor(n_neighbors=2) #近鄰引數設定成2個相鄰
neigh.fit(X, y) #使用X作為訓練資料,y作為目標值
print(neigh.predict([[1.5]])) #給提供的資料預測對應的標籤,當x=1.5的時候y應該是多少

#最終輸出當x=1.5的時候y=0.5
型別 描述
fit(X, y) 使用X作為訓練資料,y作為目標值(類似於標籤)來擬合模型。
get_params([deep]) 獲取估值器的引數。
kneighbors([X, n_neighbors, return_distance]) 查詢一個或幾個點的K個鄰居
kneighbors_graph([X, n_neighbors, mode]) 計算在X陣列中每個點的k鄰居的(權重)圖
predict(X) 給提供的資料預測對應的標籤
predict_proba(X) 返回測試資料X的概率估值
score(X, y[, sample_weight]) 返回給定測試資料和標籤的平均準確值
set_params(**params) 設定估值器的引數

k近鄰實際應用

注:該例項出至唐宇迪老師,大家也可以百度檢視
案例資料下載
案例背景:
自己在美國有一套房子想要在Airbnb平臺上進行短租,但是不知道自己的房子能租多少錢?設定多少錢才是最合理的呢?
好吧,開始前我先說明一下我的房子情況:我的房子可以容納6名旅客,有3個臥室,廁所每個臥室都有,有3張床,我想最短租1天我還是能接受的,最多租30天好像就差不多了。為了能收益最大我們直接來程式碼:

房租價格預測

匯入所需要的Python模組

import pandas as pd #匯入pandas庫
from sklearn.neighbors import KNeighborsRegressor #匯入機器學習庫中的K近鄰迴歸模型
from sklearn.metrics import mean_squared_error #匯入機器學習庫中的均方誤差迴歸損失模型

匯入資料及資料預處理

dc_listings=pd.read_csv(r'C:\Users\huangjunwen\Desktop\listings.csv') #將資料匯入,路徑請根據自己的檔案路徑設定
features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews'] #因資料太多設定只選取這8列
dc_listings = dc_listings[features] #獲取只需要的資料列,並覆蓋原始資料
dc_listings.head()#先檢視一下資料情況,對資料有個初步瞭解
dc_listings['price']=dc_listings.price.str.replace("\$|,",'').astype(float) #將價格price變成數字型別
dc_listings=dc_listings.dropna() #過濾缺失資料
normalized_listings = dc_listings #複製一下資料

norm_train_df=normalized_listings.copy().iloc[0:2792] #建立訓練集訓練集取2792個樣本
norm_test_df=normalized_listings.copy().iloc[2792:] #建立測試集取879個樣本

資料列名說明 accommodates:可以容納的旅客、bedrooms:臥室的數量、bathrooms:廁所的數量、beds:床的數量、price:每晚的費用、minimum_nights:客人最少租幾天、maximum_nights:客人最多租幾天、number_of_reviews:評論的數量

建立K近鄰模型

cols = ['accommodates','bedrooms','bathrooms','beds','minimum_nights','maximum_nights','number_of_reviews'] #選擇測試集的訓練的列
knn = KNeighborsRegressor(10) #模型近鄰值手動設定成10,其他為預設引數
knn.fit(norm_train_df[cols], norm_train_df['price']) #X放入訓練集資料,Y放入目標輸出資料
two_features_predictions = knn.predict(norm_test_df[cols]) #輸出測試集結果

建立模型效果驗證

two_features_mse = mean_squared_error(norm_test_df['price'], two_features_predictions)
two_features_rmse = two_features_mse ** (1/2)
print(two_features_rmse) #輸出模型驗證結果,根據結果調整近鄰引數

呼叫模型設定實際值進行預測

print(knn.predict([[6,3,3,3,1,30,0]])) #設定自己房子的資訊,預測出對應的價格

數字代表我房子與數量列對應的名稱,容納旅客數=6,臥室=3,廁所=3,床=3,最少租=1,最多租=30,評論=0

好了,我房子的一晚上價格大概能租192美元,哇!感覺自己好有錢。。。。好吧,能先給我來一套房子嗎?