LESSON

スケーリングと正規化

田中VPoE:「NetShop のデータには『購入金額(0〜100万円)』と『購入回数(0〜50回)』のように、スケールが大きく異なる特徴量がある。このまま使うと、金額の方がモデルに強い影響を与えてしまう。」

あなた:「数値の大きさが予測に影響するんですか?」

田中VPoE:「アルゴリズムによってはね。特に距離ベースのアルゴリズムや勾配降下法を使うモデルでは、スケーリングが必須だ。」

なぜスケーリングが必要か

スケーリングが必須なモデル

モデル理由
ロジスティック回帰勾配降下法がスケールに敏感
SVM距離ベースのアルゴリズム
KNN距離計算に依存
ニューラルネットワーク勾配降下法を使用

スケーリングが不要なモデル

モデル理由
決定木分割点で判断するためスケール不問
ランダムフォレスト決定木の集合
XGBoost / LightGBM木構造ベース

StandardScaler(標準化)

平均0、標準偏差1に変換します。正規分布に近いデータに適しています。

from sklearn.preprocessing import StandardScaler
import numpy as np

# NetShop の特徴量
data = {
    'purchase_amount': [3000, 5000, 12000, 8000, 45000],
    'purchase_count': [2, 5, 10, 7, 3],
    'days_inactive': [5, 15, 30, 10, 60],
}
X = pd.DataFrame(data)

scaler = StandardScaler()
X_scaled = pd.DataFrame(
    scaler.fit_transform(X),
    columns=X.columns
)

print("変換前:")
print(X.describe().round(2))
print("\n変換後:")
print(X_scaled.describe().round(2))
# 平均≒0, 標準偏差≒1 になっていることを確認

数式: z = (x - mean) / std

適用場面: 外れ値が少なく、正規分布に近いデータ

MinMaxScaler(正規化)

指定範囲(デフォルトは 0〜1)に変換します。

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = pd.DataFrame(
    scaler.fit_transform(X),
    columns=X.columns
)

print("変換後(0〜1の範囲):")
print(X_scaled.describe().round(2))

数式: x_scaled = (x - min) / (max - min)

適用場面: 値の範囲を揃えたい場合、ニューラルネットワーク

注意: 外れ値があるとほとんどのデータが狭い範囲に圧縮される

RobustScaler(ロバスト標準化)

中央値と四分位範囲(IQR)を使うため、外れ値に強い手法です。

from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()
X_scaled = pd.DataFrame(
    scaler.fit_transform(X),
    columns=X.columns
)

print("変換後(外れ値に頑健):")
print(X_scaled.describe().round(2))

数式: x_scaled = (x - median) / IQR

適用場面: 外れ値が含まれるデータ(例: 購入金額に高額購入者がいる)

スケーラーの比較

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
import matplotlib.pyplot as plt
import numpy as np

# 外れ値を含むデータ
np.random.seed(42)
data = np.concatenate([np.random.normal(50, 10, 95), [200, 250, 300, 350, 400]])

scalers = {
    '元データ': None,
    'StandardScaler': StandardScaler(),
    'MinMaxScaler': MinMaxScaler(),
    'RobustScaler': RobustScaler(),
}

fig, axes = plt.subplots(1, 4, figsize=(16, 4))
for ax, (name, scaler) in zip(axes, scalers.items()):
    if scaler is None:
        values = data
    else:
        values = scaler.fit_transform(data.reshape(-1, 1)).flatten()
    ax.boxplot(values)
    ax.set_title(name)

plt.tight_layout()
plt.show()

スケーリングの重要な注意点

学習データでフィット、検証/テストで変換

# 正しい使い方
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)  # fit + transform
X_val_scaled = scaler.transform(X_val)           # transform のみ
X_test_scaled = scaler.transform(X_test)         # transform のみ

# やってはいけない(データリーケージ)
# scaler.fit_transform(X)  # 全データでフィットしてから分割

Pipeline で安全にスケーリング

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('model', LogisticRegression()),
])

# Pipeline を使えば、交差検証でも正しくスケーリングされる
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

スケーラー選択ガイド

条件推奨スケーラー
正規分布に近いデータStandardScaler
値の範囲を0〜1に揃えたいMinMaxScaler
外れ値が多いRobustScaler
木構造モデルのみ使うスケーリング不要

まとめ

  • スケーリングは距離ベース・勾配降下法モデルで必須
  • StandardScaler: 平均0・標準偏差1に標準化
  • MinMaxScaler: 指定範囲に正規化(外れ値に弱い)
  • RobustScaler: 中央値・IQR ベースで外れ値に強い
  • 必ず学習データでフィットし、検証/テストには transform のみ適用
  • Pipeline を使えばデータリーケージを防げる

チェックリスト

  • スケーリングが必要なモデルと不要なモデルを判断できる
  • 3つのスケーラーの違いと使い分けを説明できる
  • データリーケージを防ぐスケーリング手順を理解した
  • Pipeline の基本的な使い方を把握した

次のステップへ

次のレッスンでは、新しい特徴量を生成する手法を学びます。既存のデータから予測に有効な特徴量を作り出す技術を身につけましょう。


推定読了時間: 30分