標準化に関連するキーワードを 機能別 に索引化しました。 検索時の語彙拡張、 関連語の発見、 章間ナビゲーションに役立ちます。
| カテゴリ | キーワード(日本語) | キーワード(英語) |
|---|---|---|
| 基本概念 | 標準化、 Zスコア化、 平均0分散1化、 中心化(センタリング)、 スケーリング | standardization, z-score, scaling, centering, normalization |
| 派生・関連手法 | Min-Max正規化、 Robustスケーリング、 単位ベクトル化、 対数変換、 Box-Cox変換、 Yeo-Johnson変換 | Min-Max scaling, RobustScaler, unit vector, log transform, Box-Cox, Yeo-Johnson |
| 理論基盤 | 平均、 分散、 標準偏差、 共分散、 相関係数、 線形変換 | mean, variance, standard deviation, covariance, correlation, linear transformation |
| 応用先 | 主成分分析、 k平均法、 サポートベクターマシン、 ニューラルネットワーク、 リッジ回帰、 ラッソ回帰 | PCA, k-means, SVM, neural network, ridge, lasso |
| 実装ライブラリ | scikit-learn、 SciPy、 NumPy、 pandas、 statsmodels | StandardScaler, scipy.stats.zscore, numpy, DataFrame, statsmodels |
| 注意点 | データリーケージ、 訓練・テスト分割、 fit_transform、 transform、 パイプライン | data leakage, train-test split, fit_transform, transform, Pipeline |
🍰 まずはやさしく
単位をそろえるための道具です。
違う種類のデータを比べるために使います。
テストの点数と身長を比べるような時に便利です。
まずは結論から簡単に説明します。
標準化(standardization, z-score normalization)は、 異なる単位・スケールの変数を「平均0、 標準偏差1」に揃える前処理。
変数1(平均100)と変数2(平均50)でスケールが大きく違うと、 直接比較できません。 標準化すれば両方とも同じスケールに。
🍰 まずはやさしく
データの準備をするための操作です。
分析の前にデータの基準を合わせるために使います。
人口と面積など単位が違うデータを扱う時に必要です。
この用語がどう使われるかを見ていきましょう。
論文中に 「標準化」として登場する用語。
標準化 とは:各値を「(値−平均)/標準偏差」に変換し、平均0・分散1に揃える。単位の違う変数の比較・統合に必須。
本ページでは「standardization」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
標準化 (Standardization, z-score 化) は各値から平均を引き標準偏差で割って平均 0・分散 1 のスケールに揃える前処理である。 単位の異なる変数 (人口・面積・所得など) を同じ土俵で比較する PCA、 k-means、 正則化回帰、 SVM の前段で不可欠で、 min-max スケーリングとは目的が異なる。
🍰 まずはやさしく
データの見た目を整えるイメージです。
バラバラな基準を一つの共通ルールにまとめます。
スマホの画面サイズが違っても同じように見せる感じです。
似たような他の方法との違いを解説します。
(x - min) / (max - min) で 0〜1 に押し込む。 ニューラルネット入力に。
中央値と IQR を使う。 外れ値に強い。
各サンプルベクトルのノルムを 1 に。 テキスト分析でよく使用。
標準化は「単位の違う変数を共通スケールに揃える」操作です。 以下 2 点の概念図で「平均 0・分散 1 化」と「外れ値の縮約効果」を視覚的に整理します。
→ 標準化は「平均をゼロに揃え、 標準偏差を 1 に揃える線形変換」です。 分布の形(歪度・尖度)は変わらず、 東京のような外れ値も Z=+4.1 のような相対位置で残ります。 単位(万人)は消え、 他の変数と直接比較できるようになります。
→ 標準化なしの状態では「人口 (万人, 0-1400)」と「年齢 (歳, 40-50)」を同じ距離式で扱うと、 人口の大きい単位差が距離をほぼ独占します。 標準化後は両軸とも σ=1 になるため、 k-NN・k-means・PCA・SVM など距離/分散ベースのアルゴリズムで両変数が公平に寄与します。
標準化の効果を視覚的に再確認する。 平均と標準偏差を引いて単位を揃えることで、 異なるスケールの変数を比較可能にする。
→ 図 A→B→C と読むと、 標準化が「中心と尺度を揃える単純操作」でありながら、 比較・外れ値判定・モデル係数の解釈すべてに効くことが分かる。
| 条件 | 確認方法 | 備考 |
|---|---|---|
| 分布が極端に歪んでいない | 歪度 (skewness) を計算、 |skew|<2 が目安 | 歪みが強い場合は log/Box-Cox を先に |
| 外れ値が支配的でない | 箱ひげ図、 |Z|>5 が複数件あれば要注意 | RobustScaler (中央値・IQR) を検討 |
| 訓練データのみで fit する | scikit-learn の fit_transform は学習データに、 transform は検証/テストに | データリーク防止 |
| 距離・分散ベースのモデル | k-NN / k-means / PCA / SVM / Ridge/Lasso などで必須 | 決定木系は不要 |
| カテゴリ変数は対象外 | One-Hot エンコード後は標準化しないのが普通 | 例外: 連続的順序を持つ場合のみ |
この 5 条件を満たすときに標準化は安全に効く。 歪度が大きい・外れ値が多い場合は ロバスト統計 や 対数変換 を先に検討する。
🍰 まずはやさしく
計算式を使って値を変換することです。
平均からの離れ具合を数字で出すために使います。
部活の記録が平均よりどれくらい高いか調べる感じです。
具体的な計算方法と使いどころを説明します。
$$ z = \frac{x - \mu}{\sigma} $$
z は無次元で、 「平均から何標準偏差離れているか」を表します。
| 手法 | 標準化必要? | 理由 |
|---|---|---|
| k-NN, SVM | ✅ 必須 | 距離に基づくため |
| k-means | ✅ 必須 | 距離に基づくため |
| PCA | ✅ 必須 | 分散を比較するため |
| 線形回帰 | ○ 推奨 | 係数比較・正則化のため |
| Ridge, LASSO | ✅ 必須 | 正則化が公平に効くため |
| ニューラルネット | ✅ 必須 | 学習の安定化 |
| 決定木 / RF / XGB | ❌ 不要 | スケール不変 |
「標準化」(z-score)と紛らわしい変換に 「正規化(min-max)」「ロバストスケーリング」 があります。 違いを式と典型用途で整理します。
| 手法 | 数式 | 中心 | 尺度 | 向く場面 |
|---|---|---|---|---|
| 標準化 (Z-score) | $(x-\mu)/\sigma$ | $\mu \to 0$ | $\sigma \to 1$ | 線形回帰・PCA・SVM |
| 正規化 (Min-Max) | $(x-x_{\min})/(x_{\max}-x_{\min})$ | $x_{\min} \to 0$ | $[0,1]$ 区間 | 画像 (0-255)・NN 入力 |
| ロバスト | $(x-\mathrm{med})/\mathrm{IQR}$ | 中央値 $\to 0$ | IQR $\to 1$ | 外れ値多い実データ |
| Max-Abs | $x / \max(|x|)$ | 原点保存 | $[-1,1]$ | 疎行列 (TF-IDF) |
このコードでやること: SSDSE-B-2026 の人口に標準化・min-max 正規化・ロバストスケーリングを適用し、 東京都の値がどう変換されるか比較します。 外れ値が結果にどう影響するかを実感する目的です。
📥 入力例: 47 都道府県の総人口 A1101(2023 年、 単位: 人。 東京 14,086,000、 平均 約 2,645,809、 中央値 1,549,000、 IQR ≈ 1,602,500)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 X = df[['A1101']].astype(float) # A1101 = 総人口 z = StandardScaler().fit_transform(X).flatten() mn = MinMaxScaler().fit_transform(X).flatten() rb = RobustScaler().fit_transform(X).flatten() cmp = pd.DataFrame({'県': df['Prefecture'].values, '総人口': X.values.flatten(), 'z': z, 'minmax': mn, 'robust': rb}) print(cmp[cmp['県'].isin(['東京都','神奈川県','埼玉県','広島県','鳥取県'])].round(2).to_string(index=False)) |
📤 実行例
💬 結果の読み方 東京都の値: z = 4.13、 min-max = 1.00、 robust = 7.82。 min-max は「最大値 = 1.00」 と縮められるため、 「東京がどれだけ突き抜けているか」が見えなくなる弱点があります。 一方 robust は中央値 IQR 基準のため、 東京が IQR の 7.82 倍離れているという外れ値性が浮き彫りに。 用途に応じて使い分けが必要です。
外れ値が多いデータでは StandardScaler は影響を受けます。 中央値と IQR を使う Robust Scaler が安全:
$$ z = \frac{x - \text{median}}{IQR} $$
Cross-validation で「fit を訓練データのみ」「transform をテストデータにも」を正しく行うため、 sklearn の Pipeline を必ず使う。 これを怠るとデータリークが起きる。
標準化の式 $z_i = (x_i - \mu) / \sigma$ は、 一見すると単なる引き算と割り算ですが、 各記号には統計的に明確な役割があります。 ここでは記号 → 意味の対応を丁寧に整理し、 さらに「数式を言葉で読み解く」プロセスとして、 z スコアが「単位のない位置情報」へ変換されるしくみを段階的に説明します。
| 記号 | 読み | 意味 | SSDSE-B-2026 での具体例 |
|---|---|---|---|
| $x_i$ | エックス・アイ | 標準化したい元の観測値 | 東京都の人口 1,409 万人 |
| $\mu$ | ミュー | 全データの算術平均(母平均の推定値) | 47 県平均 約 265 万人 |
| $\sigma$ | シグマ | 標準偏差。 ばらつきの「典型サイズ」 | 約 280 万人 (人口の標準偏差) |
| $x_i - \mu$ | 偏差 | 平均からどれだけ離れているか(中央寄せ) | 東京 = 1409 − 265 ≈ 1144 万人 |
| $z_i$ | ゼット | 「標準偏差を 1 単位とした距離」 単位なし | 東京 z ≈ 1144 / 280 ≈ 4.09 |
数式を言葉で読み解くと、 「$x_i$ から平均 $\mu$ を引いて中央寄せ(偏差)にした上で、 標準偏差 $\sigma$ で割る = ばらつきの単位で測り直す」 となります。 こうして得られた $z_i$ は、 元のデータが何の単位(人・円・km・歳)であっても無次元の「平均からの距離」へ変換され、 異なる尺度の指標同士を直接比較できる形になります。
数式を言葉で読み解く視点 2: 線形変換であること 標準化は $z = (1/\sigma) x - \mu/\sigma$ という $z = ax + b$ 型の線形変換です。 そのため、 元データの順序・相関係数・回帰直線の R² は全く変わりません。 変わるのは平均(→ 0)と標準偏差(→ 1)だけ、 という性質を、 数式の形そのものが保証しています。
数式を言葉で読み解く視点 3: 経験則との接続 正規分布に従うとき、 $|z| \le 1$ に約 68%、 $|z| \le 2$ に約 95%、 $|z| \le 3$ に約 99.7% のデータが入ります(経験則)。 つまり z スコアの絶対値は「何 σ 離れているか」だけでなく、 そのまま「珍しさのパーセンタイル」とほぼ同義の解釈ができます。
独立行政法人 統計センターの公的データ SSDSE-B(地域経済データ、 47都道府県×複数年) を使って、 標準化の具体的な計算を体験します。
| 都道府県 | 総人口(万人) | 教育費 L322108(円) | 合計特殊出生率 A4103 |
|---|---|---|---|
| 東京都 | 1409 | 24160 | 0.99 |
| 神奈川県 | 923 | 17692 | 1.13 |
| 大阪府 | 876 | 11771 | 1.19 |
| 愛知県 | 748 | 11831 | 1.29 |
| 鳥取県 | 54 | 4928 | 1.44 |
単位・桁が 万人・円・出生率(無次元) とバラバラなので、 そのまま距離計算(k-means等)すると 人口の数値が大きく寄与し過ぎる。 そこで標準化を適用します。
47都道府県の人口データから 平均 μ ≈ 265、 標準偏差 σ ≈ 280 が得られたとします。
東京都の標準化値 z = (1409 − 265) / 280 ≈ +4.09(平均から4σも上)
神奈川県 z = (923 − 265) / 280 ≈ +2.35、 鳥取県 z = (54 − 265) / 280 ≈ −0.75
| 都道府県 | 人口 z | 教育費 z | 出生率 z |
|---|---|---|---|
| 東京都 | +4.09 | +3.46 | −2.27 |
| 神奈川県 | +2.35 | +1.93 | −1.22 |
| 大阪府 | +2.19 | +0.52 | −0.77 |
| 愛知県 | +1.73 | +0.54 | −0.02 |
| 鳥取県 | −0.75 | −1.10 | +1.11 |
💡 標準化後はすべて 「平均0からのσ単位の距離」 という共通スケールに揃うため、 k-meansや主成分分析、 距離ベースの近傍法でも公平に扱える。
このコードでやること: SSDSE-B-2026 の 47 都道府県データから「総人口」列を取り出し、 平均・標準偏差を求めた上で、 全 47 県の z スコアを計算します。 上位 5・下位 5 を表示し、 「z > 2」 となる「異常に大きい」県を特定します。
📥 入力例: SSDSE-B-2026.csv を skiprows=[1] で読み、 2023 年で絞った先頭 3 行(総人口 A1101 抜粋、 単位: 人)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 pop = df['A1101'].astype(float) # A1101 = 総人口 mu = pop.mean() sigma = pop.std(ddof=0) # 母集団標準偏差 (n で割る) z = (pop - mu) / sigma result = pd.DataFrame({'県': df['Prefecture'], '総人口': pop, 'z': z}) print('平均', round(mu, 1), '標準偏差', round(sigma, 1)) print('--- z 上位 5 ---') print(result.nlargest(5, 'z').round(2).to_string(index=False)) print('--- z 下位 5 ---') print(result.nsmallest(5, 'z').round(2).to_string(index=False)) print('--- z > 2 の県(外れ値候補)---') print(result[result['z'] > 2].round(2).to_string(index=False)) |
📤 実行例 実際に SSDSE-B-2026 を使うと次のような出力になります(数値は SSDSE 公開値ベース)。
💬 結果の読み方 東京都の z = 4.13 は経験則 (99.7% は |z|≤3 以内) を大きく超え、 統計的に極めて稀。 z > 2 の県は東京・神奈川・大阪の 3 都府県のみで、 これらが「人口の右側裾」を独占している構造が読み取れます。 z 下位は鳥取・島根など中国・四国地方に集中。 単純な人口の絶対値では「東京は約 26 倍」と差が大きすぎますが、 z スコアで見ると「平均から 4.13σ 離れた点」 と統計的位置として理解できます。
合成データを (x-μ)/σ で標準化する。
1 2 3 4 5 | import numpy as np x = np.array([10,20,30,40,50]) z = (x - x.mean()) / x.std(ddof=0) print(f"z: {z.round(2)}") print(f"平均: {z.mean()}, SD: {z.std(ddof=0)}") |
💬 手計算 (Step 2) と Python 出力が完全一致。
ボタンを押すと、 桁の全く違う 2 変数 —— 総人口(数百万人)と年平均気温(十数℃)—— が z-score でどう「同じ土俵(平均 0・SD 1)」に揃うかをアニメーションで体感できます。 点をタップすると、 その県の元の値・z 値・パーセンタイルが表示されます。 使用データは SSDSE-B-2026(2023 年・47 都道府県・A1101 総人口/B4101 年平均気温) の実測値です。
💡 「そのまま」では人口の目盛(万人)と気温の目盛(℃)は全く別スケール。 「標準化」を押すと両者が同じ σ 単位の軸(平均 0・SD 1)に揃い、 直接比較できるようになります。 Min-Max は両者を [0,1] に押し込みますが、 東京のような外れ値が上限 1 に張り付き「突出度」が潰れます。
💡 生データのユークリッド距離は「人口の差(数百万)」が「気温の差(数℃)」を完全に飲み込むため、 最近傍はほぼ人口だけで決まります。 標準化すると両変数が対等になり、 最近傍(黄色い線の相手)が入れ替わります —— これが k-NN・k-means・SVM で標準化が必須とされる理由です。
💡 スケールが揃っていない(左)と損失曲面が細長い谷になり、 勾配降下は谷を横断してジグザグに振動し、 収束が遅くなります。 標準化すると曲面が丸くなり(右)、 最短経路で中心へ直行できます。 これが線形回帰・ニューラルネットで標準化が学習を安定・高速化する理由です。
上のアニメーションで見た通り、 どちらも「桁の違う変数を同じ土俵に載せる」ための変換ですが、 載せ方(何を基準に揃えるか)が違います。
| 観点 | 標準化(z-score) | Min-Max 正規化 |
|---|---|---|
| 式 | z=(x−μ)/σ | (x−xmin)/(xmax−xmin) |
| 結果の範囲 | 上下限なし(多くは −3〜+3) | 必ず [0, 1] に収まる |
| 中心・尺度 | 平均0・SD1 | 最小0・最大1 |
| 外れ値への感度 | μ・σ が引きずられるが、 変換後も「突出度(z の大きさ)」は残る | 非常に弱い。 東京のような外れ値が上限1を独占し、 残り46県が0付近に圧縮される |
| 向く場面 | 距離・分散・正則化を扱う手法(下記)、 正規分布を仮定する分析 | 上下限が決まっている入力(画像 0–255)、 出力を [0,1] にしたい NN、 有界であることが必要な場面 |
なぜ揃える必要があるのか —— 3 つの代表的な理由を、 上のデモと対応づけて整理します。
外れ値が多いなら 中央値と IQR を使う RobustScaler(本ページ上部参照)が安全です。 z-score も Min-Max も平均・最小・最大を通じて外れ値に引きずられます(Min-Max は特に脆弱)。
Pipeline + fit_transform(訓練)/transform(検証・テスト)でこれを自動的に守れます。
🎯 このコードでやること:3 種類の Scaler(標準化・MinMax・Robust)を切り替えながら、 リーケージを防ぐため fit_transform は訓練のみ・transform はテストに使い分ける典型パターンを示す。
📥 入力データ:X_train / X_test(SSDSE-B の人口・所得など、 単位スケールがバラバラな数値特徴量行列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # ── この抜粋で使うデータを用意します ── import numpy as np import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 X = df[['A1101', 'A1303', 'L3221']].astype(float).values y = df['A4101'].astype(float).values # 出生数 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42) from sklearn.linear_model import LinearRegression from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler # 標準化 scaler = StandardScaler() X_train_std = scaler.fit_transform(X_train) X_test_std = scaler.transform(X_test) # 重要: テストはtransformのみ # Min-Max scaler = MinMaxScaler(feature_range=(0, 1)) # Robust(外れ値に強い) scaler = RobustScaler() # pipeline で漏れなく from sklearn.pipeline import Pipeline pipe = Pipeline([ ('scaler', StandardScaler()), ('model', LinearRegression()) ]) pipe.fit(X_train, y_train) |
📤 実行結果:
💬 読み方:StandardScaler を Pipeline に組み込むと cross_val_score でも fold ごとに正しく fit され、 リーケージが防げる。 外れ値が多い SSDSE-B 数値列なら RobustScaler の方が安定する。
標準化は 4 つの代表的なライブラリ で実装できます。 用途に応じて使い分けましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.pipeline import Pipeline from sklearn.linear_model import Ridge df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1) X = df[['人口', '平均所得', '完全失業率']] y = df['消費支出'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) # Pipelineで漏れなくfit pipe = Pipeline([ ('scaler', StandardScaler()), ('model', Ridge(alpha=1.0)) ]) pipe.fit(X_train, y_train) print('R^2:', pipe.score(X_test, y_test)) |
1 2 3 4 5 6 7 8 9 | import pandas as pd from scipy.stats import zscore df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1) # ddof=1 で標本標準偏差。 NaN は nan_policy='omit' で除外 df_std = df[['人口', '平均所得', '完全失業率']].apply( lambda x: zscore(x, ddof=1, nan_policy='omit') ) print(df_std.describe()) # mean ≈ 0, std ≈ 1 |
1 2 3 4 5 6 7 8 9 10 11 | import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1) X = df[['人口', '平均所得', '完全失業率']].to_numpy() mu = X.mean(axis=0) # 各列の平均 sigma = X.std(axis=0, ddof=0) # 母標準偏差(scikit-learnと同じ) X_std = (X - mu) / sigma print('mean:', X_std.mean(axis=0).round(6)) print('std :', X_std.std(axis=0).round(6)) |
1 2 3 4 5 6 7 8 9 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1) cols = ['人口', '平均所得', '完全失業率'] # ddof=1 がpandasのデフォルト df_std = (df[cols] - df[cols].mean()) / df[cols].std() df_std.columns = [c + '_z' for c in cols] df_combined = pd.concat([df, df_std], axis=1) print(df_combined.head()) |
1 2 3 4 5 6 7 8 | from sklearn.preprocessing import RobustScaler import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1) X = df[['人口', '平均所得', '完全失業率']] scaler = RobustScaler() # 中央値とIQRを使う X_robust = scaler.fit_transform(X) print(pd.DataFrame(X_robust, columns=X.columns).describe()) |
| 手法 | 中心 | スケール | 外れ値耐性 |
|---|---|---|---|
| StandardScaler | 平均 | 標準偏差 | 弱い |
| MinMaxScaler | 最小値 | 最大−最小 | 弱い |
| RobustScaler | 中央値 | IQR | 強い |
| MaxAbsScaler | 0 | |max| | 弱い |
このコードでやること: SSDSE-B-2026 の 47 県人口を標準化し、 「|z|<1」「|z|<2」「|z|<3」 にそれぞれ何%が入るかを計算します。 理論値(正規分布: 68/95/99.7%)との差から、 人口分布がどれくらい正規から外れているかを確認します。
📥 入力例: 47 県の z スコア配列(平均 0, σ=1 に標準化済み)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd import numpy as np from scipy import stats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 pop = df['A1101'].astype(float) # A1101 = 総人口 z = stats.zscore(pop) for k in [1, 2, 3]: p = (np.abs(z) < k).mean() * 100 print(f'|z|<{k} の県の割合 = {p:.1f}%') print('正規性検定 (Shapiro-Wilk):', stats.shapiro(pop)) print('歪度', round(stats.skew(pop), 2), '尖度', round(stats.kurtosis(pop), 2)) |
📤 実行例
💬 結果の読み方 正規分布の理論値(68/95/99.7%)と比べ、 |z|<1 が 87% と異常に多く、 |z|<3 でも 97.9%(東京のみ |z|>3 の外側)。 歪度 2.22(> 1 で強い右歪み) と尖度 4.95 が示す通り、 人口は対数正規型分布。 z スコアの「珍しさ」 解釈は正規前提なので、 そのまま使うと東京の「異常値性」 が見えにくくなる。 log(pop) を取ってから z 化するのが定石です。
z スコアの概念は 19 世紀末のカール・ピアソン (Karl Pearson) とフランシス・ゴルトン (Francis Galton) の研究に遡ります。 ゴルトンは身長や能力など正規分布する形質を比較するため、 「平均からの偏差を標準偏差で割る」 という発想を導入しました。 これが現代の z 統計量・t 統計量・χ² 統計量などの標準正規分布をベースとした統計推論全体の起点となります。
20 世紀に入るとロナルド・フィッシャー (R.A. Fisher) が分散分析・最尤推定の中で標準化スケールを多用し、 心理学ではIQ スコア(平均 100、 SD 15 のスケール)が普及。 機械学習文脈では 1990 年代以降、 SVM・ニューラルネット入力前処理として再注目され、 2015 年の Batch Normalization (Ioffe & Szegedy) で「内部標準化」が DL 学習の標準技術となりました。
| 年代 | 人物・出来事 | 貢献 |
|---|---|---|
| 1885 | ゴルトン | 回帰の概念とともに偏差を SD で割る発想 |
| 1900 | ピアソン | 相関係数・モーメント法の中で標準化を導入 |
| 1908 | ゴセット(Student) | t 統計量 = 標準化された平均差 |
| 1916 | スターン (IQ) | 知能指数を z スコアでスケール化 |
| 1925 | フィッシャー | 分散分析で標準化を本格活用 |
| 1995 | SVM の流行 | 特徴量スケーリングが必須化 |
| 2015 | Batch Normalization | 層間で標準化、 DL の安定化に決定的 |
このコードでやること: SSDSE-B-2026 のデータで「人口を予測する回帰モデル」 を組む際、 標準化を Pipeline 内に閉じ込めることでテストデータへのリークを防ぎ、 cross-validation で正しい性能評価をする例を示します。
📥 入力例: 47 県 × 複数列 (人口・婚姻数・出生数 等) を特徴量に、 老年人口を目的変数に
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import Ridge from sklearn.model_selection import cross_val_score import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 feat_cols = ['A1101', 'A4101', 'A9101'] # 総人口・出生数・婚姻件数 X = df[feat_cols].astype(float) y = df['A1303'].astype(float) # A1303 = 65歳以上人口(老年人口) pipe = Pipeline([ ('scaler', StandardScaler()), ('ridge', Ridge(alpha=1.0)), ]) scores = cross_val_score(pipe, X, y, cv=5, scoring='r2') print('CV R²:', scores.round(3), 'mean=', scores.mean().round(3)) # NG パターン: 全データで先に fit → リーク # scaler = StandardScaler().fit(X) # ❌ # X_scaled = scaler.transform(X) # ❌ # cross_val_score(Ridge(), X_scaled, y, cv=5) # 楽観的な評価になる |
📤 実行例
💬 結果の読み方 Pipeline 内に StandardScaler を入れることで、 各 fold は「訓練データだけで fit、 テストデータには transform のみ」を自動的に行うため、 リークが防止される。 CV R² 平均 0.925 は人口・出生・婚姻から老年人口が高い精度で予測できることを示す(県内一貫した人口構造があるため)。 もし scaler を Pipeline 外で全データに fit していたら、 リークで R² がさらに 0.005-0.01 楽観的に膨らみ、 本番性能を誤評価することになります。
標準化 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 前処理 › 変換 › 標準化
中心に 標準化 を置き、 そこから 正規化・平均・標準偏差・PCA・クラスタリング・k-means など 計 11 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「標準化」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「標準化」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 標準化 の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → 変換 → 標準化 という入れ子の位置を示します。 「変換には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
標準化 Z = (x − μ)/σ は単位や桁の異なる変数を「平均 0、 分散 1」に揃える前処理。 SSDSE-B-2026 では人口 A1101 (百万単位) と合計特殊出生率 A4103 (無次元) と一般診療所数 I5102 (施設数) のように単位が異なる変数を同じスケールで扱う必要があり、 SVM / KNN / k-means / PCA / Lasso では必須。 線形回帰の係数解釈 (標準化β) でも使われる。
標準化は「分布の形状は変えず、 位置と尺度のみ揃える」操作。 元データが正規分布なら Z は標準正規分布になるが、 元が偏っていれば Z も偏ったまま。 形状を直したいなら対数 / Box-Cox を併用する。
変数のスケーリングには複数の方法があり、 分布の形・外れ値の有無・後段の手法でどれを選ぶかが変わる。 以下に典型シナリオと推奨スケーリング法を示す。
| シナリオ | 重視する観点 | 推奨スケーリング法 |
|---|---|---|
| 分布が正規 / 線形回帰・PCA を使う | 平均 0 分散 1・距離が比較可能 | z-score 標準化 (StandardScaler) |
| 外れ値が多い / 分布が歪む | 中央値・四分位範囲ベースで頑健化 | RobustScaler (中央値・IQR) |
| [0,1] 範囲が必要 / NN・画像入力 | 最小最大に固定スケーリング | Min-Max 正規化 (MinMaxScaler) |
| 疎ベクトル (スパース) を扱う | 原点保持・ベクトル長 1 化 | MaxAbsScaler / L2 正規化 |
| 右に裾の長い分布 | 対数変換で正規化に近づける | log 変換 → z-score |
| 決定木 / Random Forest / XGBoost | スケール不変なので前処理不要 | 標準化しない (木は順序のみ利用) |
sklearn.pipeline.Pipeline([("scaler", StandardScaler()), ("model", LogisticRegression())]) で CV と組合せるinverse_transform で元単位に戻すこのセクションは、 ページ全体で断片的に触れた要点を「直感 → 落とし穴 → 発展」の 3 段で再整理した追補です。 数値はすべて SSDSE-B-2026(2023 年・47 都道府県) の実測から計算しています。
標準化(z-score)は各値を $z=(x-\mu)/\sigma$ に変換し、 平均 0・分散 1 に揃えます。 これは「値を消す」のではなく「ばらつき σ を 1 目盛りとする物差しに測り直す」操作です。 単位(人・円・℃)が消えて無次元になるため、 平均も桁も違う変数どうしを同じ土俵で足し引き・比較できます。 だからこそ、 変数間の距離や係数の大小を直接扱う距離ベース・分散ベース・正則化ベースの手法で標準化が要になります。
正規化(Min-Max)との違い: 正規化 $(x-x_{\min})/(x_{\max}-x_{\min})$ は「両端(最小・最大)を 0 と 1 に固定して区間に押し込む」変換で、 上下限のある入力(画像 0–255 や NN 入力)向き。 標準化は「中心(平均)と尺度(σ)を揃える」変換で上下限を持ちません。 同じ「揃える」でも基準が端か中心かが本質的な違いです。 日本語では両者をまとめて「正規化」と呼ぶ場面があり混同されがちですが、 sklearn では前者が MinMaxScaler、 後者が StandardScaler と明確に別物です。
transform します。 全データで先に fit すると未来の情報が漏れ、 評価が楽観的に歪みます(データリーク)。 クロスバリデーションでは fold ごとに fit が必要なので、 スケーラーとモデルを Pipeline に閉じ込めるのが定石です。ColumnTransformer で数値列だけに限定して適用するのが安全です。.std() は不偏(ddof=1)が既定で、 東京都の z は 4.1336(ddof=0) と 4.0894(ddof=1) のように微妙にずれ、 再現時の食い違い原因になります。標準化と標準化β(標準化偏回帰係数)の関係: 説明変数を標準化してから回帰すると、 係数は「その変数が 1σ 動いたとき目的変数が何 σ 動くか」を表す標準化偏回帰係数になり、 単位に依存せず変数間の寄与の大小を直接比較できます。 実測例として 65 歳以上人口 A1303 を 総人口 A1101 と 出生数 A4101 で回帰すると、 生の係数は 0.412(人口)と −27.22(出生数)で単位も桁も違い比較できませんが、 標準化βは +1.66 と −0.67 となり「人口の寄与が出生数の約 2.5 倍・逆符号」と読めます。 両者は $\beta^{std}_j=\beta_j\,\sigma_{x_j}/\sigma_y$ の関係で厳密に一致します(実測で検算済み)。
対数変換との併用: 右に裾の長い変数は「log で形を整えてから z 化」が定石です。 実測では総人口の歪度は 2.22 → 0.79($\log$ 後)へ大きく改善し、 東京都の z は 4.13 → 2.57、 $|z|>2$ の県も 3 県 → 2 県へ。 標準化は形を変えないので、 形の補正(log/Box-Cox)が先・スケール合わせ(z 化)が後という順序が重要です。
パイプラインでの位置: 標準化は特徴量エンジニアリングの後・モデルの直前に置く「前処理の最終段」です。 Pipeline([("log", ...), ("scaler", StandardScaler()), ("model", ...)]) のように並べ、 fit は訓練のみ・transform は検証/テストへ——という原則を Pipeline が自動で守るため、 CV と組み合わせてもリークしません。 スケーラー別の中心・尺度・外れ値耐性は次の通りです。
| スケーラー | 中心 | 尺度 | 上下限 | 外れ値耐性 |
|---|---|---|---|---|
| StandardScaler(z-score) | 平均 | σ | なし | 弱い |
| MinMaxScaler(正規化) | 最小値 | max−min | [0,1] | とても弱い |
| RobustScaler | 中央値 | IQR | なし | 強い |
| MaxAbsScaler | 原点保存 | |max| | [−1,1] | 弱い |