パイプラインの構築
Overview
機械学習アプリケーションでは、1つのアルゴリズムを実行するだけでなく、様々な処理と複数の機械学習アルゴリズムを連鎖的に実行する必要があります。パイプラインを構築すると、すべての処理ステップを一度に行うことができます。
Theory
まずは、パイプライン構築しない例をみてみます。
code: Python
from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
# データをロードして分類
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
# 訓練データの最小値と最大値を計算
scaler = MinMaxScaler().fit(X_train)
# 訓練データをスケール変換
X_train_scaled = scaler.transform(X_train)
svm = SVC()
# SVMをスケール変換したデータで訓練
svm.fit(X_train_scaled, y_train)
# テストデータをスケール変換して、それを用いて評価
X_test_scaled = scaler.transform(X_test)
print('Test score: {:.2f}'.format(svm.score(X_test_scaled, y_test)))
--------------------------------------------------------------------------
Test score: 0.95
--------------------------------------------------------------------------
さらに、GridSearchCVを用いてSVCのより良いパラメータを求めることを考えてみます。
code: Python
from sklearn.model_selection import GridSearchCV
param_grid = {'C': 0.001, 0.01, 0.1, 1, 10, 100, 'gamma': 0.001, 0.01, 0.1, 1, 10, 100} grid = GridSearchCV(SVC(), param_grid=param_grid, cv=5)
grid.fit(X_train_scaled, y_train)
print('Best cross-validation accuracy: {:.2f}'.format(grid.best_score_))
print('Test set score: {:.2f}'.format(grid.score(X_test_scaled, y_test)))
print('Best parameters: ', grid.best_params_)
--------------------------------------------------------------------------
Best cross-validation accuracy: 0.98
Best set score: 0.97
Best parameters: {'C': 1, 'gamma': 1}
--------------------------------------------------------------------------
この実装には問題があります。交差検証の過程では、分割されたデータの一部をテストデータに使用しますが、このテストデータはスケール変換する際に既に学習されています。データの正しいスケールを決めるために、訓練データセット全体の情報を使っているためです(訓練セットでfitしたものをテストセットにtransformしている)。これはまったく新しいデータとは本質的に異なります。
https://gyazo.com/213dab7abd972d8d2c44577b5fd68ee0
この問題を回避するには、前処理をする前に交差検証のためのデータ分割を行う必要があります。これを実現するために、scikit-learnではcross_val_score関数とGridSearchCV関数にPipelineクラスを使うことができます。Pipelineクラスには、fit、predict、scoreメソッドがあり、ほかのモデルと同様に振舞います。Pipelineクラスは、前処理ステップと、クラス分類器などの教師あり学習モデルを組み合わせるためによく使われます。
Coding
Pipelineクラスを用いて、MinMaxScalerによるスケール変換を行ってからSVMを訓練する
code: Python
from sklearn.pipeline import Pipeline
# 各ステップをリストに格納する
# 個々のステップは名前と一緒にタプルに格納する
pipe.fit(X_train, y_train)
print('Test score: {:.2f}'.format(pipe.score(X_test, y_test)))
--------------------------------------------------------------------------
Test score: 0.95
--------------------------------------------------------------------------