スケーリングと正規化
田中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分