K-近鄰算法

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()

 

結果:

相關文章
相關標籤/搜索