PythonのScikit-learn(sklearn)を使って機械学習モデル、特に「分類(Classification)」タスクを扱おうとしたとき、「ValueError: unknown string format」や「could not convert string to float」といったエラーに遭遇したことはありませんか?
これは、モデルが「犬」「猫」「鳥」のような**文字列(カテゴリ)の目的変数(y)**を直接学習できないために発生します。
この記事では、この問題を解決するためのScikit-learnのLabelEncoder(ラベルエンコーダー)に焦点を当てます。
LabelEncoderの基本的な使い方から、変換した数値を元に戻すinverse_transformの方法、そして**最も重要な「使ってはいけないケース」**まで、初心者から中級者の方にも分かりやすく、具体的なコード例と共に徹底解説します。
この記事を読み終えれば、LabelEncoderをどのような場面で、どのように使うべきかが明確になり、自信を持ってデータの前処理を行えるようになります。
本記事で解説するLabelEncoderに関する公式ドキュメントはこちらです。
はじめに:Scikit-learnのLabelEncoderとは?
LabelEncoderは、Scikit-learnのpreprocessingモジュールに含まれるクラスで、カテゴリカルなデータを数値に変換するために使われます。
LabelEncoderの基本的な役割
LabelEncoderの主な役割は、文字列やカテゴリカルな値(ラベル)を、0から始まる連続した整数に変換することです。
例えば、「りんご」「みかん」「バナナ」という3種類のカテゴリを持つデータがあった場合、LabelEncoderはこれらを以下のように数値に変換します。
- 「りんご」 →
0 - 「みかん」 →
1 - 「バナナ」 →
2
(※どのカテゴリがどの数値になるかは、内部的にソートされた順序によります)
なぜ変換が必要なのか?
機械学習モデルの多くは、内部で数学的な計算を行います。そのため、目的変数(y、つまりモデルに予測させたい答え)が「りんご」や「みかん」といった文字列のままでは、学習や評価の計算ができません。
LabelEncoderは、これらの文字列ラベルをモデルが理解できる数値形式(0, 1, 2…)に変換するために使用されます。これは、特に**分類(Classification)**モデルで必須となる前処理ステップです。
※分類モデルには、ロジスティック回帰や決定木、ランダムフォレストなどがあります。
LogisticRegression(ロジスティック回帰)に関する詳しい記事はこちらです。DecisionTreeClassifier(決定木)に関する詳しい記事はこちらです。RandomForestClassifier(ランダムフォレスト)に関する詳しい記事はこちらです。
LabelEncoderによる変換イメージ
具体的に見てみましょう。もし目的変数yが以下のようなリストだった場合:
y = ['cat', 'dog', 'cat', 'bird', 'dog']
LabelEncoderを適用すると、以下のように数値の配列に変換されます。
y_encoded = [1, 2, 1, 0, 2]
(この例では、'bird'が0、'cat'が1、'dog'が2に割り当てられています)
LabelEncoderの基本的な使い方 (fit, transform)
LabelEncoderの使い方は非常にシンプルです。基本はfit(学習)とtransform(変換)の2ステップです。
必要なライブラリのインポート
まず、Scikit-learnからLabelEncoderをインポートします。
from sklearn.preprocessing import LabelEncoder
import pandas as pdサンプルデータの準備
ここでは、機械学習の分類問題で「目的変数(y)」として使われることを想定し、動物の名前が入ったPandas Series(またはリスト)を準備します。
# サンプルデータ(目的変数yを想定)
y = pd.Series(['cat', 'dog', 'cat', 'bird', 'dog', 'cat'])
print("元のデータ (y):")
print(y)実行結果:
元のデータ (y):
0 cat
1 dog
2 cat
3 bird
4 dog
5 cat
dtype: objectインスタンス化と学習 (fit)
まず、LabelEncoderのインスタンス(実体)を作成します。
次に、fitメソッドを使って、データyに「どのような種類のカテゴリが存在するか」を学習(記憶)させます。
# 1. LabelEncoderのインスタンスを作成
le = LabelEncoder()
# 2. データを学習(fit)させる
# どのようなカテゴリが存在するかを記憶する
le.fit(y)
# 学習したクラス(カテゴリ)を確認
print("学習したクラス:", le.classes_)実行結果:
学習したクラス: ['bird' 'cat' 'dog']classes_属性を見ると、'bird', 'cat', 'dog'の3種類が存在することをエンコーダが学習したことがわかります。この配列の**インデックス番号(0, 1, 2)**が、変換後の数値に対応します。
データを変換 (transform)
fitで学習したルールに基づき、データを実際に数値ラベルに「変換(transform)」します。
# 3. データを変換(transform)する
y_encoded = le.transform(y)
print("\n変換後のデータ (y_encoded):")
print(y_encoded)実行結果:
変換後のデータ (y_encoded):
[1 2 1 0 2 1]元のデータ['cat', 'dog', 'cat', 'bird', 'dog', 'cat']が、classes_の順序(0=’bird’, 1=’cat’, 2=’dog’)に従って、正しく数値配列[1 2 1 0 2 1]に変換されました。
fit_transform:学習と変換を同時に行う方法
fitとtransformは、多くの場合セットで実行されます。fit_transformメソッドを使えば、この2つのステップを1行で実行でき、コードが簡潔になります。
# 別のデータで試す
y_fruits = ['apple', 'orange', 'apple', 'banana']
# インスタンス化
le_fruits = LabelEncoder()
# fitとtransformを同時に実行
y_fruits_encoded = le_fruits.fit_transform(y_fruits)
print("fit_transformによる変換結果:")
print(y_fruits_encoded)
print("学習したクラス:", le_fruits.classes_)実行結果:
fit_transformによる変換結果:
[0 2 0 1]
学習したクラス: ['apple' 'banana' 'orange']変換した数値を元に戻す方法 (inverse_transform)
機械学習モデルの予測が完了すると、結果は[0, 1, 2]のような数値で出力されます。このままでは人間にとって分かりにくいため、元の「りんご」「みかん」「バナナ」のような文字列ラベルに戻す作業が必要になります。
inverse_transformの役割
inverse_transformメソッドは、LabelEncoderが学習したルール(classes_)に基づき、数値を元のカテゴリ名(文字列)に逆変換します。
これは、モデルの予測結果を解釈する際に非常に重要です。
具体的なコード例
先ほどfit_transformしたle_fruitsエンコーダと、その結果y_fruits_encodedを使ってみましょう。
# y_fruits_encoded は [0 2 0 1]
# le_fruits は ['apple' 'banana' 'orange'] を学習済み
# 予測結果が数値 [0, 1, 2] で得られたと仮定する
y_pred_numeric = [0, 1, 2, 0]
# 数値を元の文字列ラベルに逆変換
y_pred_labels = le_fruits.inverse_transform(y_pred_numeric)
print("逆変換後の予測ラベル:")
print(y_pred_labels)実行結果:
逆変換後の予測ラベル:
['apple' 'banana' 'orange' 'apple']数値[0, 1, 2, 0]が、学習済みの対応関係(0=’apple’, 1=’banana’, 2=’orange’)に従って、正しく文字列['apple' 'banana' 'orange' 'apple']に戻されました。
学習したクラス(カテゴリ)の確認方法
すでに出てきていますが、classes_属性を参照することで、数値とカテゴリの対応関係をいつでも確認できます。これはデバッグや結果の確認に役立ちます。
# le_fruits の対応関係を再確認
print("le_fruits のクラス (インデックスと対応):")
print(le_fruits.classes_)
# [0] = 'apple', [1] = 'banana', [2] = 'orange'【最重要】LabelEncoder使用上の注意点と落とし穴
LabelEncoderは非常に便利なツールですが、使い方を誤ると、機械学習モデルの精度を著しく低下させる重大な落とし穴があります。
注意点1:特徴量(X)への使用は原則非推奨
LabelEncoderの最も一般的な誤用は、目的変数(y)ではなく、特徴量(X)(モデルの入力データ)に対して使ってしまうことです。
例えば、以下のような特徴量データXがあったとします。
| 国名 |
| Japan |
| USA |
| China |
| USA |
これをLabelEncoderで変換すると、[1, 2, 0, 2]のようになります。(0=’China’, 1=’Japan’, 2=’USA’)
なぜ非推奨? モデルが「順序」を誤って学習するリスク
問題は、モデルがこの[1, 2, 0, 2]という数値を**「量の大小」や「順序関係」**として解釈してしまうことです。
モデルは、「China(0) < Japan(1) < USA(2)」や、「China(0) + Japan(1) = 1 (つまりJapan?)」のような、本来存在しないはずの数学的な関係を学習しようと試みてしまいます。
「国名」には順序や大小関係はありません。このような誤った学習は、モデルの予測精度に悪影響を与えます。
特徴量(X)のカテゴリ変数を変換したい場合は?
では、特徴量(X)のカテゴリ変数はどうすればよいのでしょうか? 答えは、その特徴量の性質によって異なります。
- 順序関係がない場合(例:国名、色、性別)LabelEncoderではなく、**OneHotEncoder**を使います。OneHotEncoderは、カテゴリを[1, 0, 0]や[0, 1, 0]のようなベクトルに変換するため、モデルが誤った順序関係を学習するのを防ぎます。
OneHotEncoder(ワンホットエンコーダー)に関する詳しい記事はこちらです。
- 順序関係がある場合(例:[S, M, L], [低, 中, 高])この場合に限り、OrdinalEncoderという別のエンコーダを使います。これはLabelEncoderと似ていますが、[‘S’, ‘M’, ‘L’]のような意味のある順序を[0, 1, 2]のように正しくマッピングするために設計されています。
LabelEncoderとOneHotEncoderの違いと使い分け
初心者の方が最も混乱しやすいのが、LabelEncoderとOneHotEncoderの違いです。ここで明確に整理しておきましょう。
変換結果の違い
データ['Red', 'Green', 'Blue']を変換した場合の結果を比較します。
- LabelEncoderの変換結果(1次元配列):[2, 1, 0] (例: 0=’Blue’, 1=’Green’, 2=’Red’)→ 順序関係(0 < 1 < 2)を暗示してしまう
- OneHotEncoderの変換結果(2次元配列/行列):[[0, 0, 1], [0, 1, 0], [1, 0, 0]]→ カテゴリ間に順序関係を持たない
主な使い道の違い:「y」か「X」か
この変換結果の違いから、使い道は明確に分かれます。
- LabelEncoder主に目的変数 (y) に対して使用します。(yが[0, 1, 2]になっても、モデルはそれを「クラス0」「クラス1」「クラス2」と正しく分類対象として扱えるため、順序関係は問題になりません)
- OneHotEncoder主に特徴量 (X) に対して使用します。(モデルに誤った順序関係を学習させないため)
使い分け早見表
| エンコーダ | 主な使用対象 | 変換例 [‘Red’, ‘Green’] | 特徴 |
LabelEncoder | 目的変数 (y) | [1, 0] | 1次元の数値に変換。特徴量(X)には原則使わない |
OneHotEncoder | 特徴量 (X) | [[1, 0], [0, 1]] | 0と1のベクトル(行列)に変換。順序関係を持たせない |
まとめ:LabelEncoderは「目的変数(y)」に正しく使おう
今回は、Scikit-learnのLabelEncoderについて、その基本的な使い方から注意点までを詳しく解説しました。
この記事の最も重要なポイント:
LabelEncoderは、カテゴリ(文字列)を0から始まる整数に変換するツールです。fitで学習し、transformで変換、inverse_transformで元に戻します。- 最大の注意点は、
LabelEncoderを特徴量(X)に使ってはいけないことです。モデルが誤った順序関係を学習してしまいます。 LabelEncoderの主な用途は、**分類問題の目的変数(y)**の変換です。- 特徴量(X)のカテゴリ変数を変換したい場合は、
OneHotEncoder(順序なし)やOrdinalEncoder(順序あり)を使います。
LabelEncoderはシンプルですが、誤用するとモデルの精度に直結する重要な前処理ステップです。ぜひ本記事を参考に、「目的変数(y)にのみ使う」というルールを守り、正しく活用してください。


コメント