概要(標準化は「平均0・標準偏差1」に揃えて、比較と学習を安定させる)
データの標準化(Standardization)は、各特徴量を平均0・標準偏差1に変換する処理です。スケールが揃うことで、距離や勾配に敏感なアルゴリズム(線形回帰、ロジスティック回帰、SVM、PCAなど)が安定し、重みの解釈や正則化も適切に効きます。初心者は「Zスコアの式」「列方向の計算」「学習用データでfitしてからtransform(リーク防止)」の3点を掴めば迷いません。
標準化の基本(Zスコアと列方向の計算)
Zスコア標準化の式と直感
標準化後の値は z = (x − μ) / σ。ここで μは平均、σは標準偏差です。元の単位を捨てて「平均から何個の標準偏差だけ離れているか」に変換します。分布が異なる列同士でも、同じスケールで比較できます。
pandasで列ごとに一発標準化
import pandas as pd
df = pd.DataFrame({
"height_cm": [160, 170, 180, 175, 168],
"weight_kg": [55, 68, 75, 70, 60]
})
df_std = (df - df.mean()) / df.std(ddof=1) # 列方向の平均・標準偏差
print(df_std.round(3))
Pythonpandasは列単位で平均と標準偏差を計算できます。標準偏差のddof=1は「標本標準偏差」で統計の慣例に沿います。
NumPyでベクトル演算(行列の列方向)
import numpy as np
X = np.array([[160, 55],
[170, 68],
[180, 75],
[175, 70],
[168, 60]], dtype=np.float64)
mu = X.mean(axis=0)
sd = X.std(axis=0, ddof=1)
Z = (X - mu) / sd
print(np.round(Z, 3))
Pythonaxis=0(列方向)で平均・標準偏差を取り、ベクトル引き算→割り算で一括標準化します。
scikit-learnのStandardScaler(fit/transformとリーク防止)
基本の使い方(学習用でfit→適用はtransform)
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import pandas as pd
df = pd.DataFrame({
"height_cm": [160,170,180,175,168,182,169,172],
"weight_kg": [55,68,75,70,60,78,61,66],
"label": [0,1,1,1,0,1,0,0]
})
X = df[["height_cm","weight_kg"]]
y = df["label"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
scaler = StandardScaler()
X_train_std = scaler.fit_transform(X_train) # 学習用の統計量を学習
X_test_std = scaler.transform(X_test) # 同じ統計量で変換(リーク防止)
Python「学習用(train)でfit、検証や本番(test)ではtransformだけ」が鉄則です。testの情報で平均・標準偏差を更新するとリーク(過学習)になります。
パイプライン化で“安全運用”にする
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
pipe = Pipeline([
("scaler", StandardScaler()),
("clf", LogisticRegression())
])
pipe.fit(X_train, y_train) # 内部でfit→transform→学習
score = pipe.score(X_test, y_test) # 自動でtransformしてから推論
Python前処理とモデルを一体化して、漏れや実装ミスを防ぎます。
逆変換(人が読むスケールへ戻す)
X_train_back = scaler.inverse_transform(X_train_std)
Python予測値や特徴量を元の単位で説明したいとき、inverse_transformが便利です。
標準化と正規化の違い(いつどちらを使うか)
標準化(Standardization)
平均0・標準偏差1。分布の中心と広がりを揃えるため、線形モデル、SVM、PCAなどに向きます。外れ値の影響は受けますが、正規化よりは分布形に敏感で、係数の解釈にも好相性です。
正規化(Normalization, Min–Max)
0〜1(または−1〜1)に範囲を揃える方法。画像の画素値や距離ベースのアルゴリズム(KNN、K-means)で使いやすい反面、外れ値に弱く、分布の裾が長いとスケールが歪みます。用途に応じて使い分けます。
実践例(カテゴリ混在の標準化、グループごとの標準化、外れ値耐性)
数値列だけ標準化(文字列・カテゴリは除外)
import pandas as pd
from sklearn.preprocessing import StandardScaler
df = pd.DataFrame({
"store": ["A","A","B","B","A","B"],
"sales": [100,120,90,110,130,115],
"users": [50,55,53,60,58,62]
})
num_cols = ["sales","users"]
scaler = StandardScaler()
df[num_cols] = scaler.fit_transform(df[num_cols])
print(df)
Python数値列だけ選んで標準化します。カテゴリ列はそのまま扱うか、別途エンコーディングします。
グループ(店舗・地域)ごとに標準化
def group_standardize(g):
return (g - g.mean()) / g.std(ddof=1)
df[["sales_z","users_z"]] = df.groupby("store")[["sales","users"]].apply(group_standardize).reset_index(drop=True)
Python「グループ内で相対的に高いか低いか」を見たいときは、グループ単位の標準化が有効です。
外れ値に強い“ロバストスケーリング”
from sklearn.preprocessing import RobustScaler
robust = RobustScaler() # 中央値+四分位範囲(IQR)でスケール
X_robust = robust.fit_transform(X)
Python外れ値が多い・裾が長い分布ではRobustScalerが安定します。平均・標準偏差ではなく、中央値とIQRに基づきます。
つまずき対策の深掘り(リーク、軸、欠損、パイプライン、可視化)
データリークを必ず防ぐ
標準化のfitは学習データだけ。交差検証では、各fold内でfit→transformが自動で行われる設定(Pipeline+GridSearchCVなど)を使います。
軸(列方向)を間違えない
行がサンプル、列が特徴量。平均・標準偏差はaxis=0で取ります。axisを取り違えると“行ごとの標準化”になり、意味が崩れます。
欠損は先に処理する
NaNが混じると平均・標準偏差がNaNになり、全列が壊れます。SimpleImputerなどで補完→標準化の順番が安全です。
実運用ではパイプラインに入れる
学習・推論が分離した現場では、標準化の再現性を保つためにPipeline化します。保存時はscalerも含めてpickle/joblibで一緒に保存します。
可視化で効果を確認
標準化前後でヒストグラムや箱ひげを比較すると、中心が0、広がりが1に寄っていることが分かります。モデル前後の係数解釈にも役立ちます。
まとめ(「列方向のZスコア」「trainでfit→testはtransform」「用途で正規化と使い分け」)
標準化は、特徴量のスケールを平均0・標準偏差1へ揃える基本の前処理です。pandas/NumPyなら列方向にZスコアを一発で計算でき、scikit-learnではStandardScalerで「trainでfit・testはtransform」の鉄則を守ることでリークを防げます。外れ値が強いならRobustScaler、範囲揃えが目的ならMin–Max正規化を選択。可視化で効果を確かめつつ、Pipelineに載せて再現性と安全性を担保すれば、初心者でも安定した前処理が確実に実装できます。
