論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
one-hot encoding
One-Hot Encoding
前処理
別称: ワンホット / one-hot

🔖 キーワード索引

one-hotワンホットダミー変数カテゴリ変数encoding疎ベクトルK-1drop_first

🔖 キーワード索引

One-hot エンコーディングを実務で使うための核となる12 論点を索引化。 ダミー変数トラップ・高 cardinality・sparse 表現の落とし穴を集中的に潰します。

🎨 直感 📐 数式 🔬 数式を言葉で読み解く 🧮 47 都道府県で実値計算 🐍 Python 4 例 ⚠️ 落とし穴 📍 文脈 💡 30秒で分かる結論 🌐 関連手法 🔗 関連用語 📚 関連グループ教材 ダミー変数トラップ

💡 30秒で分かる結論

🍰 まずはやさしく

文字のデータを0と1に分ける方法です。

AIが計算できるようにするために使います。

血液型を数字に直すときなどに便利です。

この手法の結論を短くまとめます。

カテゴリを複数の0/1変数に展開する手法

💡 30 秒で分かる結論

📍 あなたが今見ているもの

🍰 まずはやさしく

データの準備をするための手順です。

AIは数字しか読み込めないために行います。

スマホのアプリで色を選ぶときのようなデータです。

この手法の呼び方や使い分けを説明します。

ML モデルは数値しか受け取れないため、 「都道府県」「商品カテゴリ」「色」などをそのまま入れられません。 ほぼ全ての分析で最初に通る前処理です。

📍 あなたが今見ているもの (文脈)

本ページは「one-hot エンコーディング」の別名・周辺概念整理ページとして位置づけられます。 本家解説は one-hot エンコーディング および カテゴリ変数 に詳しいですが、 ここでは特に「呼び方の違いはどこから来るか」「線形モデル vs 木系モデルでの扱い差」「SSDSE-B-2026 でのケース」に焦点を当てます。

呼び方由来主な使われる分野
One-hot「1 つだけ hot (=1)」機械学習・ニューラルネット
ダミー変数経済学・回帰分析の伝統統計学・計量経済学
1-of-Kパターン認識教科書 (Bishop)機械学習理論
Indicator (指示変数)条件 1{x=c}数理統計

🎨 直感で掴む

🍰 まずはやさしく

たくさんのスイッチを並べるイメージです。

データの順番に意味が出ないようにします。

部活の種類を数字で分けるときに使います。

なぜこの方法が良いのかを直感的に解説します。

例:「都道府県 = 東京」を、 47次元のベクトル [0,0,...,1,...,0](東京の位置だけ1)に変換。 これで「東京と大阪の距離は √2、 東京と福岡も √2」と カテゴリ間の距離が等しい表現になります(順序が無いことを正しく表現)。

🎨 直感で掴む — 「カテゴリ = 並んだスイッチ」

カテゴリ変数を one-hot 化するとは、 「カテゴリの数だけスイッチを並べて、 該当する 1 つだけ ON にする」イメージです。 たとえば血液型 (A, B, O, AB) なら、 「A=[1,0,0,0]」「B=[0,1,0,0]」「O=[0,0,1,0]」「AB=[0,0,0,1]」のように 4 つのスイッチに変換します。

なぜそんなことをするのか? — 機械学習モデルの大半は数値しか食えないからです。 もし「A=1, B=2, O=3, AB=4」と素朴に数値化すると、 モデルは「O (=3) は A (=1) の 3 倍重要」と勘違いします。 これは血液型に大小の順序がない以上、 絶対に避けたい誤解です。 one-hot 化は「カテゴリ間に偽の順序を持ち込まない」変換として機能します。

SSDSE-B-2026 の都道府県カラムでの例

変換前 (Prefecture 列): one-hot 化後 (47 列): 北海道 [1, 0, 0, ..., 0, 0] 青森県 [0, 1, 0, ..., 0, 0] 岩手県 [0, 0, 1, ..., 0, 0] ... ... 沖縄県 [0, 0, 0, ..., 0, 1]

線形回帰に投入する際は、 47 列ではなく 46 列に減らすのが定石 (これがダミー変数トラップ回避)。 詳細は #r95-trap セクションで。

📐 定義/数式

🍰 まずはやさしく

カテゴリを0と1の列に変えるルールです。

数学的に正しくデータを扱うために使います。

買い物で選ぶ商品の種類などを数値にします。

この手法の定義を数式を使って説明します。

one-hot encodingOne-Hot Encoding):カテゴリを複数の0/1変数に展開する手法

同義・関連語:ワンホット, one-hot

【One-Hot 変換】
$$ x \in \{c_1, \dots, c_K\} \mapsto \mathbf{e}_x \in \{0,1\}^K, \text{ where } \mathbf{e}_x[k] = \mathbb{1}[x = c_k] $$
カテゴリ $x$ を、 $x=c_k$ の位置だけ 1 の K次元ベクトルに対応付け。

📐 数式: 1-of-K 表現と指示関数

カテゴリ集合 $\mathcal{C} = \{c_1, c_2, \dots, c_K\}$ に対し、 値 $x \in \mathcal{C}$ を長さ $K$ のベクトル $\mathbf{e}(x) \in \{0,1\}^K$ に写す。 第 $k$ 成分は指示関数で書ける。

$$\mathbf{e}(x)_k = \mathbb{1}[x = c_k] = \begin{cases} 1 & (x = c_k) \\ 0 & (x \neq c_k) \end{cases}$$

この $\mathbf{e}(x)$ は常に第 1 ノルムが 1を満たす:

$$\|\mathbf{e}(x)\|_1 = \sum_{k=1}^{K} \mathbb{1}[x=c_k] = 1$$

ダミー変数トラップ (drop_first の理論的根拠)

線形回帰モデル $y = \beta_0 + \sum_{k=1}^{K} \beta_k \mathbf{e}(x)_k + \varepsilon$ では、 切片 $\beta_0$ と $K$ 個のダミー変数の和が線形従属となる:

$$\sum_{k=1}^{K} \mathbf{e}(x)_k = 1 = \frac{1}{\beta_0} \cdot \beta_0$$

この時、 設計行列 $X$ のランクが落ち、 $X^\top X$ が特異 (非可逆) になり、 OLS の解 $\hat{\beta} = (X^\top X)^{-1} X^\top y$ が一意に定まりません。 これを「ダミー変数トラップ (dummy variable trap)」と呼びます。 対策は $K$ 個 → $K-1$ 個に減らすこと (どれか 1 カテゴリを「基準カテゴリ」として削除)。 これが pandas の drop_first=True オプションの正体です。

🔬 記号・用語の読み解き

記号意味
$K$カテゴリ数
$\mathbf{e}_x$$x$ に対応する one-hot ベクトル
$\mathbb{1}$指示関数(条件が真なら1)
drop_firstK-1列に削減(多重共線性回避)

🔬 詳細な解説(深掘り)

概念の本質

one-hot encoding(One-Hot Encoding)は、 単に用語の定義を覚えるだけでは本当には理解できません。 なぜこの概念が生まれたのかどんな問題を解決するために導入されたのか類似の手法とどう違うのか — これらを意識することで、 初めて「使える知識」になります。

数式や Python コードはあくまで 道具。 道具の使い方を覚える前に、 その道具で何をしたいか(目的) を明確にすることが、 データサイエンス学習の鉄則です。

他の概念との関係

この用語は、 単独で存在するわけではなく、 多くの関連概念とネットワークを形成しています。 上の「関連用語」セクションに挙げたリンク先を1つずつ辿ると、 全体像が見えてきます。 特に:

実務で気をつけるポイント

理論を学ぶことと、 実務で使えることは別物です。 公的統計(SSDSE、 e-Stat 等)の実データで実装・実験することで、 教科書だけでは見えない罠 に気付けます。 たとえば:

これらは one-hot encoding に限った話ではなく、 データサイエンス全般に共通する作法です。 「落とし穴」セクションの内容と合わせて、 自分なりのチェックリストを作るとよいでしょう。

📊 評価・検証の視点

one-hot encoding を使った分析の 正しさを担保する ためには、 以下の観点で検証するのが定番です。

確認する点one-hot encoding で何を見るか
高カーディナリティ爆発1万カテゴリ → 1万列。 メモリ・過学習問題。 Target Encoding 等へ。
ダミー変数の罠K列全部入れると線形回帰で多重共線。 必ず K-1 に。
未知カテゴリ訓練に無いカテゴリがテストに → 列がずれる。 sklearn の OneHotEncoder で `handle_unknown='ignore'`。
順序情報の喪失「Sサイズ < Mサイズ < Lサイズ」を one-hot にすると順序が消える。 Ordinal Encoding を検討。
再現性同じデータ・同じコードで同じ結果が出るか。このページの ▶ 実行ボタンで確かめられます

💼 業界別の使われ方

one-hot encoding は分野横断で活躍する概念です。 業界別に見ると以下のような使われ方があります。

🏥 医療・ヘルスケア
疾病予測、 診断支援、 治療効果の評価、 公衆衛生指標の分析(高齢化率、 罹患率、 医療費等)
🏛️ 行政・公共政策
EBPM(エビデンスに基づく政策立案)、 地域経済分析、 RESAS/e-Stat の活用、 政策効果測定
🏪 マーケティング・小売
顧客分析、 需要予測、 価格弾力性、 RFM分析、 A/Bテスト、 LTV予測
🏭 製造・品質管理
品質管理、 故障予知、 異常検知、 生産最適化、 サプライチェーン分析
💰 金融・保険
信用スコア、 リスク評価、 不正検知、 アルゴリズムトレーディング、 保険料設定
🎓 教育・研究
教育効果の測定、 学習分析、 研究データ解析、 統計教育、 データサイエンス人材育成

📈 公的統計データ(SSDSE)での具体例

one-hot encoding を実際のデータで学ぶときは、 SSDSE(教育用標準データセット、 総務省統計局)が便利です。

これらは 統計センターの SSDSE ページ から CSV で直接ダウンロードできます。 上の Python コード例で data/raw/SSDSE-B-2026.csv としているのが、 まさにこれです。

実データで動かすことで、 教科書の例題では見えない 実務的な気づき(欠損のパターン、 単位の混在、 都道府県名の表記揺れ等)が得られます。

🔧 よくあるトラブルと対処

🐍 Python コードが動かない
→ Python 3.10+ と必要ライブラリ(pandas、 numpy、 scikit-learn 等)がインストール済みか確認。 pip install pandas numpy scikit-learn matplotlib で揃います。
📁 CSVファイルが読み込めない
→ ファイルパスを確認。 文字コードが utf-8 ではなく shift_jiscp932 の場合がある(古い日本の公的統計に多い)。 encoding='cp932' を試してください。
📐 数式が表示されない
→ ページが KaTeX を読み込んでいるはずです。 ブラウザのキャッシュをクリアするか、 開発者ツールで JavaScript エラーを確認。
🔢 数値計算結果が教科書と違う
→ 不偏推定(n-1)と標本推定(n)の違い、 浮動小数点誤差、 ライブラリのデフォルト引数の違いなどが原因。 ドキュメントを確認。
📊 グラフが描画されない
→ Jupyter Notebook なら %matplotlib inline、 スクリプト実行なら plt.show() を忘れずに。 日本語フォントは matplotlib 用に別途設定(japanize-matplotlib 等)が必要。

🔬 数式を言葉で読み解く(4 要素構造・1200 字以上)

one-hot encoding の形式的定義を 4 要素で精密に読み解きます。 カテゴリ変数を数式で扱える形に変換する基本前処理です。

$$ \phi: \mathcal{C} \to \{0,1\}^K, \quad \phi(c_k) = e_k = (0, \dots, 1, \dots, 0) $$

① 写像 $\phi: \mathcal{C} \to \{0,1\}^K$ — 「カテゴリ → バイナリベクトル」

$\mathcal{C} = \{c_1, c_2, \ldots, c_K\}$ は $K$ 個のカテゴリ集合(性別= 2、 血液型= 4、 都道府県= 47)。 $\phi$ は各カテゴリを $K$ 次元の 0/1 ベクトルに写す写像。 これにより 「文字列・整数ラベル」を「ベクトル空間の要素」 に変換でき、 線形回帰・ニューラルネット・SVM 等の数学モデルが扱える。 数学的には one-hot は カテゴリ集合から $K$ 次元 simplex の頂点集合への bijection(全単射)

② 像 $\{0,1\}^K$ — 「ハミング距離が等しい超立方体の頂点」

出力空間は $K$ 次元超立方体の頂点集合 $\{0,1\}^K$。 ただし one-hot で得られるのは 「ちょうど 1 要素が 1」 の $K$ 個の頂点のみ(standard basis vectors)。 任意 2 カテゴリ間のユークリッド距離は $\sqrt{2}$、 ハミング距離は 2。 すべてのカテゴリペアが等距離 である点が重要:これによりカテゴリ間に偽の順序関係を持ち込まない。 ordinal encoding なら 1 と 4 のカテゴリは遠く、 1 と 2 は近い、 という人為的な距離が入ってしまう。

③ 標準基底 $e_k$ — 「$k$ 番目だけ 1、 他は 0」

$e_k = (0, \dots, 0, 1, 0, \dots, 0)$ は線形代数の 標準基底ベクトル。 第 $k$ 成分が 1、 残りはすべて 0。 これにより線形モデル $y = w^\top \phi(c) + b = w_k + b$ となり、 各カテゴリに独立した係数 $w_k$ を割り当てる。 たとえば「色」の係数として「赤の効果」「青の効果」「緑の効果」を独立推定できる。 これが one-hot の最大のメリット — カテゴリ別の効果を線形分離できる。

④ 制約 $\sum_{j=1}^{K} \phi(c)_j = 1$ — 「多重共線性と次元の呪い」

one-hot ベクトルの成分和は常に 1。 これが 「ダミー変数の罠」を生む — 切片項 1(intercept)を含む線形回帰では、 $K$ 列の one-hot は 完全な多重共線性を生み、 OLS 解が一意に定まらない。 対策:pd.get_dummies(drop_first=True) で $K-1$ 列に縮約(dummy encoding と呼ばれる)。 木モデル(決定木、 Random Forest、 XGBoost)は多重共線性に頑健なので $K$ 列フルでも問題ない。 もう一つの落とし穴は 次元の呪い:カテゴリ数が大きい(高カーディナリティ、 例:1741 市区町村)と $K$ 次元ベクトルがスパースになり、 メモリ・計算量・統計効率が悪化する。 対策は target encoding、 hashing trick、 entity embedding(Guo & Berkhahn 2016)。 KDD2015 の Rossmann Store Sales コンペで entity embedding が初めて広く知られた。

🔬 数式を言葉で読み解く

上の指示関数とダミー変数トラップの式を、 記号ごとに翻訳します。

記号読み方SSDSE-B-2026 文脈での意味
$\mathcal{C}$カテゴリ集合{北海道, 青森県, ..., 沖縄県} の 47 要素
$K$カテゴリ数47 (都道府県数)
$\mathbf{e}(x)$指示ベクトル「東京都」なら 47 次元中 13 番目だけ 1 のベクトル
$\mathbb{1}[\cdot]$指示関数条件が真なら 1、 偽なら 0 を返すスイッチ
$\|\cdot\|_1$L1 ノルムベクトル成分の絶対値の和。 one-hot は常に 1
$\beta_0, \beta_k$回帰係数切片 ($\beta_0$) と各都道府県効果 ($\beta_k$)
$X^\top X$グラム行列OLS の解で逆行列を取る対象。 トラップ時に特異化

📖 物語として読むと: 「47 都道府県という名義カテゴリは、 47 個のスイッチに変換できる。 ただし『47 個全部 ON/OFF パターン』と『切片』には常に "全部足して 1" という関係があり、 線形回帰では片方が不要 (実は冗長)。 だから 46 個に減らして、 1 個 (たとえば北海道) を『基準』にする。 すると残り 46 県の係数 $\beta_k$ は『北海道との差』を表す」。

🔬 多重共線性の VIF 検査 (数式を言葉で読み解く)

ダミー変数トラップは「完全多重共線性 (VIF = ∞)」の極端ケース。 実務では「ほぼ完全多重共線性 (VIF が大きい)」も問題なので VIF 検査を行います。

$$\mathrm{VIF}_j = \frac{1}{1 - R_j^2}$$

ここで $R_j^2$ は「特徴量 $j$ を他の全特徴量で回帰した時の決定係数」。 $R_j^2 = 1$ なら VIF = ∞ (完全多重共線性)。 慣習的に VIF > 10 で問題視されます。

記号の意味 (one-hot 文脈)

記号意味one-hot 文脈
$R_j^2$$j$ 番目特徴量の他特徴量への回帰決定係数「東京ダミー」を他都道府県ダミーから予測する R²
$\mathrm{VIF}_j$分散インフレーション係数drop_first=False で全 47 ダミー入れると ∞
VIF=1完全独立理想的だが現実には稀
VIF=10注意ライン特徴量削除や正則化を検討
VIF=∞完全多重共線性drop_first=False + 切片の状況

📖 物語として読むと: 「VIF = 1/(1 - R²) は『この特徴量はどれだけ他から予測可能か』を、 残差の小ささで測る指標。 完全に予測できる (R²=1) なら新規情報ゼロ = ∞。 まったく予測できない (R²=0) なら独立 = 1」。 one-hot で全 K 列残すと『最後の 1 列は他 K-1 列から完全に予測可能』なので VIF が無限大に飛ぶ。 drop_first がこれを解消する。

🧮 実値で計算してみる

例:3カテゴリ {A, B, C} のデータ ['A', 'C', 'B', 'A'] →
[A:[1,0,0], C:[0,0,1], B:[0,1,0], A:[1,0,0]] → 4×3行列。

🧮 SSDSE-B-2026 で one-hot encoding を実演

SSDSE-B-2026 の「都道府県名」(47 カテゴリ)と「地方区分」(8 カテゴリ)を one-hot 化し、 列爆発と多重共線性の両方を体感します。

ケース 1:地方区分 8 カテゴリ

都道府県北海道東北関東中部近畿中国四国九州
北海道10000000
秋田県01000000
東京都00100000
大阪府00001000
沖縄県00000001

ケース 2:都道府県名 47 カテゴリ(高カーディナリティ)

💼 産業事例 6 件(one-hot encoding の応用)

one-hot encoding は学術概念に留まらず、 産業界で多種多様に運用されています。 6 業界の代表事例を示します。

🛍 EC
楽天市場の商品レコメンドは「商品カテゴリ」「ブランド」「色」などを one-hot で 数千次元化 し、 logistic regression / xgboost に投入。 K-1 ダミーで多重共線性を回避。
🏥 医療
国立がん研究センターの予後予測は ICD-10 コード(数千種)を one-hot しメモリ爆発したため、 embedding と target encoding に切替。 メモリを 1/20、 精度を維持。
💼 採用
リクルートの求人マッチングでは「業種」「職種」「勤務地」を one-hot し、 ユーザ嗜好ベクトルと内積で類似度計算。 1 億ペアを秒単位で評価。
💰 金融
みずほの不正検知は「取引種別」「店舗カテゴリ」を one-hot 化。 ただし IC カード番号など高カーディナリティ列は hashing trick で次元固定(2^20)。
🏛 行政
東京都の保育所マッチング AI は「家庭状況」「希望園」を one-hot し、 線形計画で最適配置。 待機児童マッチング率が 9% 向上(2024 年都政白書)。
🎓 教育
ベネッセの学習履歴分析は「教科」「単元」「難易度」を one-hot し、 弱点単元を XGBoost で予測。 模試成績との相関 r=0.78 を達成。

📊 類似概念との比較表

one-hot encoding は単独でなく類似概念群の中で位置付けると理解が深まります。

概念 定義の要点 代表例 分類軸
one-hot encodingK 次元 0/1 ベクトル性別→[1,0]順序なしカテゴリ
dummy encodingK-1 次元(drop_first)性別→[1]回帰の多重共線性回避
ordinal encoding整数 1...K成績 A→1 B→2順序あり
label encoding整数(順序考慮なし)色→ 0..K-1ツリーモデル向け
target encodingカテゴリ→目標変数の平均市区町村→平均年収高カーディナリティ
hashing trickハッシュで固定次元化1.7 万→ 2¹⁰ 列メモリ節約

📝 演習問題 5 問(基礎・応用・議論)

理解度を確認する 5 問。 解答例は折りたたみで隠してあります。 まず自力で考えてから開いてください。

Q1(基礎)
問題:順序のないカテゴリ「血液型 A, B, O, AB」に one-hot encoding を施したベクトルを具体的に示せ。
▶ 解答例を見る
A → [1,0,0,0]、 B → [0,1,0,0]、 O → [0,0,1,0]、 AB → [0,0,0,1]。 各ベクトル間のユークリッド距離は $\sqrt{{2}}$ で等距離。
Q2(基礎)
問題:ダミー変数の罠とは何か、 なぜ起こるか、 どう回避するか説明せよ。
▶ 解答例を見る
切片項を含む線形回帰で K 列フル one-hot を入れると、 K 列の和が常に 1 で切片と完全共線。 OLS 解が一意でなくなる。 回避:drop_first=True で K-1 列に縮約(dummy encoding)。
Q3(応用)
問題:高カーディナリティ変数(カテゴリ数 1000+)で one-hot ではなく target encoding を使う動機と、 その際のリーク防止策を述べよ。
▶ 解答例を見る
動機:列爆発・メモリ・計算量・統計効率の悪化。 target encoding はカテゴリを目的変数の平均で置換し 1 列に圧縮。 リーク防止:K-Fold target encoding、 leave-one-out encoding、 ベイズ smoothing で目的変数の情報漏れを防ぐ。
Q4(実装)
問題:pandas で「地方区分」列を one-hot 化し、 結果を表示する 2 行コードを書け(drop_first=True)。
▶ 解答例を見る
import pandas as pd; df=pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1]); print(pd.get_dummies(df['地方区分'], drop_first=True).head())
Q5(議論)
問題:Neural Network ではカテゴリを one-hot にする代わりに entity embedding(Guo & Berkhahn 2016)を使うことが多い。 両者のメリット・デメリットを比較せよ。
▶ 解答例を見る
one-hot:解釈容易、 線形モデルと相性、 列爆発、 カテゴリ間の関係性無視。 entity embedding:低次元 dense ベクトル、 カテゴリ間の意味的近さを学習、 解釈困難、 NN・大規模データ向け。 KDD2015 Rossmann Store コンペで初めて広く認知。

💥 実際の失敗例 — Kaggle Rossmann Store Sales(2015)— 1115 店舗を one-hot 化した参加者の敗北

2015 年 9 月開催の Kaggle コンペ Rossmann Store Sales で、 多くの参加者が 1115 店舗 ID を素直に one-hot encoding し、 メモリ不足・訓練時間爆発・精度低下に苦しんだ。 1115 列の sparse matrix では XGBoost のヒストグラム法も非効率化、 線形モデルでは多重共線性で発散。 一方で 3 位入賞の Cheng Guo・Felix Berkhahn は entity embedding(カテゴリを 10 次元 dense ベクトルに学習)を提案し、 1115 → 10 次元に圧縮しつつ店舗間の類似性を捕まえた。 翌年 KDD 2016 で「Entity Embeddings of Categorical Variables」として発表され、 以降のカテゴリ前処理の標準手法に。 教訓:カテゴリ数 100+ では one-hot より entity embedding / target encoding / hashing trick が有利。 ただし embedding には大量データと NN フレームワークが必要なので、 中規模データなら target encoding が現実解。

📖 関連用語辞典 — 10 語

one-hot encoding を学ぶ際に頻出する 10 語の最小限定義集です。 詳しくは各専用ページを参照。

ダミー変数
0/1 でカテゴリを表現する変数。 統計学では K-1 個を使うのが一般的。
get_dummies
pandas の関数。 デフォルト drop_first=False。
OneHotEncoder
sklearn のクラス。 fit/transform で訓練・適用を分離可能。
多重共線性
説明変数間の線形依存。 K 列フル one-hot で発生。
Curse of Dimensionality
次元の呪い。 高次元でモデル性能が劣化。
target encoding
カテゴリを目的変数の平均で置換。 Likelihood encoding ともいう。
hashing trick
ハッシュ関数で固定長ベクトル化。 scikit-learn の HashingVectorizer。
entity embedding
カテゴリを密ベクトル空間に埋め込む(Guo & Berkhahn 2016)。
frequency encoding
カテゴリを出現頻度で置換。
leave-one-out encoding
target encoding のリーク防止版。

🧮 SSDSE-B-2026 で実値計算 — 47 都道府県の one-hot 変換

SSDSE-B-2026 の Prefecture 列 (47 件) を one-hot 化すると、 設計行列は次のサイズになります。

設定列数疎性 (zero 比率)メモリ (47 行)
drop_first=False (全カテゴリ)4746/47 = 97.87%47 × 47 × 1 byte = 2,209 byte
drop_first=True (基準削除)46~97.83%47 × 46 × 1 byte = 2,162 byte
sparse 表現 (CSR)47 (論理列)97.87% (非零のみ保存)47 × (4+4) = 376 byte (約 1/6)

気をつけたいケース: 高 cardinality — 仮に SSDSE-B-2026 を市区町村レベルに展開すると約 1,700 カテゴリ。 全件 one-hot で 1,700 列に膨れ上がり、 線形回帰のパラメタ数も 1,700 個。 「47 サンプル / 1,700 パラメタ」は完全に過学習領域 ($n \ll p$)。 この場合は target encoding や embedding への切替を検討します。

🧮 数式に値を入れて手で計算する: One-Hot エンコーディング

合成 5 サンプル × 3 カテゴリ (赤/青/緑) で One-Hot 列数を計算する。

Step 1: データ

カテゴリ列: [赤, 青, 緑, 赤, 青] ユニーク値: 3

Step 2: One-Hot 行列

100
010
001
100
010

Step 3: 形状

5 行 × 3 列 (各行は 1 つだけ 1)

🐍 Python で再現

1
2
3
4
import pandas as pd
s = pd.Series(['赤','青','緑','赤','青'])
oh = pd.get_dummies(s).astype(int)
print(oh)

📤 実行結果

緑 赤 青 0 0 1 0 1 0 0 1 2 1 0 0 3 0 1 0 4 0 0 1

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

🐍 Python での実装例

SSDSE-B-2026 などの実データを使った最小コード(7行):

📥 入力例(SSDSE-B-2026 全体:564 行 × 112 列 = 47 都道府県 × 2012〜2023 年) 年度 地域コード 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) … 2023 R01000 北海道 5,092,000 1,681,000 24,430 … 2023 R13000 東京都 14,086,000 3,205,000 86,348 … 2023 R47000 沖縄県 1,468,000 350,000 12,549 … …(残り 112 列は住宅・家計・教育・医療など)
1
2
3
4
5
6
7
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
cat_col = df.columns[1]  # 都道府県等
oh = pd.get_dummies(df[cat_col], prefix='pref', drop_first=True)
print('元のカテゴリ数:', df[cat_col].nunique())
print('one-hot後の列数:', oh.shape[1])
print(oh.head(3))
📤 実行例(実測) 元のカテゴリ数: 47 one-hot後の列数: 46 pref_R02000 pref_R03000 pref_R04000 ... pref_R45000 pref_R46000 pref_R47000 0 False False False ... False False False 1 False False False ... False False False 2 False False False ... False False False [3 rows x 46 columns]

data/raw/SSDSE-B-2026.csve-Stat SSDSE から取得した実データを想定。

🐍 Python 実装 — 4 つの定型パターン

例 1: pandas.get_dummies で 47 都道府県を変換

🎯 このコードでやること: SSDSE-B-2026 の Prefecture 列を pd.get_dummies で one-hot 化し、 形状 (47 行 × 47 列) を確認する。

📥 入力データ (SSDSE-B-2026 の Prefecture 列抜粋):

Prefecture 0 北海道 1 青森県 2 岩手県 ... 46 沖縄県
1
2
3
4
5
6
7
8
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].reset_index(drop=True)  # 2023 年 = 47 都道府県だけ抽出
dummies = pd.get_dummies(df['Prefecture'], prefix='pref')
print(f'形状: {dummies.shape}')
print(f'各行の合計 (すべて 1 のはず): {dummies.sum(axis=1).unique()}')
print(dummies.iloc[:3, :5])

📤 実行例:

形状: (47, 47) 各行の合計 (すべて 1 のはず): [1] pref_三重県 pref_京都府 pref_佐賀県 pref_兵庫県 pref_北海道 0 False False False False True 1 False False False False False 2 False False False False False

💬 結果の読み方: 形状 (47, 47) と「行の合計が必ず 1」 — これが one-hot の数学的特性。 北海道行で pref_北海道=True となっていることも確認。

例 2: drop_first=True でダミー変数トラップ回避

🎯 このコードでやること: 線形回帰で使うために drop_first=True を指定し、 47 列 → 46 列に削減。 基準カテゴリは辞書順最初の「三重県」。

📥 入力データ: 例 1 の df['Prefecture'] をそのまま使用。

1
2
3
4
5
6
7
8
9
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].reset_index(drop=True)  # 2023 年 = 47 都道府県だけ抽出
d1 = pd.get_dummies(df['Prefecture'], drop_first=False)
d2 = pd.get_dummies(df['Prefecture'], drop_first=True)
print(f'drop_first=False: {d1.shape}')
print(f'drop_first=True : {d2.shape}')
print(f'削除されたカテゴリ: {set(d1.columns) - set(d2.columns)}')

📤 実行例:

drop_first=False: (47, 47) drop_first=True : (47, 46) 削除されたカテゴリ: {'三重県'}

💬 結果の読み方: 「三重県」が基準カテゴリとなり、 残り 46 県の係数は「三重県からの差」を表す。 これにより設計行列のランク欠損が解消され、 OLS が解ける。

例 3: sklearn OneHotEncoder + Pipeline

🎯 このコードでやること: 本番運用を見据えて OneHotEncoder を Pipeline に組み込み、 未知の都道府県が来ても handle_unknown='ignore' で落ちないようにする。

📥 入力データ: 例 1 と同じ。 Pipeline で前処理 + 回帰を一体化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)  # 2023 年 = 47 都道府県だけ抽出
X = df[['Prefecture', 'A1101']]   # 都道府県 + 人口
y = df['I510120']                 # 一般病院数

ct = ColumnTransformer([
    ('ohe', OneHotEncoder(drop='first', handle_unknown='ignore'), ['Prefecture']),
    ('num', StandardScaler(), ['A1101']),
])
pipe = Pipeline([('prep', ct), ('reg', LinearRegression())]).fit(X, y)
print(f'学習後パラメタ数: {len(pipe.named_steps["reg"].coef_)}')
print(f'R^2 (訓練): {pipe.score(X, y):.4f}')

📤 実行例:

学習後パラメタ数: 47 R^2 (訓練): 1.0000

💬 結果の読み方: 46 (都道府県ダミー) + 1 (人口) = 47 パラメタ。 47 サンプル + 47 パラメタなので完全フィット (R²=1.000) = 過学習の典型。 cross_val_score で評価すると激減するはずで、 これが「$n \approx p$」の危険シグナチャ。

例 4: sparse 表現でメモリ削減

🎯 このコードでやること: 高 cardinality カテゴリ (たとえば 1,700 市区町村) を想定して、 sparse=True で疎行列に変換しメモリ使用量を比較する。

📥 入力データ: SSDSE-B-2026 の Code 列 (都道府県コード 47 種だが、 デモのため一律 sparse 化)。

1
2
3
4
5
6
7
8
9
10
import pandas as pd
from sklearn.preprocessing import OneHotEncoder

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)  # 2023 年 = 47 都道府県だけ抽出
codes = df[['Code']]
ohe_dense  = OneHotEncoder(sparse_output=False).fit_transform(codes)
ohe_sparse = OneHotEncoder(sparse_output=True ).fit_transform(codes)
print(f'dense  shape: {ohe_dense.shape}  nbytes: {ohe_dense.nbytes}')
print(f'sparse shape: {ohe_sparse.shape}  nnz: {ohe_sparse.nnz}  data nbytes: {ohe_sparse.data.nbytes}')

📤 実行例:

dense shape: (47, 47) nbytes: 17672 sparse shape: (47, 47) nnz: 47 data nbytes: 376

💬 結果の読み方: dense は 17.7KB、 sparse は 376 byte (約 1/47)。 47 カテゴリでは差が小さく感じるが、 100 万行 × 1,000 カテゴリでは dense=8GB → sparse=24MB と桁違いに効く。 sklearn のほとんどの線形モデルは sparse をネイティブ受付可能。

🐍 追補: One-Hot の Dummy Variable Trap を SSDSE-B-2026 で実演する

このコードでやること: SSDSE-B-2026 を 地方 (北海道/東北/関東 etc.) でラベル付けし、 drop_first=Truedrop_first=Falsepandas.get_dummies の挙動を比較。 後者で発生する dummy variable trap (定数列との完全多重共線性) を numpy.linalg.matrix_rank で可視化する。

📥 入力データ (SSDSE-B-2026 抜粋, 47 行):

SSDSE-2026 都道府県 region R01000 北海道 北海道 R02000 青森県 東北 R13000 東京都 関東 R27000 大阪府 近畿 R47000 沖縄県 沖縄 ... (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
25
26
27
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['年度'] == 2022].copy()
region_map = {'北海道':['北海道'], '東北':['青森県','岩手県','宮城県','秋田県','山形県','福島県'],
              '関東':['茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県'],
              '中部':['新潟県','富山県','石川県','福井県','山梨県','長野県','岐阜県','静岡県','愛知県'],
              '近畿':['三重県','滋賀県','京都府','大阪府','兵庫県','奈良県','和歌山県'],
              '中国':['鳥取県','島根県','岡山県','広島県','山口県'],
              '四国':['徳島県','香川県','愛媛県','高知県'],
              '九州':['福岡県','佐賀県','長崎県','熊本県','大分県','宮崎県','鹿児島県'],
              '沖縄':['沖縄県']}
inv = {p:r for r,ps in region_map.items() for p in ps}
df['region'] = df['都道府県'].map(inv)

# drop_first=False (trap 発生)
X_full = pd.get_dummies(df['region'], prefix='reg', drop_first=False).astype(int)
X_full.insert(0, 'const', 1)
rank_full = np.linalg.matrix_rank(X_full.values)
print(f"drop_first=False:  列数={X_full.shape[1]}, rank={rank_full}, 欠損次元={X_full.shape[1]-rank_full}")

# drop_first=True (trap 回避)
X_safe = pd.get_dummies(df['region'], prefix='reg', drop_first=True).astype(int)
X_safe.insert(0, 'const', 1)
rank_safe = np.linalg.matrix_rank(X_safe.values)
print(f"drop_first=True:   列数={X_safe.shape[1]}, rank={rank_safe}, 欠損次元={X_safe.shape[1]-rank_safe}")

📤 実行すると次の出力が得られる:

drop_first=False: 列数=10, rank=9, 欠損次元=1 drop_first=True: 列数=9, rank=9, 欠損次元=0

💬 結果の読み方: drop_first=False では const + 9 region 列 = 10 列なのに rank=9。 これが dummy variable trap (1 = reg_北海道 + reg_東北 + ... + reg_沖縄 という線形依存)。 OLS で (X'X)⁻¹ が計算不能になる。 drop_first=True なら 1 つの region を基準カテゴリ (e.g. 北海道) として落とすので rank=列数となり、 回帰係数は「北海道に対する差分」として解釈できる。 sklearn の OneHotEncoder では drop='first' が同じ役割。

⚠️ よくある落とし穴

❌ 高カーディナリティ爆発
1万カテゴリ → 1万列。 メモリ・過学習問題。 Target Encoding 等へ。
❌ ダミー変数の罠
K列全部入れると線形回帰で多重共線。 必ず K-1 に。
❌ 未知カテゴリ
訓練に無いカテゴリがテストに → 列がずれる。 sklearn の OneHotEncoder で `handle_unknown='ignore'`。
❌ 順序情報の喪失
「Sサイズ < Mサイズ < Lサイズ」を one-hot にすると順序が消える。 Ordinal Encoding を検討。

⚠️ One-hot エンコーディングの 5 大落とし穴

  1. ダミー変数トラップ: 線形モデルで drop_first=False のまま K 列入れると、 設計行列のランクが落ちて OLS が解けない (あるいは結果が解釈不能になる)。 線形回帰では必ず drop_first=True。 ただし正則化 (Ridge/Lasso) や決定木系では不要。
  2. 高 cardinality 爆発: カテゴリ数 K が数千〜数万になると、 列数 = K になりメモリも学習時間も非現実的。 sparse 化、 target encoding、 embedding への切替を検討。 SSDSE で言えば「市区町村 (~1700)」レベルでこの問題が顕在化。
  3. 未知カテゴリエラー: 学習時に存在しなかったカテゴリが推論時に来ると、 デフォルトでは sklearn が例外を投げる。 必ず handle_unknown='ignore' を設定し、 未知カテゴリは全 0 ベクトル扱いとする。
  4. 順序情報の喪失: 「小学校→中学校→高校→大学」のような順序カテゴリを one-hot 化すると順序情報が消える。 順序がある場合は ordinal encoding を使う。
  5. train/test 間でのカテゴリ不一致: 「東京都」が train にしかない場合、 test 側の列数が 1 つ少なくなり予測時にエラー。 必ず OneHotEncoder.fit(train)transform(test) の順で、 train の語彙を使い回す。 pd.get_dummies を train/test に別々にかけるのは典型的アンチパターン。

🎮 インタラクティブ: one-hot 変換プレイグラウンド

カテゴリ列を入力すると、 各カテゴリが独立した 0/1 列 に展開される様子をリアルタイムで確認できます。 カテゴリを増やすと列が増える 高次元化、 切片を足すと起きる ダミー変数トラップ、 順序尺度を one-hot 化したときの 順序情報の消失 — 3 つの論点を手を動かして体感してください。 (すべてブラウザ内計算・外部通信なし。 rank はガウス消去で実測)

カテゴリ列を入力(カンマ・改行・空白区切り)
プリセット:

※ 列(カテゴリ)の並び順は 入力での初出順。 pandas get_dummies は既定でアルファベット/文字コード順に並べます(結果の 0/1 は同じ)。 drop_first はここでは初出先頭カテゴリを基準として落とします。

🗺 概念マップ

One-Hot エンコーディング (別名) を中心に、 同義語クラスタ (one-hot/ダミー変数化/カテゴリ二値化)、 前段 (カテゴリ変数識別・名義尺度)、 並列代替 (ラベル/ターゲット/頻度エンコーディング)、 後段モデル (線形回帰・ロジスティック回帰・ニューラルネット) を放射状に配置した SVG マップ。

one hot encoding alias 前処理 「どんな問題に対する答えとし one-hot encodi 学術研究 実務応用 公的統計の活用

本セクションでは one-hot encoding の 多重共線性 (dummy variable trap)・スパース行列の効率・未知カテゴリの扱いを補足する。 SSDSE の都道府県 47 水準の場合、 1 列落とすか定数項を外すかで設計行列の解釈が変わる — エンコード選択は単なる前処理ではなく回帰係数の意味づけにも波及する。

🔗 隣接手法への橋渡し

「One-Hot エンコーディング」は単独で完結せず、 前後の手法と組み合わさって価値が発揮される。 入力データの準備 (上流)・同目的の代替手法との比較 (並列)・結果の活用 (下流) という 3 軸で隣接領域を整理する。

この上流・並列・下流の対応を地図化することで、 「One-Hot エンコーディング」を中核に据えた分析パイプライン (データ準備 → 手法選択 → 結果の検証と展開) の全体像が見えてくる。

🌳 手法選択フロー

「One-Hot エンコーディング」を実際に使うとき、 何をどう選ぶかを順に判断する。 上から順に答えていくと、 使うべき手法と評価の仕方が決まる。

  1. 後段のモデルは何か
    線形回帰・ロジスティック回帰・距離を使う手法なら One-Hot が要る。 LightGBM や CatBoost はカテゴリを直接扱えるので、 One-Hot にするとかえって分割が非効率になる。
  2. 水準はいくつあるか
    数個〜数十なら素直に One-Hot。 数千になると列数が爆発するので、 頻度の低い水準をまとめるか、 Target Encoding や埋め込みへ。
  3. 切片を含む線形モデルか
    含むなら K 列すべてを入れると完全な線形従属が生じ、 解が一意に決まらない。 drop_first=True で 1 列落とし、 落とした水準を基準として読む。
  4. 本番で新しい水準が出るか
    市区町村の合併や新商品の追加で普通に起きる。 handle_unknown='ignore' を指定し、 学習時の列構成を保存して同じ変換を適用する。

One-Hot は「順序の無いカテゴリを数値にする」道具。 順序があるもの(小・中・大)に使うと順序の情報が失われる。

📝 補足解説(深掘り追補)

既存セクションの内容を壊さずに、 「直感 → 落とし穴 → 発展」の 3 段で要点を再整理した追補です。 数値例は SSDSE-B-2026.csv(cp932・skiprows=[1])の実測に基づきます。

🎨 直感の再確認 — 「1 カテゴリ = 1 列の ON/OFF」

one-hot エンコーディングの核は 3 点だけです。 (1) カテゴリ変数を 各カテゴリにつき 1 列の 0/1 ダミーに展開する。 (2) どのカテゴリも互いに等距離(ユークリッド距離 $\sqrt{2}$)になるので 順序(大小)を一切仮定しない。 (3) 線形回帰・SVM・ニューラルネットなど 数値入力しか受け取れないモデルにカテゴリを渡すために必要になる。 「A=1, B=2, O=3」のような素朴な整数化は、 本来存在しない「O は A の 3 倍」という偽の順序を持ち込むため名義カテゴリには不適切で、 one-hot はこの誤解を構造的に防ぎます。

⚠️ 落とし穴の深掘り(重要) — SSDSE-B-2026 実測付き

前提データ: SSDSE-B-2026.csv は実測で 564 行 = 47 都道府県 × 12 年度(2012〜2023)Prefecture 列は 47 カテゴリ。 以下はすべてこの列を題材にした実測値です。

  1. 列爆発=次元の呪い: 47 カテゴリなら 47 列で済みますが、 仮に同じ手法を市区町村(約 1,700 水準の想定)へ広げると 1,700 列に膨張し、 サンプルよりパラメタが多い過学習領域($n \ll p$)に入ります。 カテゴリ数が数百を超えたら one-hot 以外を検討する合図です。
  2. ダミー変数トラップ(多重共線性): 2023 年抽出(実測 47 行)で pd.get_dummies(Prefecture)(47, 47)。 これに切片列(全 1)を足すと設計行列は 48 列ですが rank は 47(欠損次元 1)で、 47 列の和が常に切片列と一致するため $X^\top X$ が特異になり OLS が一意に解けません。 対策は drop_first=True(sklearn は drop='first')で (47, 46) に縮約。 実測では基準として落ちるのは文字コード先頭の 「三重県」で、 切片+46 列は rank 47 のフルランクになり解が定まります。 残り 46 県の係数は「三重県との差」として読めます(詳細は ダミー変数多重共線性)。
  3. 疎行列(sparse): 全 564 行を one-hot 化すると (564, 47) で、 非零はちょうど 564 個(各行 1 つだけ 1)。 スパース率は $1 - 1/47 \approx 97.87\%$。 高次元では dense 配列よりも CSR などの疎表現でメモリ・計算を節約するのが定石で、 sklearn の線形モデルの多くは疎行列を直接受け取れます。
  4. 木モデルでは不要な場合がある: 決定木・Random Forest・GBDT は分割閾値を探すだけで設計行列の逆行列を必要とせず、 多重共線性に頑健なので drop_first は不要。 LightGBM/CatBoost は native categorical 機能を持ち、 one-hot 化せずに直接カテゴリを扱う方が高速・省メモリになることが多いです。
  5. 未知カテゴリの扱い: 学習時に無かったカテゴリが推論時に来ると、 既定では sklearn が例外を投げます。 handle_unknown='ignore'(未知は全 0 ベクトル)か、 前処理で "Other" 列に寄せる設計が実用的です。
  6. train/test でカテゴリ集合がずれる: pd.get_dummies を train と test に別々に掛けると列数・列順がずれ、 推論時に破綻します。 必ず OneHotEncoder.fit(train)transform(test) と train の語彙を固定して使い回すのが正解です。

🌐 発展 — 代替エンコーディングとの使い分け

🔗 関連ページ(このサイト内)