Python | データ処理:データの標準化

Python
スポンサーリンク

概要(標準化は「平均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))
Python

pandasは列単位で平均と標準偏差を計算できます。標準偏差の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))
Python

axis=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に載せて再現性と安全性を担保すれば、初心者でも安定した前処理が確実に実装できます。

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