論文一覧に戻る 📚 用語解説(ジャストインタイム型データサイエンス教育)
標準化
Standardization (Z-score) (z)
各値を「(値−平均)/標準偏差」に変換し、平均0・分散1に揃える。単位の違う変数の比較・統合に必須。
データ前処理zZ-score標準化正規化

🔖 キーワード索引 — 拡張版

標準化に関連するキーワードを 機能別 に索引化しました。 検索時の語彙拡張、 関連語の発見、 章間ナビゲーションに役立ちます。

カテゴリキーワード(日本語)キーワード(英語)
基本概念標準化、 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、 statsmodelsStandardScaler, scipy.stats.zscore, numpy, DataFrame, statsmodels
注意点データリーケージ、 訓練・テスト分割、 fit_transform、 transform、 パイプラインdata leakage, train-test split, fit_transform, transform, Pipeline

💡 30秒で分かる結論

🍰 まずはやさしく

単位をそろえるための道具です。

違う種類のデータを比べるために使います。

テストの点数と身長を比べるような時に便利です。

まずは結論から簡単に説明します。

👁️ 直感 — 標準化は「単位を揃える」

標準化(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 スケーリングとは目的が異なる。

🎨 標準化の派生

🍰 まずはやさしく

データの見た目を整えるイメージです。

バラバラな基準を一つの共通ルールにまとめます。

スマホの画面サイズが違っても同じように見せる感じです。

似たような他の方法との違いを解説します。

① Min-Max スケーリング

(x - min) / (max - min) で 0〜1 に押し込む。 ニューラルネット入力に。

② Robust スケーリング

中央値と IQR を使う。 外れ値に強い。

③ Unit Vector スケーリング

各サンプルベクトルのノルムを 1 に。 テキスト分析でよく使用。

🚧 標準化の落とし穴

🎨 概念図で押さえる(標準化を視覚で理解)

標準化は「単位の違う変数を共通スケールに揃える」操作です。 以下 2 点の概念図で「平均 0・分散 1 化」と「外れ値の縮約効果」を視覚的に整理します。

図A: Z 変換 — ヒストグラムの中心移動と分散正規化

標準化前後の分布シフト 標準化前 (例: 人口 万人) 平均≈265 / σ≈280 東京 平均 標準化後 (Z スコア) 平均=0 / σ=1 -3 0 +3 +4.8σ Z=(x-μ)/σ

→ 標準化は「平均をゼロに揃え、 標準偏差を 1 に揃える線形変換」です。 分布の形(歪度・尖度)は変わらず、 東京のような外れ値も Z=+4.1 のような相対位置で残ります。 単位(万人)は消え、 他の変数と直接比較できるようになります。

図B: 多変数間スケール統一 — 距離計算の歪み解消

標準化なし vs あり — k-NN/k-means での距離歪み 標準化なし (生の値) 年齢 (歳) 人口 (万人, 0-1400) 東京 距離≈人口差で決まる 標準化あり (Z スコア) 年齢 Z 人口 Z 東京 (Z=+4.8) 2 軸が同等に効く

→ 標準化なしの状態では「人口 (万人, 0-1400)」と「年齢 (歳, 40-50)」を同じ距離式で扱うと、 人口の大きい単位差が距離をほぼ独占します。 標準化後は両軸とも σ=1 になるため、 k-NN・k-means・PCA・SVM など距離/分散ベースのアルゴリズムで両変数が公平に寄与します。

📷 標準化の視覚補強

標準化の効果を視覚的に再確認する。 平均と標準偏差を引いて単位を揃えることで、 異なるスケールの変数を比較可能にする。

標準化の概念図
図A: 元データ→センタリング (平均0)→スケーリング (σ=1) の 2 段階。 標準化は単位の違いを消すための前処理。
Z スコアと標準正規分布
図B: Z スコアの分布。 標準化後は平均 0・標準偏差 1 になり、 ±2 内に約 95%、 ±3 内に約 99.7% が入る (68-95-99.7 ルール)。
68-95-99.7 ルールと標準化
図C: 標準化された変数は σ 単位で「異常値の遠さ」を直接読める。 |Z| > 3 は約 0.3% の希少値。

→ 図 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 minmax robust 埼玉県 7331000.0 1.69 0.50 3.61 東京都 14086000.0 4.13 1.00 7.82 神奈川県 9229000.0 2.38 0.64 4.79 鳥取県 537000.0 -0.76 0.00 -0.63 広島県 2738000.0 0.03 0.16 0.74

💬 結果の読み方 東京都の値: z = 4.13、 min-max = 1.00、 robust = 7.82。 min-max は「最大値 = 1.00」 と縮められるため、 「東京がどれだけ突き抜けているか」が見えなくなる弱点があります。 一方 robust は中央値 IQR 基準のため、 東京が IQR の 7.82 倍離れているという外れ値性が浮き彫りに。 用途に応じて使い分けが必要です。

🔬 「標準化」を深く理解する

🔬 「標準化」を深く理解する

標準化の派生 — Robust Scaler

外れ値が多いデータでは StandardScaler は影響を受けます。 中央値と IQR を使う Robust Scaler が安全:

$$ z = \frac{x - \text{median}}{IQR} $$

パイプライン化の重要性

Cross-validation で「fit を訓練データのみ」「transform をテストデータにも」を正しく行うため、 sklearn の Pipeline を必ず使う。 これを怠るとデータリークが起きる。

📝 練習問題 — 理解度チェック

  1. この用語の基本定義を、 自分の言葉で説明できますか?
  2. この手法が使われる典型的なシナリオを3つ挙げられますか?
  3. この手法の前提条件・仮定を確認できますか?
  4. 結果を解釈する際の注意点は何ですか?
  5. 類似手法との違いを説明できますか?
  6. Python(または他言語)で実装できますか?
  7. SSDSE データで応用例を作成できますか?

標準化の式 $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 による標準化 — 実値計算例

独立行政法人 統計センターの公的データ SSDSE-B(地域経済データ、 47都道府県×複数年) を使って、 標準化の具体的な計算を体験します。

① 元データの抜粋(総人口、 教育費、 合計特殊出生率の3変数)

都道府県総人口(万人)教育費 L322108(円)合計特殊出生率 A4103
東京都1409241600.99
神奈川県923176921.13
大阪府876117711.19
愛知県748118311.29
鳥取県5449281.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

③ 標準化後の3変数(数値の桁が揃う)

都道府県人口 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 で z-score を計算 — 47 都道府県人口の実値

このコードでやること: SSDSE-B-2026 の 47 都道府県データから「総人口」列を取り出し、 平均・標準偏差を求めた上で、 全 47 県の z スコアを計算します。 上位 5・下位 5 を表示し、 「z > 2」 となる「異常に大きい」県を特定します。

📥 入力例: SSDSE-B-2026.csv を skiprows=[1] で読み、 2023 年で絞った先頭 3 行(総人口 A1101 抜粋、 単位: 人)

SSDSE-B-2026 Code Prefecture A1101 2023 R01000 北海道 5092000 2023 R02000 青森県 1184000 2023 R03000 岩手県 1163000 ... 2023 R47000 沖縄県 1468000
 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 公開値ベース)。

平均 2645808.5 標準偏差 2767630.2 --- z 上位 5 --- 県 総人口 z 東京都 14086000.0 4.13 神奈川県 9229000.0 2.38 大阪府 8763000.0 2.21 愛知県 7477000.0 1.75 埼玉県 7331000.0 1.69 --- z 下位 5 --- 県 総人口 z 鳥取県 537000.0 -0.76 島根県 650000.0 -0.72 高知県 666000.0 -0.72 徳島県 695000.0 -0.70 福井県 744000.0 -0.69 --- z > 2 の県(外れ値候補)--- 県 総人口 z 東京都 14086000.0 4.13 神奈川県 9229000.0 2.38 大阪府 8763000.0 2.21

💬 結果の読み方 東京都の z = 4.13 は経験則 (99.7% は |z|≤3 以内) を大きく超え、 統計的に極めて稀。 z > 2 の県は東京・神奈川・大阪の 3 都府県のみで、 これらが「人口の右側裾」を独占している構造が読み取れます。 z 下位は鳥取・島根など中国・四国地方に集中。 単純な人口の絶対値では「東京は約 26 倍」と差が大きすぎますが、 z スコアで見ると「平均から 4.13σ 離れた点」 と統計的位置として理解できます。

🧮 数式に値を入れて手で計算する: z 値への標準化

合成データを (x-μ)/σ で標準化する。

Step 1: 元データ

x = [10, 20, 30, 40, 50] μ = 30, σ = 14.14 (母 SD)

Step 2: z

z = (x-30)/14.14 = [-1.41, -0.71, 0, 0.71, 1.41] 平均(z) = 0, SD(z) = 1 (定義)

🐍 Python で再現

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)}")

📤 実行結果

z: [-1.41 -0.71 0. 0.71 1.41] 平均: 0.0, SD: 1.0

💬 手計算 (Step 2) と Python 出力が完全一致。

🎮 触って理解する — 標準化インタラクティブ

ボタンを押すと、 桁の全く違う 2 変数 —— 総人口(数百万人)と年平均気温(十数℃)—— が z-score でどう「同じ土俵(平均 0・SD 1)」に揃うかをアニメーションで体感できます。 点をタップすると、 その県の元の値・z 値・パーセンタイルが表示されます。 使用データは SSDSE-B-2026(2023 年・47 都道府県・A1101 総人口/B4101 年平均気温) の実測値です。

① 変換モードを選ぶ(点をタップで県を選択)
点をタップすると、 その県の詳細(元の値・z 値・パーセンタイル)が出ます。

💡 「そのまま」では人口の目盛(万人)と気温の目盛(℃)は全く別スケール。 「標準化」を押すと両者が同じ σ 単位の軸(平均 0・SD 1)に揃い、 直接比較できるようになります。 Min-Max は両者を [0,1] に押し込みますが、 東京のような外れ値が上限 1 に張り付き「突出度」が潰れます。

② 距離ベースの手法(kNN)は標準化で「最近傍」が変わる

💡 生データのユークリッド距離は「人口の差(数百万)」が「気温の差(数℃)」を完全に飲み込むため、 最近傍はほぼ人口だけで決まります。 標準化すると両変数が対等になり、 最近傍(黄色い線の相手)が入れ替わります —— これが k-NN・k-means・SVM で標準化が必須とされる理由です。

③ 勾配降下法は標準化で収束が速くなる
標準化なし(細長い谷)
標準化あり(丸い谷)

💡 スケールが揃っていない(左)と損失曲面が細長い谷になり、 勾配降下は谷を横断してジグザグに振動し、 収束が遅くなります。 標準化すると曲面が丸くなり(右)、 最短経路で中心へ直行できます。 これが線形回帰・ニューラルネットで標準化が学習を安定・高速化する理由です。

📌 標準化(z-score)と Min-Max 正規化の使い分け

上のアニメーションで見た通り、 どちらも「桁の違う変数を同じ土俵に載せる」ための変換ですが、 載せ方(何を基準に揃えるか)が違います。

観点標準化(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 は特に脆弱)。

⚠️ データリークを避ける — 統計量は「訓練データだけ」で計算する
μ・σ(Min-Max なら min・max)は訓練データのみから求め、 その同じ値を使って検証・テストデータを変換します。 検証データを含めて統計量を計算すると、 未来の情報が前処理に漏れ込むデータリークとなり、 評価が楽観的に歪みます。 scikit-learn では Pipeline + fit_transform(訓練)/transform(検証・テスト)でこれを自動的に守れます。

🔗 このデモに関連する用語

🐍 Python での標準化

🎯 このコードでやること: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)

📤 実行結果

X_train_std.mean(axis=0) ≈ [0, 0, 0, ...] ← 標準化後は平均 0 X_train_std.std(axis=0) ≈ [1, 1, 1, ...] ← 分散 1 pipe.score(X_test, y_test) → 0.78 ← Pipeline で fit→predict が安全に動く

💬 読み方:StandardScaler を Pipeline に組み込むと cross_val_score でも fold ごとに正しく fit され、 リーケージが防げる。 外れ値が多い SSDSE-B 数値列なら RobustScaler の方が安定する。

🚧 落とし穴と注意点

🐍 Python 実装バリエーション — scikit-learn / scipy / numpy / pandas

標準化は 4 つの代表的なライブラリ で実装できます。 用途に応じて使い分けましょう。

① scikit-learn(機械学習パイプライン向け、 最推奨)

 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))

② scipy.stats.zscore(簡易・統計解析向け)

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

③ NumPy(軽量・手動計算)

 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))

④ pandas(DataFrameのまま操作したい時)

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())

⑤ RobustScaler(外れ値対策)

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強い
MaxAbsScaler0|max|弱い

⚠️ 標準化の落とし穴 — 拡張版(実務で本当に困る5+件)

  1. データリーケージ(fit対象の誤り):訓練データとテストデータを結合してからfitすると、 テストの分布情報が訓練に漏れ込み、 汎化性能を過大評価してしまう。 必ず訓練データのみで fit し、 テストには transform のみを適用する。 クロスバリデーション時は scikit-learn の Pipeline でラップして fold ごとに自動的に fit するのが事故防止の鉄則。
  2. 外れ値による平均・標準偏差の歪み:標準化は平均と標準偏差を用いるため、 外れ値(例:人口東京、 所得超富裕層)が1点でも混入すると σ が大きく膨らみ、 残りのデータが 0付近に圧縮される。 RobustScaler(中央値・IQRベース)や対数変換と組み合わせるか、 事前に外れ値処理(Winsorize等)を検討する。
  3. カテゴリ変数や0/1ダミーへの誤適用:ワンホットエンコード後のバイナリ変数(0または1)に標準化を適用すると、 解釈不能な小数値になり、 ツリーモデルで意味的な分岐が壊れる。 数値変数のみに ColumnTransformer 等で限定して適用する。 ID列や年月コードのような名義尺度は除外。
  4. 時系列でのリーク:時系列データで全期間からまとめて μ, σ を計算すると、 未来の情報が過去の標準化に漏れ込む。 walk-forward validation では、 各時点までの情報のみで scaler を更新する(expanding window や rolling window)必要がある。 株価・需要予測で特に致命的。
  5. ツリーモデルへの不要な適用:決定木、 ランダムフォレスト、 XGBoost、 LightGBM は分岐基準が 順序のみ に依存するため標準化しても結果は基本変わらない。 計算時間とコード複雑さだけが増す。 一方で SVM、 ロジスティック回帰(L1/L2正則化付き)、 k-NN、 ニューラルネットワークでは標準化必須。
  6. n−1 vs n の自由度問題:scikit-learn の StandardScaler は母標準偏差(ddof=0、 n割り)を使うが、 pandas の .std() は標本標準偏差(ddof=1、 n−1割り)がデフォルト。 同じデータでも値が微妙に異なり、 再現実験で「合わない」原因になる。 ddof を明示することで防止する。
  7. 欠損値の扱い:StandardScaler は欠損値(NaN)があるとエラーになる。 SimpleImputer などで先に補完するか、 IterativeImputer + StandardScaler の Pipeline を組む。 欠損のまま fit すると 0 件で std=0 となり、 ZeroDivisionError や inf の混入を招く。

⚠️ 標準化の落とし穴 — 実務で本当に困る 7 件

  1. 外れ値が μ・σ を歪める — 東京都のような巨大外れ値は平均と σ を持ち上げ、 他県の z スコアを「過小評価」する。 RobustScaler の方が安全。 (約 110 文字)
  2. 訓練データのパラメータをテストにも使う — テストデータで再度 fit すると分布ずれが起こる。 `scaler.fit(X_train); scaler.transform(X_test)` の二段が必須。 (約 120 文字)
  3. ddof の選択ミス — `numpy.std` は ddof=0 (母分散)、 `pandas.std` は ddof=1 (不偏分散) がデフォルト。 z スコアが微妙に違ってくる。 統一を意識する。 (約 130 文字)
  4. カテゴリ変数を標準化してしまう — One-hot エンコード後の 0/1 列を標準化すると意味が破壊される。 数値列のみ ColumnTransformer で対象を限定。 (約 115 文字)
  5. 分布が対称でない場合に解釈が困難 — 右に長い裾(人口・所得)では z=2 でも珍しくない。 log 変換 → 標準化の二段構えが有効。 (約 110 文字)
  6. クロスバリデーションの中で fit する — fold 全体に scaler.fit すると情報リーク。 Pipeline で fold 内 fit を保証する。 (約 110 文字)
  7. 比例尺度 vs 間隔尺度の混同 — 比率に意味がある量(人口 0 = 無)を標準化すると「0 中心」 になり原点情報が失われる。 Box-Cox や log を検討。 (約 120 文字)

📊 経験則 (68/95/99.7 ルール) を SSDSE で検証

このコードでやること: 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))

📤 実行例

|z|<1 の県の割合 = 87.2% |z|<2 の県の割合 = 93.6% |z|<3 の県の割合 = 97.9% 正規性検定 (Shapiro-Wilk): ShapiroResult(statistic=0.689, pvalue=1.1e-08) 歪度 2.22 尖度 4.95

💬 結果の読み方 正規分布の理論値(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フィッシャー分散分析で標準化を本格活用
1995SVM の流行特徴量スケーリングが必須化
2015Batch 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)  # 楽観的な評価になる

📤 実行例

CV R²: [0.855 0.936 0.978 0.914 0.943] mean= 0.925

💬 結果の読み方 Pipeline 内に StandardScaler を入れることで、 各 fold は「訓練データだけで fit、 テストデータには transform のみ」を自動的に行うため、 リークが防止される。 CV R² 平均 0.925 は人口・出生・婚姻から老年人口が高い精度で予測できることを示す(県内一貫した人口構造があるため)。 もし scaler を Pipeline 外で全データに fit していたら、 リークで R² がさらに 0.005-0.01 楽観的に膨らみ、 本番性能を誤評価することになります。

🗺️ 概念マップ — 3つの視点で体系を理解する

標準化 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。

📍 体系階層のパス

🌐 統計・データサイエンス前処理変換標準化

① 🔗 関係マップ — 「他の手法とどう繋がっているか」

中心に 標準化 を置き、 そこから 正規化・平均・標準偏差・PCA・クラスタリング・k-means など 計 11 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語あとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。

凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先

② ⭕ 包含マップ — 「どのカテゴリに含まれているか」

大きな円が小さな円を包含する Circle Packing 図。 「標準化」は緑色でハイライト

📍現在地:統計・データサイエンス

③ 🌳 ツリーマップ — 「面積で見るボリューム比較」

長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「標準化」は緑色でハイライト

🎯 3つのマップの使い分け

マップ 分かること こんな時に見る
🔗 関係マップ手法間の横の関係(前提→発展→応用)「次に何を学べばよい?」 学習順序の判断
⭕ 包含マップ分類体系の入れ子構造(上位⊃下位)「この手法はどんなジャンルに属する?」
🌳 ツリーマップ分野の規模比較(面積=ボリューム)「データサイエンス全体の俯瞰像」

💡 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スケール不変なので前処理不要標準化しない (木は順序のみ利用)

選んだ後の検証ステップ

  1. fit/transform 分離: 学習データで fit、 検証/テストには transform のみ。 リークを防ぐため train で学んだ μ・σ を保持
  2. パイプライン化: sklearn.pipeline.Pipeline([("scaler", StandardScaler()), ("model", LogisticRegression())]) で CV と組合せる
  3. 外れ値感度: StandardScaler は平均・SD を使うため外れ値で歪む。 SSDSE-B-2026 の人口は東京で歪むので RobustScaler を比較すべき
  4. 逆変換: モデル出力を解釈する際は inverse_transform で元単位に戻す
  5. 新変数追加時: スケーラーを再 fit して保存ファイル (joblib) を更新。 古いスケーラーで新データを変換しない

🔎 解説深化 — 直感・落とし穴・発展をまとめて押さえる

このセクションは、 ページ全体で断片的に触れた要点を「直感 → 落とし穴 → 発展」の 3 段で再整理した追補です。 数値はすべて SSDSE-B-2026(2023 年・47 都道府県) の実測から計算しています。

👁️ 直感 — 「平均 0・分散 1 に置き直す物差し替え」

標準化(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 と明確に別物です。

🚧 落とし穴 — ここを外すと分析が崩れる

🚀 発展 — 標準化β・対数変換との併用・パイプライン位置

標準化と標準化β(標準化偏回帰係数)の関係: 説明変数を標準化してから回帰すると、 係数は「その変数が 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]弱い

🔗 関連ページ