多項式回帰

想像してみてください。物体が空中から落下する軌跡を観察しているとします。その落下速度は均一ではなく、どんどん速くなります。この軌跡を直線でフィッティングしようとすると、効果は非常に悪いでしょう。直線はこのような曲がった変化を表現できないからです。このような場合、曲がることができる線が必要になります——多項式回帰はこの種の問題を解決する強力なツールです。

簡単に言うと、多項式回帰は線形回帰の一種の拡張です。元の特徴に高次の項(平方項、立方項など)を追加することで、データをより高次元の空間にマッピングし、それによって「曲線」でデータに存在する非線形関係をフィッティングします。


一、 中核概念:直線から曲線へ

1.1 線形回帰の復習

線形回帰のモデル式は非常にシンプルです:y = w₁ * x + bここで:

  • yは予測したい目的値です。
  • xは入力特徴です。
  • w₁は特徴の重み(傾き)です。
  • bはバイアス項(切片)です。

このモデルが描けるのは一本の直線だけです。。

1.2 多項式回帰の導入

多項式回帰の中心的な考え方は:特徴の高次のべき乗を新しい特徴とみなすそして、この拡張された特徴セットに線形回帰を適用します。

例えば、2次多項式回帰モデル:y = w₁ * x + w₂ * x² + b

ご覧のとおり、方程式の中にはx²が現れていますが、これを私たちがxとx²2つの独立した特徴と見なすならX1とX2、モデルは次のようになります:y = w₁ * X1 + w₂ * X2 + bこれは本質的に依然として線形モデルですが、それが線形なのは特徴 X1とX2に関してです。これが、多項式回帰が「線形回帰の拡張」と呼ばれる理由です。

1.3 重要な用語

  • 次数:多項式の中で最も高い指数。次数が2なら2次曲線(放物線)、次数が3なら3次曲線、以下同様です。
  • 過学習:選択する次数が高すぎると、モデルは非常に「曲がりくねった」ものになり、すべての学習データ点を完璧に通過しますが、新しいデータに対する予測能力は急激に低下します。複雑な網で数個の点を捕まえようとするようなもので、網目が細かすぎると、逆に大きな魚は捕まえられません。
  • 未学習:次数が低すぎる場合(例えば、明らかに曲がったデータを直線でフィッティングする場合)、モデルはデータの基本的なパターンを捉えられず、予測能力も同様に非常に悪くなります。

以下のフローチャートは、多項式回帰を適用する際の典型的な思考プロセスを示しています:


二、 実践:Pythonで多項式回帰を実装する

私たちはscikit-learnこの強力な機械学習ライブラリを使用します。これにより、多項式回帰の実装が非常に簡単になります。

2.1 環境とデータの準備

まず、必要なライブラリがインストールされていることを確認し、模擬的な非線形データのセットを作成します。

例

# 必要なライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# 乱数シードを設定し、毎回の実行結果を一定にする
np.random.seed(42)

# 模擬データを作成:y は x の二次関数にいくつかのランダムノイズを加えたもの
X = 6 * np.random.rand(100, 1) - 3  # [-3, 3) 区間の乱数を100個生成
y = 0.5 * X**2 + X + 2 + np.random.randn(100, 1)  # y = 0.5x² + x + 2 + ノイズ

# 元データを可視化
plt.scatter(X, y, s=10, alpha=0.7, label='元データ')
plt.xlabel('X')
plt.ylabel('y')
plt.title('模擬的な非線形データ')
plt.legend()
plt.show()

このコードを実行すると、データ点がおおよそ「U」字型(放物線)の分布をしていることがわかります。直線でフィッティングするのは明らかに適切ではありません。

2.2 中核ステップ:特徴変換とモデル学習

重要なステップは、PolynomialFeaturesを使用して高次の項の特徴を生成することです。

例

# 1. 多項式特徴を作成
# パラメータ degree が多項式の次数を決定します。ここでは2次を試します
poly_features = PolynomialFeatures(degree=2, include_bias=False)
# 元の特徴Xを、XとX^2を含む新しい特徴行列X_polyに変換
X_poly = poly_features.fit_transform(X)

print(f"元のXの形状: {X.shape}")
print(f"変換後のX_polyの形状: {X_poly.shape}")
print(f"X_polyの先頭5行のデータ:\n{X_poly[:5]}")
# 出力から、X_poly には2列あることがわかる:1列目はX、2列目はX^2

# 2. 変換後の特徴で線形回帰モデルを学習する
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)  # 元のXではなく、X_polyを使用する

# 3. 学習されたモデルのパラメータ(重みとバイアス)を確認する
print(f"\nモデルパラメータ(重みw1, w2): {lin_reg.coef_.ravel()}")
print(f"モデルバイアス(切片b): {lin_reg.intercept_}")
# 出力結果は、データ生成時に使用したパラメータ [1, 0.5] と 2 に近いはずです

2.3 フィッティング結果の可視化

学習済みの「曲線」モデルがどのようなものか見てみましょう。

例

# 滑らかな曲線を描くために、一様分布の点を生成する
X_new = np.linspace(-3, 3, 100).reshape(100, 1)
# この新しい点のセットにも同様に多項式特徴変換を行う
X_new_poly = poly_features.transform(X_new)
# モデルで予測する
y_new = lin_reg.predict(X_new_poly)

# プロットを開始
plt.scatter(X, y, s=10, alpha=0.7, label='学習データ')
plt.plot(X_new, y_new, 'r-', linewidth=2, label='多項式回帰フィッティング (degree=2)')
plt.xlabel('X')
plt.ylabel('y')
plt.title('2次多項式回帰のフィッティング結果')
plt.legend()
plt.show()

美しい赤い曲線が見えるはずです。データの放物線の傾向をうまく捉えています。


三、 重要なテーマ:正しい次数をどう選ぶか?

次数の選択はトレードオフのプロセスです。異なる次数のフィッティング結果を可視化することで、直感的に理解できます。

例

# 異なる次数を試す:1(線形)、2、15(高すぎ)
degrees = [1, 2, 15]
plt.figure(figsize=(15, 4))

for i, degree in enumerate(degrees):
    # サブプロットを作成
    ax = plt.subplot(1, len(degrees), i + 1)
   
    # 多項式特徴を生成し、モデルを学習
    poly_features = PolynomialFeatures(degree=degree, include_bias=False)
    X_poly = poly_features.fit_transform(X)
    lin_reg = LinearRegression()
    lin_reg.fit(X_poly, y)
   
    # 予測してプロット
    y_new = lin_reg.predict(poly_features.transform(X_new))
   
    ax.scatter(X, y, s=10, alpha=0.7)
    ax.plot(X_new, y_new, 'r-', linewidth=2)
    ax.set_title(f'Degree = {degree}')
    ax.set_xlabel('X')
    ax.set_ylabel('y')
    # R²スコアを計算して表示(1に近いほど良い)
    y_pred = lin_reg.predict(X_poly)
    r2 = r2_score(y, y_pred)
    ax.text(0.05, 0.95, f'$R^2$ = {r2:.3f}', transform=ax.transAxes,
            verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

plt.tight_layout()
plt.show()

観察と解説:

  • Degree=1(線形):直線であり、R²スコアが低く、明らかに未学習、データの曲がりを表現できません。
  • Degree=2(2次):滑らかな曲線で、R²スコアが非常に高く、フィッティング効果は良好です。
  • Degree=15(15次):曲線が激しく振動し、多くのデータ点を通過しますが、データ点の間の傾向の予測は奇妙です。訓練データ上ではR²1に近くなるかもしれませんが、新しいデータに対する予測は非常に悪くなります。これは典型的な過学習。

3.1 より科学的な方法:交差検証

実際には、私たちは交差検証を用いて、異なる次数のモデルの未知データでの性能を評価し、検証セットで最も性能の良いモデルを選択します。scikit-learnのcross_val_scoreこれを簡単に実現できます。

例

from sklearn.model_selection import cross_val_score

# 一連の次数をテスト
degrees_to_try = range(1, 11)
cv_scores = []

for degree in degrees_to_try:
    poly_features = PolynomialFeatures(degree=degree, include_bias=False)
    X_poly = poly_features.fit_transform(X)
    lin_reg = LinearRegression()
    # 5分割交差検証を使用し、負の平均二乗誤差をスコアとする(sklearnの慣例:スコアが高いほど良いため、負のMSEを使用)
    scores = cross_val_score(lin_reg, X_poly, y, cv=5, scoring='neg_mean_squared_error')
    cv_scores.append(-scores.mean())  # 平均を取って正のMSEに戻す

# 交差検証誤差が最小となる次数を見つける
best_degree = degrees_to_try[np.argmin(cv_scores)]
print(f"交差検証によると、最適な次数は: {best_degree}")

# 交差検証誤差の次数による変化を可視化
plt.plot(degrees_to_try, cv_scores, 'bo-')
plt.xlabel('多項式の次数')
plt.ylabel('5分割交差検証の平均MSE')
plt.title('交差検証による最適な次数の選択')
plt.axvline(x=best_degree, color='r', linestyle='--', label=f'最適な次数={best_degree}')
plt.legend()
plt.grid(True)
plt.show()

四、 実践演習

さあ、学んだ知識を手を動かして定着させる時です。

演習1:診断と修正以下のコードを実行してください。多項式回帰でデータをフィッティングしようとしていますが、うまくいきません。問題がどこにあるのかを分析し、コードを修正して正しくフィッティングできるようにしてください。

例

# 問題のあるコード
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

X = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y = np.array([2, 4, 9, 16, 25])  # おおよそ y = x^2

# 1次の多項式(線形)でフィッティングを試みる
poly = PolynomialFeatures(degree=1)
X_poly = poly.fit_transform(X)
model = LinearRegression().fit(X_poly, y)

X_plot = np.linspace(1, 5, 100).reshape(-1, 1)
X_plot_poly = poly.transform(X_plot)
y_plot = model.predict(X_plot_poly)

plt.scatter(X, y, label='Data')
plt.plot(X_plot, y_plot, 'r-', label='Fit')
plt.legend()
plt.show()

演習2:実データセットの探索使用scikit-learn付属のボストン住宅価格データセット 或 糖尿病データセット目的値と非線形関係にある特徴量を選択し、多項式回帰を適用します。

  1. 绘制原始数据散点图。 → 元データの散布図を描画します。
  2. 尝试不同阶数(2, 3, 4),可视化拟合曲线。 → 異なる次数(2, 3, 4)を試し、適合曲線を可視化します。
  3. 交差検証を使用して、その特徴量に対して予測性能が最も良い多項式の次数を見つけます。

练习 3:挑战 - 多元多项式回归 → 演習3:チャレンジ - 多変量多項式回帰上記の例では、特徴量は1つだけですx。多项式回归同样适用于多个特征。例如,有两个特征 → 。多項式回帰は複数の特徴量にも同様に適用できます。例えば、2つの特徴量があるx1とx2場合、degree=2の多項式特徴量には次のものが含まれます:x1, x2, x1², x1*x2, x2²。 尝试创建一个包含两个特征 → 。2つの特徴量を含む(x1, x2)のシミュレーションデータセット(例えば、→ シミュレーションデータセット(例えば、y = x1 + x2² + 噪声),并使用 → )を作成し、それを使用してPolynomialFeatures(degree=2)フィッティングを行います。生成された特徴行列の形状を観察し、その意味を理解しましょう。

其他扩展 → その他の拡張