MLPRegressorを使いこなす!Scikit-learnでニューラルネットワーク回帰モデルを構築する方法

Python

「線形回帰を使ってみたけれど、どうも予測精度が上がらない…」 データ分析における「回帰問題」で、このような壁にぶつかった経験はありませんか?その原因は、データが持つ複雑な非線形性を、モデルが捉えきれていないことにあるかもしれません。

この記事では、その壁を打ち破る強力な一手として、PythonのScikit-learnライブラリに含まれる**MLPRegressor**を使いこなす方法を徹底的に解説します。

MLPRegressorはニューラルネットワークを利用した回帰モデルであり、複雑なデータパターンからでも高精度な予測を実現するポテンシャルを秘めています。

この記事を読み終える頃には、あなたは以下のスキルを身につけているはずです。

  • MLPRegressorの仕組みと、なぜそれが強力なのかを理解できる
  • モデル構築から評価までの一連のプロセスを自分で実装できる
  • モデルの性能を最大限に引き出すためのハイパーパラメータ調整の勘所がわかる

はじめに:なぜ今、MLPRegressorなのか?

MLPRegressorを使いこなす第一歩として、まずその強力な理由と利便性を理解しましょう。

線形モデルの限界を超える非線形性への対応

MLPRegressorの最大の強みは、多層パーセプトロン(Multi-layer Perceptron) というニューラルネットワーク構造により、入力と出力の間の複雑な非線形関係を学習できる点にあります。

例えば、単純な比例関係だけでなく、「ある値までは増加するが、それを超えると減少に転じる」といった複雑なパターンも捉えることが可能です。これにより、従来の線形モデルでは難しかった高精度な予測が期待できます。

Scikit-learnで始めるニューラルネットワークの手軽さ

通常、ニューラルネットワークは専門的なライブラリ(TensorFlowやPyTorchなど)を必要としますが、Scikit-learnを使えば、他の機械学習モデルと全く同じ手軽さでニューラルネットワークを導入できます。

この手軽さが、MLPRegressorを「使いこなす」ための最初の武器となります。複雑な理論の前に、まずは実践から入ることができるのです。

MLPRegressor実装の3ステップ

MLPRegressorの基本的な実装は、たった3つのステップで完了します。ここでは、各ステップの要点とコード例を見ていきましょう。

Step 1: データの準備と最重要ポイント「標準化」

これは最も重要なステップです。MLPRegressorは、各特徴量のスケール(大きさの範囲)が大きく異なると、学習が非効率になったり、うまく収束しなかったりします。そのため、学習前には必ず**データの前処理(特に標準化)**を行いましょう。

標準化とは、データ平均を0、標準偏差を1に変換する処理で、StandardScalerを使えば簡単に実装できます。

import numpy as np
from sklearn.preprocessing import StandardScaler

# サンプルデータ
X = np.array([[10, 1], [20, 2], [100, 5], [110, 6]])
y = np.array([1, 2, 5, 6])

# スケーラーのインスタンスを作成
scaler = StandardScaler()

# スケーラーにデータを学習させ、変換を適用
X_scaled = scaler.fit_transform(X)

print("標準化前のデータ:\n", X)
print("標準化後のデータ:\n", X_scaled)

Step 2: モデルの学習 (fit) と予測 (predict)

データが準備できたら、いよいよモデルの学習です。Scikit-learnのお作法通り、fit()メソッドで学習し、predict()メソッドで予測します。

from sklearn.neural_network import MLPRegressor

# MLPRegressorのインスタンスを作成
# random_stateで結果を固定、max_iterで学習回数を増やす
model = MLPRegressor(random_state=1, max_iter=1000)

# 標準化されたデータでモデルを学習
model.fit(X_scaled, y)

# 新しいデータを予測する場合も、必ず同じスケーラーで標準化する
new_data = np.array([[50, 3]])
new_data_scaled = scaler.transform(new_data)

# 予測を実行
prediction = model.predict(new_data_scaled)
print(f"新しいデータ {new_data[0]} の予測値: {prediction[0]}")

Step 3: モデル性能の評価 (score)

モデルがどれだけ優れているかは、score()メソッドで評価できます。このメソッドは決定係数(R2)を返し、1に近いほど良いモデルとされます。

# 学習データに対するスコアを評価
score = model.score(X_scaled, y)
print(f"モデルのスコア (R^2): {score:.4f}")

モデルを使いこなすためのハイパーパラメータ調整

基本的な実装は簡単ですが、MLPRegressorを**「使いこなす」**ためには、ハイパーパラメータの調整が不可欠です。ここでは、特に重要なものをピックアップして解説します。

hidden_layer_sizes: モデルの表現力を決める心臓部

モデルの複雑さを直接コントロールする、最も重要なパラメータです。 タプル形式で(ニューロン数, ニューロン数, ...)と指定し、タプルの要素数が隠れ層の数、各数値がその層のニューロン数を意味します。

  • (100,): 隠れ層1層、ニューロン100個(デフォルト)
  • (64, 32): 隠れ層2層、1層目に64個、2層目に32個のニューロン

使いこなしのヒント: 最初は1〜2層で試し、ニューロン数を調整してみましょう。モデルが複雑すぎると過学習(学習データにだけ適合しすぎる状態)の原因になるため、闇雲に増やすのは禁物です。

activation: ニューロンの個性を決める活性化関数

各ニューロンがどのように活性化(発火)するかを決める関数です。

  • 'relu': 現在最も広く使われている標準的な選択肢。ほとんどの場合、これで良好な結果が得られます(デフォルト)。
  • 'tanh': -1から1の範囲で出力する関数。
  • 'logistic': 0から1の範囲で出力するシグモイド関数。

使いこなしのヒント: まずは'relu'で試し、性能が頭打ちになったら他の関数を試す、というアプローチが効率的です。

solver: 効率的な学習を実現する最適化手法

学習プロセスで、どのようにモデルの重みを最適化していくかのアルゴリズムです。

  • 'adam': 汎用性が高く、多くのケースで効率的に学習が進むため、第一選択肢となります(デフォルト)。
  • 'lbfgs': データセットが小さい場合に性能が良いことがあります。
  • 'sgd': 確率的勾配降下法。学習率などの調整がシビアになることがあります。

使いこなしのヒント: データセットのサイズに関わらず、まずは'adam'を試すのが定石です。学習がうまく収束しない場合に他の選択肢を検討しましょう。

alphaとmax_iter: 過学習防止と学習回数のコントロール

  • alpha: 過学習を抑制するための正則化の強さを指定します。値が大きいほどモデルはシンプルになります(デフォルト: 0.0001)。
  • max_iter: 学習の最大エポック(繰り返し)数です。学習が収束しきる前に終了してしまう場合(ConvergenceWarningが出る場合)は、この値を増やします(デフォルト: 200)。

実践:カリフォルニア住宅価格データでモデルを構築

それでは、より実践的なデータセットを使い、ハイパーパラメータを調整しながらモデルを構築してみましょう。 (※ scikit-learn 1.2以降、Boston住宅価格データは非推奨となったため、ここではカリフォルニア住宅価格データを使用します。)

データセットの読み込みから前処理まで

from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split

# データセットのロード
housing = fetch_california_housing()
X, y = housing.data, housing.target

# 学習用とテスト用にデータを分割
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

# ★重要★ 標準化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

ハイパーパラメータを設定して学習

これまで学んだ知識を元に、ハイパーパラメータを設定してモデルを構築します。

# ハイパーパラメータを調整してモデルをインスタンス化
final_model = MLPRegressor(hidden_layer_sizes=(100, 50), # 2層のネットワーク
                           activation='relu',
                           solver='adam',
                           alpha=0.001,
                           max_iter=1000,
                           random_state=1)

# 学習の実行
final_model.fit(X_train_scaled, y_train)

予測精度を評価し、結果を可視化する

最後に、未知のデータであるテストデータに対してモデルの性能を評価し、結果を可視化して確認します。

import matplotlib.pyplot as plt

# テストデータでスコアを評価
test_score = final_model.score(X_test_scaled, y_test)
print(f"テストデータに対するスコア (R^2): {test_score:.4f}")

# 予測値を計算
y_pred = final_model.predict(X_test_scaled)

# 結果の可視化
plt.figure(figsize=(8, 8))
plt.scatter(y_test, y_pred, alpha=0.3)
plt.xlabel("実際の価格 (Actual Price)")
plt.ylabel("予測価格 (Predicted Price)")
plt.title("MLPRegressorによる予測結果")
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--')
plt.grid(True)
plt.show()

散布図で点が赤い対角線上に集まっていれば、モデルが良い予測ができていることを示しています。

まとめ:MLPRegressorを使いこなすために

今回は、Scikit-learnMLPRegressorを使いこなし、ニューラルネットワーク回帰モデルを構築する方法を解説しました。

使いこなしのための重要ポイントを再確認しましょう。

  1. データの前処理、特に「標準化」を絶対に忘れないこと。 これがモデル性能の土台となります。
  2. hidden_layer_sizesがモデルの表現力を決める。 データに合わせて層の数やニューロン数を調整することが精度向上の鍵です。
  3. まずはactivation='relu', solver='adam'から試す。 これらは多くの場合で堅実な性能を発揮します。
  4. 警告メッセージ(ConvergenceWarning)に注意する。 もし出たらmax_iterを増やすことを検討しましょう。

MLPRegressorは、線形モデルでは太刀打ちできない複雑なデータに対処するための強力なツールです。この記事を参考に、ぜひあなたの回帰問題にニューラルネットワークの力を活用してみてください。

コメント

タイトルとURLをコピーしました