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
型別 | 描述 |
---|---|
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美元,哇!感覺自己好有錢。。。。好吧,能先給我來一套房子嗎?