Sklearn パイプライン(Pipeline)

機械学習プロジェクトでは、データ処理、特徴量エンジニアリング、モデルトレーニング、評価などのステップは互いに依存し合うことがよくあります。これらのステップの順序と調整は、最終モデルの性能にとって非常に重要です。

Pipelineは、scikit-learnにおいてこれらのステップを整理・簡素化するための重要なツールです。

Pipelineを使用すると、データ前処理とモデルトレーニングを統合できるため、ワークフローを簡素化し、コードの再利用性を高めることができます。

Pipelineとは

Pipelineは、複数のデータ処理ステップとモデルトレーニングステップを順番に実行できるツールです。

Pipelineでは、各ステップはタプルであり、名前とオブジェクトを含みます。

各オブジェクトは通常、変換器(Transformer)または推定器(Estimator)であり、そのうち:

  • 変換器(Transformer)データ変換を実行するオブジェクトです。例えば、データ前処理(正規化、標準化、特徴量選択など)です。
  • 推定器(Estimator)モデルのトレーニングに使用されるオブジェクトです。例えば、分類器や回帰器です。

Pipeline複数のステップを再利用可能なワークフローに統合することが簡単になり、データ処理プロセスの一貫性を確保し、コードの重複や手動処理によるエラーを防ぐことができます。

なぜPipelineを使うのか

  • コードの簡素化:複数のステップを1つの全体にまとめ、コード構造と管理を簡素化します。
  • データ漏洩の回避:データ前処理時に、トレーニングセットとテストセットの処理が分離されていることを保証し、データ漏洩を防ぎます。例えば、標準化操作では、テストセット上で平均と標準偏差を計算してはいけません。
  • 重複作業の削減:を通じてPipelineデータ前処理とモデルトレーニングプロセスを結び付け、毎回のトレーニングで前処理コードを繰り返し書くことを避けることができます。
  • 再利用性の向上:データ処理とモデルトレーニングを1つのPipelineオブジェクトにカプセル化し、異なるプロジェクトやデータセットで再利用できます。
  • チューニングが容易:を通じてPipelineチューニング時にハイパーパラメータ最適化や交差検証などを直接適用でき、プロセス全体を簡素化できます。

Pipelineの構成要素

Pipelineは複数のステップ(step)から構成され、各ステップは2つの要素を含むタプルです:

  1. ステップ名(文字列型):各ステップを識別するために使用されます。
  2. 変換器または推定器:データ処理またはモデリングに使用されるオブジェクト。

一般的なステップには以下が含まれます:

  • データ前処理ステップ:データクリーニング、標準化、エンコーディングなど。
  • モデルトレーニングステップ:分類器、回帰器など。

簡単なPipelineを作成する

データセットがあり、データを標準化した後にサポートベクターマシン(SVM)分類器をトレーニングする必要があるとします。標準化とモデルトレーニングのステップをパイプライン(Pipeline)に組み合わせることができます。

例

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

# データを読み込む
data = load_iris()
X, y = data.data, data.target

# データセットをトレーニングセットとテストセットに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Pipelineを作成する
pipeline = Pipeline([
    ('scaler', StandardScaler()),  # データの標準化
    ('svc', SVC())  # サポートベクターマシン分類器
])

# モデルをトレーニングする
pipeline.fit(X_train, y_train)

# 結果を予測する
y_pred = pipeline.predict(X_test)

# モデルの精度を出力する
print(f"Model accuracy: {pipeline.score(X_test, y_test)}")

上記のコードを実行すると、出力は次のようになります:

Model accuracy: 1.0

Pipelineの動作原理

上記の例では、Pipelineは2つのステップを実行しました:

  1. データの標準化(によってStandardScaler()):データを標準化処理し、各特徴が平均0と分散1を持つようにします。
  2. モデルトレーニング(によってSVC()):標準化されたデータ上でサポートベクターマシン分類器をトレーニングします。

Pipelineのワークフローは次のとおりです:まずデータ前処理ステップ(標準化など)を実行し、次に処理済みデータをモデルに渡してトレーニングします。このプロセスはpipeline.fit()ワンステップで完了します、pipeline.predict()予測時には、データも同じ順序でパイプラインの各ステップを通過します。


Pipelineの利点

コードとプロセスの簡素化

Pipelineを使用すると、複数のステップを1つのオブジェクトに統合できるため、複数のステップを手動で実行するコードが減ります。

使用しない場合は、前処理を複数回実行する必要があります:

例

# Without Pipeline (前処理を複数回実行する必要がある)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

model = SVC()
model.fit(X_train_scaled, y_train)
y_pred = model.predict(X_test_scaled)

Pipelineを使用すると、ワンステップで完了します:

例

# With Pipeline (ワンステップで完了)
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('svc', SVC())
])

pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

トレーニングとテストのデータ処理の一貫性を保証する

Pipelineがない場合、手動でデータ処理とトレーニングを行うと、トレーニングセットとテストセットに異なる処理方法を誤って使用し、データ漏洩を引き起こす可能性があります。

例えば、トレーニングセットで標準化の平均と分散を計算したのに、テストセットで異なる平均と分散を計算してしまうと、モデルの評価が不正確になります。Pipelineを使用することで、これらの処理方法の一貫性を確保できます。

プロセス全体の自動化

Pipelineを使用すると、複数のステップを1つのオブジェクトにカプセル化し、データ前処理、モデルトレーニング、予測のプロセス全体を自動化できます。この自動化されたフローにより、人為的エラーを減らし、コードの再利用性を高めることができます。


Pipelineのチューニングと最適化

Pipelineを使用する場合、直接ハイパーパラメータのチューニングを行うことができます。

GridSearchCVまたはRandomizedSearchCVと組み合わせることで、パイプライン内の各ステップのハイパーパラメータを最適化できます。

GridSearchCVを使用してPipelineのハイパーパラメータをチューニングする:

例

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV


# データを読み込む
data = load_iris()
X, y = data.data, data.target

# データセットをトレーニングセットとテストセットに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Pipelineを作成する
pipeline = Pipeline([
    ('scaler', StandardScaler()),  # データの標準化
    ('svc', SVC())  # サポートベクターマシン分類器
])

# モデルをトレーニングする
pipeline.fit(X_train, y_train)

# ハイパーパラメータのグリッドを定義する
param_grid = {
    'svc__C': [0.1, 1, 10],  # SVCのCパラメータを調整する
    'svc__kernel': ['linear', 'rbf']  # kernelパラメータを調整する
}

# GridSearchCVオブジェクトを作成する
grid_search = GridSearchCV(pipeline, param_grid, cv=5)

# ハイパーパラメータのチューニングを実行する
grid_search.fit(X_train, y_train)

# 最適なパラメータとスコアを出力する
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best score: {grid_search.best_score_}")
<

strong>説明:

  • svc__Cとsvc__kernelであるPipeline 中 SVCステップのハイパーパラメータ。〜内で指定するGridSearchCVこれらのパラメータを指定することで、直接Pipeline内のモデルのハイパーパラメータをチューニングできます。
  • cv=55分割交差検証を表します。

出力結果は次のとおりです:

Best parameters: {'svc__C': 0.1, 'svc__kernel': 'linear'}
Best score: 0.9583333333333334

Pipelineを使用した交差検証

Pipelineと交差検証を組み合わせることで、モデル評価プロセス全体が一貫していることを保証できます。交差検証では、各イテレーションでトレーニングデータを前処理し、その後モデルをトレーニングして検証します。

例

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score


# データを読み込む
data = load_iris()
X, y = data.data, data.target

# データセットをトレーニングセットとテストセットに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Pipelineを作成する
pipeline = Pipeline([
    ('scaler', StandardScaler()),  # データの標準化
    ('svc', SVC())  # サポートベクターマシン分類器
])

# モデルをトレーニングする
pipeline.fit(X_train, y_train)

# 5分割交差検証を実行する
cv_scores = cross_val_score(pipeline, X, y, cv=5)

# 交差検証スコアを出力する
print(f"Cross-validation scores: {cv_scores}")
print(f"Mean cross-validation score: {cv_scores.mean()}")

この例では、cross_val_scoreが自動的にデータの交差検証を行い、各トレーニング前にデータを標準化します。

出力結果は次のとおりです:

Cross-validation scores: [0.96666667 0.96666667 0.96666667 0.93333333 1.        ]
Mean cross-validation score: 0.9666666666666666
その他の拡張