K-近鄰算法又稱KNN算法,最先是由Cover和Hart提出的一種分類算法,其原理很是簡單,主要是根據計算兩個樣本之間的距離從而對樣本進行預測分類,經常使用的距離計算公式有歐氏距離:python
根據未知樣本與已知樣本的歐式距離,計算出距離最近的樣本,則其爲預測樣本的類別算法
在Python的sklearn中使用KNN算法的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方法的值來決定最合適的算法;(不一樣實現方式影響效率)
使用示例:Facebook V: Predicting Check Ins機器學習
數據集來源:https://www.kaggle.com/c/facebook-v-predicting-check-ins/data學習
注意:下載數據需激活帳戶(激活帳戶需fan qiang)測試
示例來源:優化
Facebook和Kaggle2016年推出的機器學習工程競賽題目:spa
本次比賽的目的是預測一我的想要簽到的地方。爲了本次比賽的目的,Facebook建立了一我的工世界,其中包括10平方千米的100,000多個地方。對於給定的座標集,您的任務是返回最可能位置的排名列表。數據被製做成相似於來自移動設備的位置信號,讓您瞭解如何處理由不許確和嘈雜的值致使的實際數據。不一致和錯誤的位置數據可能會破壞Facebook Check In等服務的體驗。orm
部分數據示例:blog
數據介紹:
train.csv,test.csv
row_id:登記事件的ID
xy:座標
準確性:定位準確性
時間:時間戳
place_id:業務的ID,這是您預測的目標
分析
對於數據作一些基本處理(這裏所作的一些處理不必定達到很好的效果,只是簡單嘗試,有些特徵能夠根據一些特徵選擇的方式去作處理)
一、縮小數據集範圍 DataFrame.query()
data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
二、處理日期數據 pd.to_datetime pd.DatetimeIndex
time_value = pd.to_datetime(data['time'], unit='s')
三、增長分割的日期數據
time_value = pd.DatetimeIndex(time_value)
data['day'] = time_value.day
data['weekday'] = time_value.weekday
data['hour'] = time_value.hour
四、刪除沒用的數據 DataFrame.drop
data = data.drop(['time'], axis=1)
# 刪除入住次數少於三次位置
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
五、將簽到位置少於n個用戶的刪除
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
六、模型參數設置
knn = KNeighborsClassifier(n_neighbors=1)
n_neighbors即KNN算法中的K值:算法傳入參數不定的值,當值設置爲1時,結果以下:
因爲K的值直接影響到預測的準確率,經過調整k的值能夠優化準確率,使用sklearn提供的超參數搜索-網格搜索(Grid Search),採用交叉驗證來進行評估,最後選出最優參數組合創建模型:
knn = KNeighborsClassifier()
param = {"n_neighbors": list(range(1, 10))}
gc = GridSearchCV(knn, param_grid=param, cv=2)
gc.fit(x_train, y_train)
# 交叉驗證獲取最佳模型參數
print("gc選擇了的模型K值是:", gc.best_estimator_)
best_k = gc.best_estimator_.__dict__.get("n_neighbors")
調參結果:
完整代碼:
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
def knncls():
"""
K近鄰算法預測入住位置類別
:return:
"""
# 1、處理數據以及特徵工程
# 一、讀取收,縮小數據的範圍
data = pd.read_csv("./train.csv")
# 數據邏輯篩選操做 df.query()
data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
# 二、處理時間戳日期
time_value = pd.to_datetime(data['time'], unit='s')
time_value = pd.DatetimeIndex(time_value)
# 加入時間的其它的特徵
data['day'] = time_value.day
data['weekday'] = time_value.weekday
data['hour'] = time_value.hour
# 刪除time這一列特徵
data = data.drop(['time'], axis=1)
# 刪除入住次數少於三次位置
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
# 三、取出特徵值和目標值
y = data['place_id']
x = data.drop(['place_id', 'row_id'], axis=1)
# 四、數據分割與特徵工程?
# (1)、數據分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
# (2)、標準化
std = StandardScaler()
# 對訓練集進行標準化操做
x_train = std.fit_transform(x_train)
# 進行測試集的標準化操做
x_test = std.fit_transform(x_test)
# 2、算法的輸入訓練預測
# K值:算法傳入參數不定的值 理論上:k = 根號(樣本數)
# 交叉驗證調參 使用網格搜索和交叉驗證找到合適的參數
knn = KNeighborsClassifier()
param = {"n_neighbors": list(range(1, 10))}
gc = GridSearchCV(knn, param_grid=param, cv=2)
gc.fit(x_train, y_train)
# 交叉驗證獲取最佳模型參數
print("gc選擇了的模型K值是:", gc.best_estimator_)
best_k = gc.best_estimator_.__dict__.get("n_neighbors")
knn = KNeighborsClassifier(n_neighbors=best_k)
# 調用fit()
knn.fit(x_train, y_train)
# 預測測試數據集,得出準確率
y_predict = knn.predict(x_test)
print("預測測試集類別:", y_predict)
print("準確率爲:", knn.score(x_test, y_test))
return None
knncls()
結果: