天天看點

機器學習交叉驗證和網格搜尋案例分析

目錄

  • ​​1 什麼是交叉驗證(cross validation)​​
  • ​​1.1 分析​​
  • ​​1.2 為什麼需要交叉驗證​​
  • ​​2 什麼是網格搜尋(Grid Search)​​
  • ​​3 交叉驗證-網格搜尋API:​​
  • ​​4 鸢尾花案例增加K值調優​​
  • ​​5 Facebook簽到的位置預測​​
  • ​​5.1 資料集介紹​​
  • ​​5.2 步驟分析​​
  • ​​5.3 代碼實作​​
  • ​​6 總結​​

1 什麼是交叉驗證(cross validation)

交叉驗證:将拿到的訓練資料,分為訓練和驗證集。以下圖為例:将資料分成4份,其中一份作為驗證集。然後經過4次(組)的測試,每次都更換不同的驗證集。即得到4組模型的結果,取平均值作為最終結果。又稱4折交叉驗證。

1.1 分析

我們之前知道資料分為訓練集和測試集,但是**為了讓從訓練得到模型結果更加準确。**做以下處理

  • 訓練集:訓練集+驗證集
  • 測試集:測試集
機器學習交叉驗證和網格搜尋案例分析

1.2 為什麼需要交叉驗證

交叉驗證目的:為了讓被評估的模型更加準确可信

問題:這個隻是讓被評估的模型更加準确可信,那麼怎麼選擇或者調優參數呢?

2 什麼是網格搜尋(Grid Search)

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

機器學習交叉驗證和網格搜尋案例分析

3 交叉驗證-網格搜尋API:

  • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
  • 解釋:對估計器的指定參數值進行詳盡搜尋
  • 參數:
  • estimator:估計器對象
  • param_grid:估計器參數(dict){“n_neighbors”:[1,3,5]}
  • cv:指定幾折交叉驗證
  • 方法:
  • fit:輸入訓練資料
  • score:準确率
  • 結果分析:
  • bestscore__:在交叉驗證中驗證的最好結果
  • bestestimator:最好的參數模型
  • cvresults:每次交叉驗證後的驗證集準确率結果和訓練集準确率結果

4 鸢尾花案例增加K值調優

  • 使用GridSearchCV建構估計器
# 1、擷取資料集
iris = load_iris()
# 2、資料基本處理 -- 劃分資料集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3、特征工程:标準化
# 執行個體化一個轉換器類
transfer = StandardScaler()
# 調用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4、KNN預估器流程
#  4.1 執行個體化預估器類
estimator = KNeighborsClassifier()

# 4.2 模型選擇與調優——網格搜尋和交叉驗證
# 準備要調的超參數
param_dict = {"n_neighbors": [1, 3, 5]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
# 4.3 fit資料進行訓練
estimator.fit(x_train, y_train)
# 5、評估模型效果
# 方法a:比對預測結果和真實值
y_predict = estimator.predict(x_test)
print("比對預測結果和真實值:\n", y_predict == y_test)
# 方法b:直接計算準确率
score = estimator.score(x_test, y_test)
print("直接計算準确率:\n", score)      
  • 然後進行評估檢視最終選擇的結果和交叉驗證的結果
print("在交叉驗證中驗證的最好結果:\n", estimator.best_score_)
print("最好的參數模型:\n", estimator.best_estimator_)
print("每次交叉驗證後的準确率結果:\n", estimator.cv_results_)      
  • 最終結果
比對預測結果和真實值:
 [ True  True  True  True  True  True  True False  True  True  True  True
  True  True  True  True  True  True False  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True]
直接計算準确率:
 0.947368421053
在交叉驗證中驗證的最好結果:
 0.973214285714
最好的參數模型:
 KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=5, p=2,
           weights='uniform')
每次交叉驗證後的準确率結果:
 {'mean_fit_time': array([ 0.00114751,  0.00027037,  0.00024462]), 'std_fit_time': array([  1.13901511e-03,   1.25300249e-05,   1.11011951e-05]), 'mean_score_time': array([ 0.00085751,  0.00048693,  0.00045625]), 'std_score_time': array([  3.52785082e-04,   2.87650037e-05,   5.29673344e-06]), 'param_n_neighbors': masked_array(data = [1 3 5],
             mask = [False False False],
       fill_value = ?)
, 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}], 'split0_test_score': array([ 0.97368421,  0.97368421,  0.97368421]), 'split1_test_score': array([ 0.97297297,  0.97297297,  0.97297297]), 'split2_test_score': array([ 0.94594595,  0.89189189,  0.97297297]), 'mean_test_score': array([ 0.96428571,  0.94642857,  0.97321429]), 'std_test_score': array([ 0.01288472,  0.03830641,  0.00033675]), 'rank_test_score': array([2, 3, 1], dtype=int32), 'split0_train_score': array([ 1.        ,  0.95945946,  0.97297297]), 'split1_train_score': array([ 1.        ,  0.96      ,  0.97333333]), 'split2_train_score': array([ 1.  ,  0.96,  0.96]), 'mean_train_score': array([ 1.        ,  0.95981982,  0.96876877]), 'std_train_score': array([ 0.        ,  0.00025481,  0.0062022 ])}      

5 Facebook簽到的位置預測

機器學習交叉驗證和網格搜尋案例分析
  • 本次比賽的目的是預測一個人将要簽到的地方。
  • 為了本次比賽,建立了一個虛拟世界,其中包括10公裡*10公裡共100平方公裡的約10萬個地方。
  • 對于給定的坐标集,您的任務将根據使用者的位置,準确性和時間戳等預測使用者下一次的簽到位置。
  • 資料被制作成類似于來自移動裝置的位置資料。
  • 請注意:您隻能使用提供的資料進行預測。

5.1 資料集介紹

資料介紹:

檔案說明 train.csv, test.csv
  row id:簽入事件的id
  x y:坐标
  accuracy: 準确度,定位精度
  time: 時間戳
  place_id:      

5.2 步驟分析

  • 對于資料做一些基本處理(這裡所做的一些處理不一定達到很好的效果,我們隻是簡單嘗試,有些特征我們可以根據一些特征選擇的方式去做處理)
  • 1 縮小資料集範圍 DataFrame.query()
  • 2 選取有用的時間特征
  • 3 将簽到位置少于n個使用者的删除
  • 分割資料集
  • 标準化處理
  • k-近鄰預測
具體步驟:
# 1.擷取資料集
# 2.基本資料處理
# 2.1 縮小資料範圍
# 2.2 選擇時間特征
# 2.3 去掉簽到較少的地方
# 2.4 确定特征值和目标值
# 2.5 分割資料集
# 3.特征工程 -- 特征預處理(标準化)
# 4.機器學習 -- knn+cv
# 5.模型評估      

5.3 代碼實作

  • 1.擷取資料集
# 1、擷取資料集
facebook = pd.read_csv("./data/FBlocation/train.csv")      
  • 2.基本資料處理
# 2.基本資料處理
# 2.1 縮小資料範圍
facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 選擇時間特征
time = pd.to_datetime(facebook_data["time"], unit="s")
time = pd.DatetimeIndex(time)
facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday
# 2.3 去掉簽到較少的地方
place_count = facebook_data.groupby("place_id").count()
place_count = place_count[place_count["row_id"]>3]
facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)]
# 2.4 确定特征值和目标值
x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
y = facebook_data["place_id"]
# 2.5 分割資料集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)      
  • 3.特征工程–特征預處理(标準化)
# 3.特征工程--特征預處理(标準化)
# 3.1 執行個體化一個轉換器
transfer = StandardScaler()
# 3.2 調用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)      
  • 4.機器學習–knn+cv
# 4.機器學習--knn+cv
# 4.1 執行個體化一個估計器
estimator = KNeighborsClassifier()
# 4.2 調用gridsearchCV
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
# 4.3 模型訓練
estimator.fit(x_train, y_train)      
  • 5.模型評估
# 5.模型評估
# 5.1 基本評估方式
score = estimator.score(x_test, y_test)
print("最後預測的準确率為:\n", score)

y_predict = estimator.predict(x_test)
print("最後的預測值為:\n", y_predict)
print("預測值和真實值的對比情況:\n", y_predict == y_test)

# 5.2 使用交叉驗證後的評估方式
print("在交叉驗證中驗證的最好結果:\n", estimator.best_score_)
print("最好的參數模型:\n", estimator.best_estimator_)
print("每次交叉驗證後的驗證集準确率結果和訓練集準确率結果:\n",estimator.cv_results_)      

6 總結

  • 交叉驗證【知道】
  • 定義:
  • 将拿到的訓練資料,分為訓練和驗證集
  • *折交叉驗證
  • 分割方式:
  • 訓練集:訓練集+驗證集
  • 測試集:測試集
  • 為什麼需要交叉驗證
  • 為了讓被評估的模型更加準确可信
  • 注意:交叉驗證不能提高模型的準确率
  • 網格搜尋【知道】
  • 超參數:
  • sklearn中,需要手動指定的參數,叫做超參數
  • 網格搜尋就是把這些超參數的值,通過字典的形式傳遞進去,然後進行選擇最優值
  • api【知道】
  • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
  • estimator – 選擇了哪個訓練模型
  • param_grid – 需要傳遞的超參數
  • cv – 幾折交叉驗證