K_DM Book
用語集
対象者 高校生
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

One-Hot Encoding(高校生向け)

入門高校生

01.4.1 高校生向け

One-Hot Encoding(高校生向け)

最終更新 2026-11-01 読了時間 2 分
まとめ
One-Hot Encoding は、「サッカー部」「吹奏楽部」のような言葉で表されるデータ(質的データ)を、カテゴリの数だけ列を作って 0 と 1 で表す変換です。各列は「そのカテゴリに当てはまるか」という Yes/No の質問で、1 行につき 1 だけが 1 つ、残りは 0 になります。「1・2・3」と番号を振る方法とちがい、カテゴリどうしに大小や順序の意味を持ち込まないのが最大の利点です。欠点はカテゴリの種類が多いと列が増えすぎることで、都道府県の 47 列くらいまでの、数種類〜数十種類のときに向いています。

こんな場面を想像してみよう #

クラスの 5 人について、「部活」と「1 日の勉強時間」から「定期テストの点数」を予想するモデルを作りたいとします。

名前部活勉強時間(時間)点数
Aサッカー1.062
B吹奏楽2.075
C美術1.570
Dサッカー2.580
E吹奏楽0.558

勉強時間は数なので、そのまま直線の式 \(y = ax + b\) に入れられます。ところが「部活」は言葉なので、何とかして数に直さなければなりません。

一番手軽なのは「サッカー=1、吹奏楽=2、美術=3」と番号を振る方法です。でも、こう直してから直線の式に入れると、コンピュータは **「美術はサッカーの 3 倍」「吹奏楽はサッカーと美術のちょうど中間」**という関係があるものとして計算します。サッカー・吹奏楽・美術という部活の名前に、そんな大小も順序もありません。

そこで One-Hot Encoding です。「部活」の 1 列を、カテゴリの数だけの Yes/No の列に分けます。

名前部活=サッカー部活=吹奏楽部活=美術
A100
B010
C001
D100
E010

変換前は「言葉が 1 列」。変換後は「0 と 1 だけの 3 列」で、どの行も 1 がちょうど 1 つだけ点灯しています。

仕組み:カテゴリごとに Yes/No の列を立てる #

まず、カテゴリの種類を数えます。部活の列に出てくる言葉は「サッカー・吹奏楽・美術」の 3 種類で、これが新しい列の本数になります。次に、種類ごとに列を 1 本ずつ作ります。「部活=サッカー?」「部活=吹奏楽?」「部活=美術?」という 3 つの質問です。そのうえで各行を見て、当てはまる列だけを 1、ほかを 0 にします。A さんはサッカーなので (1, 0, 0)、B さんは (0, 1, 0) となり、表は横に広がって言葉の列は消えます。最後に数の列と並べてモデルに渡します。直線の式でいえば \(y = a_1 \times(\text{サッカー}) + a_2 \times(\text{吹奏楽}) + a_3 \times(\text{美術}) + a_4 \times(\text{勉強時間}) + b\) の形になり、\(a_1\) は「サッカー部であることが点数を何点動かすか」と読めます。

flowchart LR A["部活 = 吹奏楽"] --> B["サッカー? → 0"] A --> C["吹奏楽? → 1"] A --> D["美術? → 0"] B --> E["(0, 1, 0)"] C --> E D --> E

次の短い Python は、5 人の部活のリストを One-Hot に直して 1 行ずつ表示します。ライブラリを使わず、「種類を数える」「当てはまれば 1」の 2 手順だけで書けることを確かめるコードです。

1
2
3
4
5
6
7
clubs = ["soccer", "band", "art", "soccer", "band"]
cats = sorted(set(clubs))                        # ['art', 'band', 'soccer']
for c in clubs:
    print(c.ljust(7), [1 if c == k else 0 for k in cats])
# soccer  [0, 0, 1]
# band    [0, 1, 0]
# art     [1, 0, 0] ...

番号を振る方法では「サッカーと美術の距離は 2、サッカーと吹奏楽の距離は 1」と差がつきましたが、One-Hot ではどの 2 つの部活も同じだけ離れています。「ちがう」という事実だけを数にして、「どれだけちがう」は持ち込まない。これが One-Hot の設計です。

気をつけたいこと #

最初の注意点は、カテゴリの種類が多いと One-Hot の列が爆発することです。都道府県なら 47 列、市区町村なら 1,700 列以上になり、列が増えるほど計算が重くなるので、種類が多いときは「出現頻度に置き換える」など別の数値化を考えます。二つ目は、順序があるカテゴリには向かないことがある点です。「小・中・大」のように本当に順序がある言葉は、1・2・3 と振ったほうが情報を活かせることもあり、One-Hot は順序をわざと捨てる変換だと覚えておきます。三つ目は、学習時になかったカテゴリが来ると困ることです。「書道部」が新しく現れたとき対応する列がないので、実務では「未知のカテゴリは全部 0 にする」などの決まりを先に作っておきます。

やってみよう #

最初の課題は、自分のクラスの 10 人について「好きな教科」を聞き、紙の表で One-Hot Encoding してみることです。列の本数が教科の種類と同じになること、各行の 1 の個数がちょうど 1 になることを確かめましょう。二つ目は、身の回りの「言葉で表されるデータ」を 5 つ探し(血液型・曜日・天気など)、それぞれ One-Hot にすると何列になるか数えてみることです。血液型は 4 列、曜日は 7 列になりますが、その中に順序のあるものはどれか考えてみてください。三つ目は、「曜日」を月=1〜日=7 と番号で表したとき、どんなおかしな結論が出そうか考える課題です。日曜と月曜は隣なのに距離が 6 になる、というところがヒントです。

つぎに読む #

scikit-learn の OneHotEncoder と ColumnTransformer を使った実装、列が増えすぎたときの対策は 標準版の One-Hot Encoding で扱っています。逆に「数を言葉(区間)に直す」前処理は 数値データのビニング(高校生向け) へ進んでください。数の列の単位をそろえる前処理は StandardScaler(高校生向け) で説明しており、One-Hot した 0/1 の列とは別の扱いになる理由も見えてきます。