概要(正規化は「値の範囲を揃えて比較・学習を安定化」する前処理)
正規化(Normalization)は、特徴量の値を一定の範囲にスケーリングする処理です。最も基本的な手法は Min–Max 正規化で、各列を 0〜1(または任意の範囲)に収めます。距離ベースのアルゴリズム(KNN、K-means)、ニューラルネットの入力、画像の画素値などで効果が大きく、桁や単位が異なる複数特徴量を“公平”に扱えるようになります。外れ値の影響やデータリークを避ける設計が重要です。
正規化の基本(Min–Maxと任意レンジ、直感と式)
Min–Max 正規化の式は z = (x − min) / (max − min) です。列の最小値と最大値を基準に 0〜1 に押し込み、分布の形は保ったままスケールだけを揃えます。0〜1が不便なら z = a + (b − a) × (x − min) / (max − min) で a〜b(例:−1〜1)に変換できます。直感は「その値が最小と最大の間のどこに位置するか」を割合で表す、です。
pandas・NumPyでの実装(列指向の一括処理)
pandasなら各列に対して min と max を取り、式をそのまま適用します。DataFrame全体を扱う場合は数値列だけ選んで正規化し、カテゴリや文字列は別途エンコードします。
import pandas as pd
df = pd.DataFrame({
"height_cm": [160, 170, 180, 175, 168],
"weight_kg": [55, 68, 75, 70, 60]
})
df_norm = (df - df.min()) / (df.max() - df.min()) # 0〜1
df_range = -1 + 2 * df_norm # −1〜1 に変換
print(df_norm.round(3)); print(df_range.round(3))
PythonNumPyでも列方向(axis=0)で min/max を取り、ベクトル演算で一括処理します。ブロードキャストでループ無しに書けるため高速です。
import numpy as np
X = np.array([[160, 55],
[170, 68],
[180, 75],
[175, 70],
[168, 60]], dtype=np.float64)
mn = X.min(axis=0); mx = X.max(axis=0)
Z01 = (X - mn) / (mx - mn)
Z11 = -1 + 2 * Z01
print(np.round(Z01, 3)); print(np.round(Z11, 3))
Pythonscikit-learnで安全運用(MinMaxScalerとNormalizer、fit/transform)
MinMaxScalerは学習用データで fit(min/max を学習)し、検証・本番データは transform のみで同じスケールに揃えます。trainでfit、testはtransformという流れが“リーク防止”の鉄則です。
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import pandas as pd
df = pd.DataFrame({"x1": [10,20,30,40,50], "x2": [5,15,25,35,45]})
X_train, X_test = train_test_split(df, test_size=0.4, random_state=0)
scaler = MinMaxScaler(feature_range=(0, 1))
X_train_n = scaler.fit_transform(X_train) # train で min/max を学習
X_test_n = scaler.transform(X_test) # 同じスケールを適用
Python各サンプル(行)をベクトル単位で L2 正規化する Normalizer も便利です。これは「各行の長さ(ノルム)を 1 にする」処理で、コサイン類似度系やテキスト特徴量で使われます。
from sklearn.preprocessing import Normalizer
norm = Normalizer(norm="l2")
X_row_norm = norm.fit_transform(df.values) # 行ごとに ||x||=1 へ
Python元のスケールへ戻したいときは inverse_transform を使います。モデル係数の解釈や報告で役立ちます。
X_train_back = scaler.inverse_transform(X_train_n)
Python実務例(画像の画素、KNN/K-means、グループ別の相対比較)
画像の画素値は 0〜255 を 0〜1 に正規化すると、学習の安定性が上がります。型は float に揃え、丸め誤差やオーバーフローを避けます。
import numpy as np
img_uint8 = np.random.randint(0, 256, size=(480, 640), dtype=np.uint8)
img01 = img_uint8.astype(np.float32) / 255.0
PythonKNNやK-meansのような距離ベースでは、各列のスケール差が距離に直撃します。Min–MaxまたはStandardScalerで揃えた上で、学習を進めます。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
Xn = scaler.fit_transform(df.values) # 0〜1に揃えてから距離計算へ
Python店舗や地域などグループ内の相対比較なら、グループ単位で Min–Max を行うと「そのグループの中での位置づけ」が明瞭になります。
import pandas as pd
data = pd.DataFrame({
"store": ["A","A","B","B","A","B"],
"sales": [100,120,90,110,130,115]
})
g = data.groupby("store")["sales"]
data["sales_norm_in_group"] = (g.transform(lambda s: (s - s.min()) / (s.max() - s.min())))
Python重要ポイントの深掘り(外れ値、欠損、リーク、パイプライン、可視化)
外れ値が大きいと min/max が引っ張られて、ほとんどの値が狭い範囲に押し込まれます。Winsorize(極端値のクリップ)や Percentile ベースのレンジで緩和し、必要なら RobustScaler(中央値+IQR)や QuantileTransformer(分位変換)の検討も有効です。正規化と“外れ値対策”はセットで考えるのが安全です。
欠損値(NaN)は min/max 計算を壊します。SimpleImputerなどで補完を先に行い、補完後に正規化します。補完の戦略(平均・中央値・最頻値・回帰補完)はデータの性質に合わせて選び、再学習時も同じ手順を再現します。
データリークは必ず防ぎます。学習用データで scaler.fit を行い、検証・本番では transform のみを適用します。scikit-learn の Pipeline に正規化を組み込み、学習・推論の両方で同じ処理が自動適用される運用にするとミスが減ります。
効果の確認には可視化が有効です。正規化前後でヒストグラムや箱ひげを見比べると、レンジが狙いどおりに変化しているか、外れ値の影響が過度ではないかが直感的に把握できます。説明責任のある場では、変換式・範囲・外れ値の扱いを明記します。
まとめ(「Min–Maxで範囲を揃える」「fitはtrainのみ」「外れ値・欠損を先に設計」)
正規化は、値の範囲を揃えて比較と学習を安定させる基本の前処理です。pandas/NumPyなら式をそのまま列に適用でき、scikit-learnでは MinMaxScaler と Normalizer を使って再現性の高い運用ができます。trainでfit、testはtransformの鉄則を守り、欠損補完や外れ値対策を先に設計する。可視化で効果を確認し、Pipeline化で本番でも同じ手順を担保すれば、初心者でも“安全で説得力のある”正規化が確実に実装できます。
