1. 程式人生 > >機器學習實踐(八)—sklearn之交叉驗證與引數調優

機器學習實踐(八)—sklearn之交叉驗證與引數調優

一、交叉驗證與引數調優

  • 交叉驗證(cross validation)

    • 交叉驗證:將拿到的訓練資料,分為訓練集、驗證集和測試集。
      • 訓練集:訓練集+驗證集
      • 測試集:測試集
    • 為什麼需要交叉驗證
      • 為了讓被評估的模型更加穩健
  • 引數調優

    • 超引數搜尋-網格搜尋(Grid Search)

      通常情況下,有很多引數是需要手動指定的(如k-近鄰演算法中的K值),這種叫超引數。但是手動過程繁雜,所以需要對模型預設幾種超引數組合。每組超引數都採用交叉驗證來進行評估。最後選出最優引數組合建立模型。

  • 區分交叉驗證和引數調優

    • 交叉驗證
      • 使模型更穩健
    • 引數調優
      • 使模型準確性更高

二、模型選擇、引數調優和交叉驗證整合 API

sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)

  • 介紹
    • 對估計器的指定引數值進行詳盡搜尋
  • 引數介紹
    • estimator
      • 估計器物件
    • param_grid
      • 估計器引數(dict){“n_neighbors”:[1,3,5]}
    • cv
      • 指定幾折交叉驗證
  • return
    • estimator
      • 新的估計器物件
  • 使用新的估計器物件方法不變
    • fit:輸入訓練資料
    • score:準確率
  • 新估計器物件的屬性
    • bestscore:在交叉驗證中驗證的最好結果_
    • bestestimator
      :最好的引數模型
    • cvresults:每次交叉驗證後的驗證集準確率結果和訓練集準確率結果

三、交叉驗證與引數調優-案例:鳶尾花案例增加K值調優

  • 完整程式碼

    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split,GridSearchCV
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    
    # 載入資料
    iris = load_iris()
    
    # 劃分資料集
    x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.3,random_state=8)
    
    # 標準化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    
    # 指定演算法及模型選擇與調優——網格搜尋和交叉驗證
    estimator = KNeighborsClassifier()
    param_dict = {"n_neighbors": [1, 3, 5]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
    
    # 訓練模型
    estimator.fit(x_train,y_train)
    
    # 模型評估
    # 方法一 比對真實值與預測值
    y_predict = estimator.predict(x_test)
    y_test == y_predict
    # 方法二 計算準確率
    estimator.score(x_test,y_test)
    
    # 然後進行評估檢視最終選擇的結果和交叉驗證的結果
    print("在交叉驗證中驗證的最好結果:\n", estimator.best_score_)
    print("最好的引數模型:\n", estimator.best_estimator_)
    print("每次交叉驗證後的準確率結果:\n", estimator.cv_results_)
    

四、交叉驗證與引數調優-案例:預測facebook簽到位置

  • 目標

    • 將根據使用者的位置,準確性和時間戳預測使用者正在檢視的業務。
  • 資料集介紹

在這裡插入圖片描述

  • 兩個檔案

    • train.csv
    • test.csv
  • 檔案欄位

    • row_id:登記事件的ID

    • xy:座標

    • accuracy:定位準確性

    • time:時間戳

    • place_id:業務的ID,這是您預測的目標

官網:https://www.kaggle.com/navoshta/grid-knn/data

  • 步驟分析

    • 資料預處理
      • 縮小資料集範圍
      • 時間特徵提取
      • 將簽到數少於n的位置刪除
    • 資料集劃分
    • 特徵工程
      • 標準化
    • KNN演算法
    • GSCV優化
    • 模型評估
  • 完整程式碼

import pandas as pd
from sklearn.model_selection import GridSearchCV,train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

#讀取資料
facebook=pd.read_csv("./data/FBlocation/train.csv")
facebook.head()

# 資料預處理
# 1> 縮小資料集範圍
facebook = facebook.query("x<1.5&x>1.25&y>2.25&y<2.5")
# 2> 時間特徵提取
time_value = pd.to_datetime(facebook['time'],unit='s')
time_value = pd.DatetimeIndex(time_value)
facebook['day'] = time_value.day
facebook['hour'] = time_value.hour
facebook['weekday'] = time_value.weekday
# 3> 刪除簽到數少於n的位置
place_count = facebook.groupby(['place_id']).count()
place_count = place_count.query('row_id>3')
facebook = facebook[facebook['place_id'].isin(place_count.index)]

# 資料集劃分
# 1> 拿取有用的特徵資料
x=facebook[['x','y','accuracy','day','hour','weekday']]
# 2> 拿取目標值資料
y=facebook['place_id']
# 3> 資料集劃分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=8)

# 特徵工程:標準化
# 1> 建立轉換器
transfer = StandardScaler()
# 2> 計算並標準化訓練集資料
x_train = transfer.fit_transform(x_train)
# 3> 計算並標準化測試集資料
x_test = transfer.transform(x_test)

# 模型訓練及引數優化
# 1> 例項化一個K-近鄰估計器
estimator = KNeighborsClassifier()
# 2> 運用網路搜尋引數優化KNN演算法
param_dict = {"n_neighbors":[3,5,7,9]}  # K-近鄰中分別選取這幾個 K 值,最終經過交叉驗證會返回各個取值的結果和最好的結果
estimator = GridSearchCV(estimator,param_grid=param_dict,cv=5)  # 返回優化後的估計器
# 3> 傳入訓練集,進行機器學習
estimator.fit(x_train,y_train)

# 模型評估
# 方法一:比較真實值與預測值
y_predict=estimator.predict(x_test)
print("預測值為:\n",y_predict)
print("比較真實值與預測值結果為:\n",y_predict==y_test)
# 方法二:計算模型準確率
print("模型準確率為:\n",estimator.score(x_test,y_test))
print("在交叉驗證中最的結果:\n",estimator.best_score_)
print("最好的引數模型:\n",estimator.best_estimator_)
print("每次交叉驗證後的結果準確率為/n",estimator.cv_results_)