Pythonで機械学習の前処理!Scikit-learn LabelBinarizerによるラベルのワンホットエンコーディング

Python

Pythonで機械学習モデル(例えばLogisticRegressionRandomForestClassifierなど)を構築する際、データの前処理は非常に重要です。特に、モデルが理解できる形にデータを整える必要があります。

「犬」「猫」「鳥」といった**文字列のデータ(カテゴリデータ)**は、そのままでは機械学習モデルに入力できません。これらを「0」や「1」といった数値に変換する必要があります。

この記事では、Pythonの機械学習ライブラリ**Scikit-learn(サイキットラーン)に含まれるLabelBinarizer**に焦点を当てます。

LabelBinarizerは、主に機械学習の「正解データ(ラベル)」を、モデルが扱いやすい「0」と「1」のベクトル形式(ワンホットエンコーディング)に変換するための強力なツールです。

この記事を最後まで読めば、以下のことが明確に理解できます。

  • LabelBinarizerの基本的な使い方(fit, transform
  • マルチクラス(3種類以上)のラベルを変換する方法
  • 変換したデータを元のラベルに戻す方法(inverse_transform
  • OneHotEncoderLabelEncoderなど、非常に混同しやすいクラスとの決定的な違い

機械学習の前処理で迷いがちな「ラベルの変換」を、この記事でスッキリ解決しましょう。

本記事で解説するLabelBinarizerの公式ドキュメントはこちらです。


  1. はじめに:LabelBinarizerとは?
    1. 機械学習における「ラベル」とは?
    2. なぜ「ワンホットエンコーディング」が必要?:機械は文字を理解できない
    3. LabelBinarizerの役割:文字列や数値の「ラベル」を0と1のベクトルに変換する
    4. この記事で学べること:LabelBinarizerの基本から実践、類似クラスとの違いまで
  2. LabelBinarizerを使うための準備
    1. Scikit-learnのインストール(または確認)
    2. LabelBinarizerのインポート方法 (sklearn.preprocessing)
  3. LabelBinarizerの基本的な使い方 (fit / transform)
    1. ステップ1:LabelBinarizerのインスタンスを作成する
    2. ステップ2:「fit」でラベルの種類(クラス)を学習する
    3. ステップ3:「transform」でデータを二値化(ワンホット)ベクトルに変換する
    4. 「fit_transform」メソッドで学習と変換を同時に行う
  4. 【実践】サンプルコードで動作を理解する
    1. 準備:サンプルのラベルデータ(文字列、数値)
    2. シナリオ1:2クラス(バイナリ)のラベルを変換する (例: [‘yes’, ‘no’])
    3. シナリオ2:3クラス以上(マルチクラス)のラベルを変換する (例: [‘Tokyo’, ‘Osaka’, ‘Nagoya’])
    4. classes_属性:学習したクラス(順番)を確認する方法
  5. 予測結果を元に戻す!「inverse_transform」の使い方
    1. なぜinverse_transformが必要なのか?
    2. 使い方:0と1のベクトルから元のラベル(’cat’など)を復元する
  6. 【最重要】類似クラスとの違いと使い分け
    1. 1. LabelBinarizer vs OneHotEncoder:決定的な違いは「入力の対象」
    2. 2. LabelBinarizer vs Binarizer:数値とカテゴリの違い
    3. 3. LabelBinarizer vs LabelEncoder:ベクトルか単一整数かの違い
    4. 4. LabelBinarizer vs MultiLabelBinarizer:マルチクラスかマルチラベルか
    5. 使い分けの早見表
  7. まとめ:LabelBinarizerで「ラベル」を正しく前処理しよう

はじめに:LabelBinarizerとは?

まずはLabelBinarizerがどのようなもので、なぜ機械学習に必要なのかを見ていきましょう。

機械学習における「ラベル」とは?

機械学習(特に教師あり学習)では、モデルに「問題(特徴量X)」と「答え(ラベルy)」のセットを与えて学習させます。

例えば、動物の写真を見て「犬」か「猫」かを分類するモデルを作る場合、

  • 問題(X):動物の写真データ
  • 答え(y):その写真が「犬」であるか、「猫」であるかという**「ラベル」**

となります。この「答え」に相当するデータが「ラベル」です。

なぜ「ワンホットエンコーディング」が必要?:機械は文字を理解できない

機械学習のアルゴリズムは、基本的に数学的な計算(数値計算)で動作します。そのため、「犬」や「猫」といった文字列(カテゴリ)をそのまま計算することはできません。

そこで、これらの文字列を数値に変換する必要があります。

よくある間違いは、「犬=0」「猫=1」「鳥=2」のように単純な整数に変換することです(これはLabelEncoderの機能に近いですが、注意が必要です)。

これでは、モデルが「犬(0)と鳥(2)の中間が猫(1)」のような、本来存在しない数値的な大小関係や順序を誤って学習してしまう可能性があります。

この問題を解決するのが**ワンホットエンコーディング(One-Hot Encoding)**です。

これは、各カテゴリを「0」と「1」で構成されるベクトル(配列)で表現する方法です。

  • 犬 → [1, 0, 0]
  • 猫 → [0, 1, 0]
  • 鳥 → [0, 0, 1]

これなら、各カテゴリは対等な関係となり、モデルが誤った順序を学習するのを防げます。

LabelBinarizerの役割:文字列や数値の「ラベル」を0と1のベクトルに変換する

Scikit-learnのLabelBinarizerは、まさにこの「ラベル」のワンホットエンコーディングを簡単に行うためのクラスです。

[‘犬’, ‘猫’, ‘犬’] というラベルのリストを、

[[1, 0], [0, 1], [1, 0]] のような(この例は2クラスなので少し異なりますが、イメージです)数値の配列に変換してくれます。

この記事で学べること:LabelBinarizerの基本から実践、類似クラスとの違いまで

この記事では、LabelBinarizerのインストール確認から始まり、基本的なfit / transformの使い方、そして予測結果を元のラベルに戻すinverse_transformまでを解説します。

特に重要な点として、OneHotEncoderBinarizerLabelEncoderといった類似クラスとの違いを徹底的に比較し、あなたが「どの場面でLabelBinarizerを使うべきか」を明確に判断できるようになることを目指します。


LabelBinarizerを使うための準備

LabelBinarizerは、Scikit-learnライブラリの一部として提供されています。

Scikit-learnのインストール(または確認)

AnacondaやGoogle Colaboratoryなどの一般的なデータ分析環境では、Scikit-learn(sklearn)は通常、最初からインストールされています。

もし手元の環境になければ、pipコマンドでインストールしてください。

# ターミナルやコマンドプロンプトで実行
pip install scikit-learn

LabelBinarizerのインポート方法 (sklearn.preprocessing)

LabelBinarizerはsklearn.preprocessingモジュールに含まれています。

以下のようにインポートして使用します。

from sklearn.preprocessing import LabelBinarizer
import numpy as np

LabelBinarizerの基本的な使い方 (fit / transform)

LabelBinarizerの使い方は、Scikit-learnの他の変換器(StandardScalerMinMaxScalerなど)と共通しており、fit(学習)とtransform(変換)の2ステップが基本です。

ステップ1:LabelBinarizerのインスタンスを作成する

まず、LabelBinarizerクラスの設計図から「インスタンス(実体)」を作成します。

# LabelBinarizerのインスタンスを作成
lb = LabelBinarizer()

この時点では、まだ何も学習していません。

ステップ2:「fit」でラベルの種類(クラス)を学習する

次に、fit()メソッドを使って、私たちが扱いたいラベルデータにどのような種類(クラス)があるかをLabelBinarizerに学習させます。

# サンプルとなるラベルデータ
labels = ['cat', 'dog', 'cat', 'fish', 'dog']

# 'cat', 'dog', 'fish' の3種類があることを学習させる
lb.fit(labels)

lbインスタンスは、内部で「このデータには ‘cat’, ‘dog’, ‘fish’ の3つのクラスが存在する」という情報(辞書)を保持した状態になりました。

ステップ3:「transform」でデータを二値化(ワンホット)ベクトルに変換する

fitで学習したルールに基づき、transform()メソッドを使って実際のデータをワンホットベクトルに変換します。

# 学習に使ったデータを変換する
transformed_labels = lb.transform(labels)

print(transformed_labels)

実行結果:

[[1 0 0]  # 'cat'
 [0 1 0]  # 'dog'
 [1 0 0]  # 'cat'
 [0 0 1]  # 'fish'
 [0 1 0]] # 'dog'

このように、3種類のクラスが、3次元の0/1ベクトル(ワンホットベクトル)に正しく変換されました。

「fit_transform」メソッドで学習と変換を同時に行う

学習(fit)と変換(transform)を一度に行うfit_transform()メソッドも用意されています。学習データに対しては、こちらを使うのが一般的で簡潔です。

lb_new = LabelBinarizer()
labels = ['cat', 'dog', 'cat', 'fish', 'dog']

# fitとtransformを同時に実行
transformed_labels = lb_new.fit_transform(labels)

print(transformed_labels)

結果は先ほどと全く同じです。


【実践】サンプルコードで動作を理解する

LabelBinarizerの挙動は、扱うクラス(ラベルの種類)が2つか、3つ以上かで少し異なります。

準備:サンプルのラベルデータ(文字列、数値)

文字列のラベルと、数値のラベルを準備します。LabelBinarizerは、数値であってもそれを「カテゴリ」として扱います。

# 2クラスのラベル(文字列)
labels_binary_str = ['yes', 'no', 'yes', 'yes']

# 3クラス以上のラベル(文字列)
labels_multi_str = ['Tokyo', 'Osaka', 'Nagoya', 'Tokyo']

# 3クラス以上のラベル(数値だがカテゴリとして扱う)
labels_multi_num = [1, 5, 10, 5, 1]

シナリオ1:2クラス(バイナリ)のラベルを変換する (例: [‘yes’, ‘no’])

まず、クラスが2種類('yes''no')の場合を見てみましょう。

lb_binary = LabelBinarizer()
result_binary = lb_binary.fit_transform(labels_binary_str)

print(f"元のデータ: {labels_binary_str}")
print("変換後のデータ:")
print(result_binary)

実行結果:

元のデータ: ['yes', 'no', 'yes', 'yes']
変換後のデータ:
[[1]
 [0]
 [1]
 [1]]

注目ポイント:

結果が [[1, 0], [0, 1], [1, 0], [1, 0]] のような2次元ベクトルではなく、**1次元のベクトル(0か1かの単一の数値)**になっています。

これはLabelBinarizerの仕様です。クラスが2つの場合、[1, 0][0, 1] のように2列使うのは冗長であるため、自動的に1列(10か)で表現されます。これは機械学習の(特に二値分類の)入力として非常に効率的です。

シナリオ2:3クラス以上(マルチクラス)のラベルを変換する (例: [‘Tokyo’, ‘Osaka’, ‘Nagoya’])

次に、クラスが3種類以上(マルチクラス)の場合です。

lb_multi = LabelBinarizer()
result_multi = lb_multi.fit_transform(labels_multi_str)

print(f"元のデータ: {labels_multi_str}")
print("変換後のデータ:")
print(result_multi)

実行結果:

元のデータ: ['Tokyo', 'Osaka', 'Nagoya', 'Tokyo']
変換後のデータ:
[[0 0 1]  # Tokyo
 [0 1 0]  # Osaka
 [1 0 0]  # Nagoya
 [0 0 1]] # Tokyo

こちらは想定通り、クラスの数(3つ)と同じ次元のワンホットベクトルに変換されています。

classes_属性:学習したクラス(順番)を確認する方法

fitを実行した後、LabelBinarizerインスタンスのclasses_属性を調べることで、どのクラスがどの順番(どの列)に対応しているかを確認できます。

# 先ほどの lb_multi を確認
print(lb_multi.classes_)

実行結果:

['Nagoya' 'Osaka' 'Tokyo']

この結果から、

  • 1列目 ([1, 0, 0]) が ‘Nagoya’
  • 2列目 ([0, 1, 0]) が ‘Osaka’
  • 3列目 ([0, 0, 1]) が ‘Tokyo’

に対応していることがわかります。(順番はアルファベット順または昇順でソートされます)


予測結果を元に戻す!「inverse_transform」の使い方

LabelBinarizerの非常に便利な機能がinverse_transformです。これはtransformの逆、つまり0/1のベクトルを元のラベル文字列に戻す機能です。

なぜinverse_transformが必要なのか?

機械学習モデルを訓練し、新しいデータで予測を行うと、モデルの出力は[0, 0, 1][0]のような数値(または確率)になります。

このままでは、人間が「この予測結果が何を意味するのか」を理解できません。

inverse_transformは、この機械語(数値ベクトル)を人間語(元のラベル)に翻訳するために使われます。

使い方:0と1のベクトルから元のラベル(’cat’など)を復元する

fitで学習済みのLabelBinarizerインスタンス(ここではlb_multi)を使います。

# モデルが予測した結果(という想定)
prediction_data = np.array([
    [0, 0, 1],  # 予測1
    [1, 0, 0],  # 予測2
    [0, 1, 0]   # 予測3
])

# 0/1のベクトルを元のラベルに戻す
original_labels = lb_multi.inverse_transform(prediction_data)

print(original_labels)

実行結果:

['Tokyo' 'Nagoya' 'Osaka']

lb_multi.classes_が [‘Nagoya’ ‘Osaka’ ‘Tokyo’] だったので、

[0, 0, 1] → ‘Tokyo’

[1, 0, 0] → ‘Nagoya’

[0, 1, 0] → ‘Osaka’

と正しく復元されていることがわかります。


【最重要】類似クラスとの違いと使い分け

Scikit-learnにはLabelBinarizerと機能が似ているクラスが多数存在し、初学者が最も混乱するポイントです。

ここでは、主要な4つのクラスとの違いを明確にします。

1. LabelBinarizer vs OneHotEncoder:決定的な違いは「入力の対象」

これが最も重要で、最も混同しやすい比較です。

  • LabelBinarizer (今回の主役)
    • 対象: 「ラベル(y)」(正解データ)。
    • 入力形式: ['a', 'b', 'c'] のような**1次元のリスト(配列)**を想定しています。
    • 目的: 主に「正解ラベル」を変換するために使われます。
  • OneHotEncoder
    • 対象: 「特徴量(X)」(説明変数、問題データ)。
    • 入力形式: [['男性', '東京'], ['女性', '大阪']] のような**2次元のリスト(配列)**を想定しています。
    • 目的: データセットの「列(特徴)」に含まれるカテゴリ(性別、出身地など)をまとめて変換するために使われます。

使い分け:

  • 機械学習の「正K答え(y)」を変換したい → LabelBinarizer
  • 機械学習の「問題(X)」の複数の列を変換したい → OneHotEncoder (詳しい記事はこちら)

2. LabelBinarizer vs Binarizer:数値とカテゴリの違い

これは、前回の記事(Binarizer)との比較です。

  • LabelBinarizer
    • 対象: カテゴリデータ(’犬’, ‘猫’など)。
    • 処理: カテゴリを「ワンホットベクトル」([1,0])に変換します。
  • Binarizer
    • 対象: 数値データ(10, 50, 100など)。
    • 処理: **しきい値(threshold)**に基づいて、単一の0か1に変換します(例: 50より大きいか小さいか)。

使い分け:

  • 「犬か猫か」を変換したい → LabelBinarizer
  • 「50点以上か未満か」を変換したい → Binarizer (詳しい記事はこちら)

3. LabelBinarizer vs LabelEncoder:ベクトルか単一整数かの違い

LabelBinarizerLabelEncoderは、どちらも「ラベル(y)」を対象とすることが多いため、これも混同しやすいです。

  • LabelBinarizer
    • 出力: ワンホットベクトル(例: [0, 0, 1])。
    • 利点: カテゴリ間に誤った順序関係を与えません。
  • LabelEncoder
    • 対象: 「ラベル(y)」。
    • 出力: 単一の整数(例: 0, 1, 2)。
    • 用途: RandomForestClassifierなど、ツリーベースのモデルの「ラベル(y)」変換には使えます(X特徴量に使うのは非推奨)。

使い分け:

  • ラベルをワンホットベクトル([0, 0, 1])にしたい → LabelBinarizer
  • ラベルを単純な整数(0, 1, 2)にしたい → LabelEncoder (詳しい記事はこちら)

4. LabelBinarizer vs MultiLabelBinarizer:マルチクラスかマルチラベルか

これは少し高度なトピックですが、名前が似ているため解説します。

  • LabelBinarizer
    • 対象: **マルチクラス(Multi-class)**分類。
    • データ例: ['犬', '猫', '犬'] (1つのサンプルには、1つの正解ラベルしかない)
  • MultiLabelBinarizer
    • 対象: **マルチラベル(Multi-label)**分類。
    • データ例: [('SF', 'アクション'), ('コメディ'), ('SF', 'ドラマ')] (1つのサンプルに、複数の正解ラベルが同時に存在しうる)
    • 出力: [[1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 1, 1]] のような形式。

使い分け:

  • 1つのサンプルに答えが1つ(例: 犬) → LabelBinarizer
  • 1つのサンプルに答えが複数あり得る(例: 映画のジャンル) → MultiLabelBinarizer

使い分けの早見表

クラス名主な対象入力形式 (想定)出力形式 (例)
LabelBinarizerラベル (y)1次元 (マルチクラス)[0, 0, 1] (ワンホット)
OneHotEncoder特徴量 (X)2次元 (複数列)[0, 1, 0, 0, 1] (ワンホット)
Binarizer特徴量 (X)2次元 (数値)[0] or [1] (しきい値)
LabelEncoderラベル (y)1次元 (マルチクラス)2 (単一整数)
MultiLabelBinarizerラベル (y)1次元 (マルチラベル)[1, 0, 1] (複数ON)

まとめ:LabelBinarizerで「ラベル」を正しく前処理しよう

今回は、Scikit-learnのLabelBinarizerについて、その基本的な使い方から、inverse_transformによる復元、そして最も重要な各種類似クラスとの違いまでを詳しく解説しました。

  • LabelBinarizerは、主に**「ラベル(y)」ワンホットエンコーディング**するために使う。
  • fitでラベルの種類を学習し、transformでベクトルに変換する。
  • inverse_transformで数値ベクトルを元のラベルに戻せる。
  • 2クラスの場合は[0][1]の1次元、3クラス以上の場合は[1, 0, 0]のような多次元ベクトルになる。
  • 特徴量(X)を扱いたい場合はOneHotEncoder数値のしきい値で分けたい場合は**Binarizer**を使う。

LabelBinarizerOneHotEncoderの違いを正しく理解することは、Scikit-learnを使った機械学習の前処理における最初の、そして最も重要なステップの一つです。

この記事を参考に、あなたのデータに最適な前処理クラスを選択し、精度の高いモデル構築に役立ててください。

コメント

タイトルとURLをコピーしました