1.錯誤類型
機器學習中常犯的兩個錯誤是,過於簡化模型,過於複雜化模型
2.交叉驗證
之前將數據分爲訓練集和測試集,判定模型效果,實際上犯了一個錯誤,將測試集參與了模型判定。
爲更客觀的反映模型效果,引入一個新的子集,交叉驗證集。
一般複雜模型如下圖,訓練誤差越來越小,測試誤差開始很大,然後逐漸減小,然後再逐漸變大。
左側欠擬合,右側過擬合。
3. K 折交叉驗證
將數據分成K份,然後訓練模型K次,每次輪流取不同的幾分數據作爲測試集,剩餘數據作爲訓練集,然後對結果取平均,得到最終的模型。
從SKLearn庫中調用K折交叉驗證很簡單,創建一個K折交叉驗證對象,其參數分別是數據的大小和測試集的大小,建議每次都隨機化數據,以消除任何偏差暗示,
4.學習曲線
以訓練數據樣本數爲橫軸,誤差爲縱軸,畫出訓練集和交叉驗證集的誤差曲線
在高偏差或欠擬合模型中,兩個曲線彼此逐漸靠近,收斂在高點;
好的模型中,兩個曲線彼此逐漸靠近,並且收斂在低點;
在高方差或過擬合模型中,兩個曲線不會彼此靠近,訓練誤差曲線保持在低位,而交叉驗證誤差曲線保持在高位;
這是區分欠擬合和過擬合的一種方法;
通過學習曲線檢測過擬合和欠擬合實例
做個測驗,我們將使用三個模型來訓練下面的圓形數據集。
決策樹模型,
邏輯迴歸模型,
支持向量機模型。
其中一個模型會過擬合,一個欠擬合,還有一個正常。首先,我們將編寫代碼爲每個模型繪製學習曲線,最後我們將查看這些學習曲線,判斷每個模型對應哪個曲線。
我們將使用函數 learning_curve:
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=None, n_jobs=1, train_sizes=np.linspace(.1, 1.0, num_trainings))
不需要擔心該函數的所有參數(你可以在此處瞭解詳情),這裏,我們將解釋主要參數:
estimator,是我們針對數據使用的實際分類器,例如 LogisticRegression() 或 GradientBoostingClassifier()。
X 和 y 是我們的數據,分別表示特徵和標籤。
train_sizes 是用來在曲線上繪製每個點的數據大小。
train_scores 是針對每組數據進行訓練後的算法訓練得分。
test_scores 是針對每組數據進行訓練後的算法測試得分。
兩個重要的現象:
a.訓練和測試得分是一個包含 3 個值的列表,這是因爲函數使用了 3 折交叉驗證。
b.非常重要:可以看出,我們使用訓練和測試誤差來定義我們的曲線,而這個函數使用訓練和測試得分來定義曲線。二者是相反的,因此誤差越高,得分就越低。因此,當你看到曲線時,你需要自己在腦中將它顛倒過來,以便與上面的曲線對比。
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import learning_curve
# It is good to randomize the data before drawing Learning Curves
def randomize(X, Y):
permutation = np.random.permutation(Y.shape[0])
X2 = X[permutation,:]
Y2 = Y[permutation]
return X2, Y2
def draw_learning_curves(X, y, estimator, num_trainings,estimator_name):
train_sizes, train_scores, test_scores = learning_curve(
estimator, X2, y2, cv=None, n_jobs=1, train_sizes=np.linspace(.1, 1.0, num_trainings))
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.grid()
plt.title("Learning Curves")
plt.xlabel("Training examples_"+estimator_name)
plt.ylabel("Score")
plt.plot(train_scores_mean, 'o-', color="g",
label="Training score")
plt.plot(test_scores_mean, 'o-', color="y",
label="Cross-validation score")
plt.legend(loc="best")
plt.savefig("./"+estimator_name+".png")
plt.show()
# Import, read, and split data
import pandas as pd
data = pd.read_csv('data.csv')
import numpy as np
X = np.array(data[['x1', 'x2']])
y = np.array(data['y'])
# Fix random seed
np.random.seed(55)
### Imports
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.svm import SVC
# TODO: Uncomment one of the three classifiers, and hit "Test Run"
# to see the learning curve. Use these to answer the quiz below.
### Logistic Regression
#estimator = LogisticRegression()
#estimator_name = "LogisticRegression"
### Decision Tree
#estimator = GradientBoostingClassifier()
#estimator_name = "GradientBoostingClassifier"
### Support Vector Machine
estimator = SVC(kernel='rbf', gamma=1000)
estimator_name = "SVC"
num_trainings = len(y)/10
print(len(y),num_trainings)
X2, y2 = randomize(X, y)
draw_learning_curves( X, y,estimator,num_trainings,estimator_name)
100 10.0
分別獲得曲線:
我們可以根據這些曲線得出結論:
對數機率迴歸模型的訓練和測試得分很低。
決策樹模型的訓練和測試得分很高。
支持向量機模型的訓練得分很高,測試得分很低。
。
同樣,我們可以翻轉這些曲線(因爲它們測量的是得分,而原始曲線測量的是錯誤),並將它們與下面的三條曲線對比,可以看出它們與我們之前看到的三條曲線很像。(注意:我們需要翻轉曲線並不意味着錯誤是 1 減去得分。只是表示模型越來越好的話,錯誤會降低,得分會升高。)
現在我們應該檢測在實際模型中是否這樣。當我們繪製每個模型的界限曲線時,結果如下所示:
當我們查看上述模型時,第一個模型欠擬合,第二個正常,第三個過擬合,這種現象合理嗎?合理吧?我們看到數據由圓圈或方框正確地劃分出來。我們的模型按以下形式劃分數據:
邏輯迴歸模型使用一條直線,這太簡單了。在訓練集上的效果不太好,因此欠擬合。
決策樹模型使用一個方形,擬合的很好,並能夠泛化。因此,該模型效果很好。
支持向量機模型實際上在每個點周圍都畫了一個小圓圈。它實際上是在記住訓練集,無法泛化。因此 過擬合。
最好儘可能進行實際檢查,確保模型的確具有指標所指示的行爲。
5.網格搜索
總結一下機器學習過程:
首先用訓練集訓練一些模型,然後利用交叉驗證集數據在其中選擇一個最好的模型,最後利用測試數據進行檢測來保證這個模型是最好的。
這是一個訓練邏輯迴歸的例子:
它是一條直線,一個二階、三階和四階模型,用訓練集數據來訓練這個多項式的斜率和係數參數等,用交叉驗證集數據來計算F1分數值
然後選擇F1分數最高的模型,最後使用測試數據來確保所選模型是最好的.
同理,看另外一個例子,訓練決策樹,它的超參數是,深度
如果有多個超參數,比如訓練支持向量機,如何在覈參數和C參數之間選擇最佳組合呢?
用網格搜索,做一張有各種可能性的表格,用訓練集數據訓練模型,然後用交叉驗證集計算,選擇F1分數最高值。
6.在sklearn中的網格搜索
假設我們想要訓練支持向量機,並且我們想在以下參數之間做出決定:
kernel:poly或rbf。
C:0.1,1 或 10。
6.1 導入 GridSearchCV
from sklearn.model_selection import GridSearchCV
6.2 選擇參數:
現在我們來選擇我們想要選擇的參數,並形成一個字典。 在這本字典中,鍵 (keys) 將是參數的名稱,值 (values) 將是每個參數可能值的列表。
parameters = {'kernel':['poly', 'rbf'],'C':[0.1, 1, 10]}
6.3 創建一個評分機制 (scorer)
我們需要確認將使用什麼指標來爲每個候選模型評分。 這裏,我們將使用 F1 分數。
from sklearn.metrics import make_scorer
from sklearn.metrics import f1_score
scorer = make_scorer(f1_score)
6.4 使用參數 (parameter) 和評分機制 (scorer) 創建一個 GridSearch 對象。 使用此對象與數據保持一致 (fit the data) 。
# Create the object.
grid_obj = GridSearchCV(clf, parameters, scoring=scorer)
# Fit the data
grid_fit = grid_obj.fit(X, y)
6.5 獲得最佳估算器 (estimator)
best_clf = grid_fit.best_estimator_
現在可以使用這一估算器best_clf來做出預測。
實例參考