標籤:分布 form 降維 red transform 步驟 模型訓練 tween 輸入
在做資料處理時,需要用到不同的手法,如特徵標準化,主成分分析,等等會重複用到某些參數,sklearn中提供了管道,可以一次性的解決該問題
先展示先通常的做法
import pandas as pdfrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAfrom sklearn.linear_model import LogisticRegressiondf = pd.read_csv(‘wdbc.csv‘)X = df.iloc[:, 2:].valuesy = df.iloc[:, 1].values# 標準化sc = StandardScaler()X_train_std = sc.fit_transform(X_train)X_test_std = sc.transform(X_test)# 主成分分析PCApca = PCA(n_components=2)X_train_pca = pca.fit_transform(X_train_std)X_test_pca = pca.transform(X_test_std)# 邏輯斯蒂迴歸預測lr = LogisticRegression(random_state=1)lr.fit(X_train_pca, y_train)y_pred = lr.predict(X_test_pca)
先對資料標準化,然後做主成分分析降維,最後做迴歸預測
現在使用管道
from sklearn.pipeline import Pipelinepipe_lr = Pipeline([(‘sc‘, StandardScaler()), (‘pca‘, PCA(n_components=2)), (‘lr‘, LogisticRegression(random_state=1))])pipe_lr.fit(X_train, y_train)pipe_lr.score(X_test, y_test)
Pipeline對象接收元組構成的列表作為輸入,每個元組第一個值作為變數名,元組第二個元素是sklearn中的transformer或Estimator。
管道中間每一步由sklearn中的transformer構成,最後一步是一個Estimator。我們的例子中,管道包含兩個中間步驟,一個StandardScaler和一個PCA,這倆都是transformer,邏輯斯蒂迴歸分類器是Estimator。
當管道pipe_lr執行fit方法時,首先StandardScaler執行fit和transform方法,然後將轉換後的資料輸入給PCA,PCA同樣執行fit和transform方法,最後將資料輸入給LogisticRegression,訓練一個LR模型。
對於管道來說,中間有多少個transformer都可以。工作方式如下
使用管道減少了很多代碼量
現在迴歸模型的評估和調參
訓練機器學習模型的關鍵一步是要評估模型的泛化能力。如果我們訓練好模型後,還是用訓練集取評估模型的效能,這顯然是不符合邏輯的。一個模型如果效能不好,要麼是因為模型過於複雜導致過擬合(高方差),要麼是模型過於簡單導致導致欠擬合(高偏差)。可是用什麼方法評價模型的效能呢?這就是這一節要解決的問題,你會學習到兩種交叉驗證計數,holdout交叉驗證和k折交叉驗證, 來評估模型的泛化能力
一、holdout交叉驗證(評估模型效能)
holdout方法很簡單就是將資料集分為訓練集和測試集,前者用於訓練,後者用於評估
如果在模型選擇的過程中,我們始終用測試集來評價模型效能,這實際上也將測試集變相地轉為了訓練集,這時候選擇的最優模型很可能是過擬合的。
更好的holdout方法是將原始訓練集分為三部分:訓練集、驗證集和測試集。訓練機用於訓練不同的模型,驗證集用於模型選擇。而測試集由於在訓練模型和模型選擇這兩步都沒有用到,對於模型來說是未知資料,因此可以用於評估模型的泛化能力。展示了holdout方法的步驟:
缺點:它對資料分割的方式很敏感,如果未經處理資料集分割不當,這包括訓練集、驗證集和測試集的樣本數比例,以及分割後資料的分布情況是否和未經處理資料集分布情況相同等等。所以,不同的分割方式可能得到不同的最優模型參數
二、K折交叉驗證(評估模型效能)
k折交叉驗證的過程,第一步我們使用不重複抽樣將未經處理資料隨機分為k份,第二步 k-1份資料用於模型訓練,剩下那一份資料用於測試模型。然後重複第二步k次,我們就得到了k個模型和他的評估結果(譯者註:為了減小由於資料分割引入的誤差,通常k折交叉驗證要隨機使用不同的劃分方法重複p次,常見的有10次10折交叉驗證)
然後我們計算k折交叉驗證結果的平均值作為參數/模型的效能評估。使用k折交叉驗證來尋找最優參數要比holdout方法更穩定。一旦我們找到最優參數,要使用這組參數在未經處理資料集上訓練模型作為最終的模型。
k折交叉驗證使用不重複採樣,優點是每個樣本只會在訓練集或測試中出現一次,這樣得到的模型評估結果有更低的方法。
示範了10折交叉驗證:
10次10折交叉驗證我的理解是將按十種劃分方法,每次將資料隨機分成k分,k-1份訓練,k份測試。擷取十個模型和評估結果,然後取10次的平均值作為效能評估
from sklearn.cross_validation import StratifiedKFold
pipe_lr = Pipeline([(‘sc‘, StandardScaler()), (‘pca‘, PCA(n_components=2)), (‘lr‘, LogisticRegression(random_state=1))]) pipe_lr.fit(X_train, y_train) kfold = StratifiedKFold(y=y_train, n_folds=10, random_state=1) scores= [] for k, (train, test) in enumerate(kfold): pipe_lr.fit(X_train[train], y_train[train]) score = pipe_lr.score(X_train[test], y_train[test]) scores.append(scores) print(‘Fold: %s, Class dist.: %s, Acc: %.3f‘ %(k+1, np.bincount(y_train[train]), score))print(‘CV accuracy: %.3f +/- %.3f‘ %(np.mean(scores), np.std(scores)))
更簡單的方法
from sklearn.cross_validation import StratifiedKFold pipe_lr = Pipeline([(‘sc‘, StandardScaler()), (‘pca‘, PCA(n_components=2)), (‘lr‘, LogisticRegression(random_state=1))]) pipe_lr.fit(X_train, y_train) scores = cross_val_score(estimator=pipe_lr, X=X_train, y=y_train, cv=10, n_jobs=1) print(‘CV accuracy scores: %s‘ %scores) print(‘CV accuracy: %.3f +/- %.3f‘ %(np.mean(scores), np.std(scores)))
cv即k
三、學習曲線(調試演算法)
from sklearn.learning_curve import learning_curve pipe_lr = Pipeline([(‘scl‘, StandardScaler()), (‘clf‘, LogisticRegression(penalty=‘l2‘, random_state=0))]) train_sizes, train_scores, test_scores = learning_curve(estimator=pipe_lr, X=X_train, y=y_train, train_sizes=np.linspace(0.1, 1.0, 10), cv=10, n_jobs=1) train_mean = np.mean(train_scores, axis=1) train_std = np.std(train_scores, axis=1) test_mean = np.mean(test_scores, axis=1) test_std = np.std(test_scores, axis=1) plt.plot(train_sizes, train_mean, color=‘blue‘, marker=‘0‘, markersize=5, label=‘training accuracy‘) plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color=‘blue‘) plt.plot(train_sizes, test_mean, color=‘green‘, linestyle=‘--‘, marker=‘s‘, markersize=5, label=‘validation accuracy‘) plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color=‘green‘) plt.grid() plt.xlabel(‘Number of training samples‘) plt.ylabel(‘Accuracy‘) plt.legend(loc=‘lower right‘) plt.ylim([0.8, 1.0]) plt.show()
python 機器學習中模型評估和調參