LabelEncoderの「y contains previously unseen labels」は、学習した対応表にない値を変換しようとしたときに起きます。 まず、その列が予測したい目的変数yなのか、予測に使う説明変数Xなのかを確認してください。Xの未知カテゴリを扱う設定を、未知の正解ラベルへそのまま流用することはできません。

この記事は、分類モデルの学習と検証へ進み、文字列ラベルを整数へ変換する段階で止まった人向けです。架空の問い合わせ種別を使い、エラーが出る例と、エラーは出ないのに番号の意味が変わる例を比較します。モデルの性能を上げる手法ではなく、変換と評価の前提を揃える確認手順です。

公式情報の確認日:2026年10月28日。LabelEncoder、OrdinalEncoder、前処理でのデータ漏洩を避ける説明を参照しています。確認時の安定版資料とコード実行環境はscikit-learn 1.9.1、Python 3.12.14です。

学習したbillingとusageの対応表にrefundは含まれない。yなら分類対象と学習を再確認し、Xなら特徴量用エンコーダーの未知値設定を検討する。
未知の値へ番号を付けられることと、その種類をモデルが学んだことを区別します。

LabelEncoderの未知ラベルは、対応表と列の役割から調べる

LabelEncoderは目的変数yに使う道具と確認する

目的変数yは、モデルに予測させたい正解の列です。問い合わせならbillingかusageか、商品なら種別名などが該当します。一方、説明変数Xは、入力文の特徴、地域、契約区分といった予測に使う材料です。同じ文字列の列でも、モデルの中での役割は異なります。

公式資料ではLabelEncoderは目的変数を符号化するもので、入力Xには使わないと説明されています。過去のサンプルには、表のカテゴリ列を一列ずつLabelEncoderへ渡す例もあります。コードを写す前に、その例が何のために書かれ、現在の自分の列と役割が一致するかを見てください。

この教材では、billingとusageを問い合わせの正解種別yとして扱います。どちらが重要か、どちらが大きいかという順序はありません。0と1は識別のための番号であり、usageがbillingの二倍という量ではありません。数字へ変換した後もラベルの意味を対応表へ残します。

文字列の列を変換する前の使い分け
対象検討する道具確認すること
予測したい正解yLabelEncoder、または推定器が扱える元ラベル一つの対応表を再利用。未知yは学習範囲を確認
説明変数XのカテゴリOrdinalEncoderやOneHotEncoder順序の意味、未知値、欠損、後続モデルとの相性
表示用の名前対応辞書やinverse_transform内部番号と表示名が同じ版で対応しているか

使う推定器が文字列の目的変数に対応しているなら、LabelEncoderによる手動変換自体が不要な場合もあります。「機械学習だから全列を整数にする」と一律に決めず、利用する推定器の入力要件を確認しましょう。本稿は、番号へ変換する必要がある場面で対応表を点検する教材です。

Xの変換で未知カテゴリがゼロベクトルになる理由は、OneHotEncoderの未知カテゴリ確認で別に扱っています。今回は特徴量の列を増やす方法より、LabelEncoderを選ぶ前提と、正解ラベルの対応関係へ範囲を絞ります。

四件の学習ラベルから、未知のrefundでエラーを再現する

学習側の正解はbilling、usage、billing、usageの四件です。LabelEncoderをfitすると、classes_へ文字列の対応表が保持されます。この教材ではbillingが0、usageが1です。元データへ最初に現れた順番をそのまま採番する、という前提で番号を決めないでください。

検証側にはusage、refund、billingの三件を用意します。refundは学習側にない種類なので、そのままtransformできません。例外を捕まえる例も教材へ含め、どの値が未知だったかをclasses_と入力から確認します。

from sklearn.preprocessing import LabelEncoder

y_train = ["billing", "usage", "billing", "usage"]
y_test = ["usage", "refund", "billing"]
le = LabelEncoder().fit(y_train)
assert le.classes_.tolist() == ["billing", "usage"]
assert le.transform(y_train).tolist() == [0, 1, 0, 1]
assert le.transform(["usage", "billing"]).tolist() == [1, 0]

try:
    le.transform(y_test)
except ValueError as exc:
    assert "unseen labels" in str(exc)
    print("未知のrefundを含むため変換できません")
else:
    raise AssertionError("未知ラベルの入力を再確認してください")

これは、問い合わせ文の内容を理解できなかったために出るエラーではありません。変換の段階で、対応表にrefundという名前がない状態です。入力の型や綴りが間違っているのか、本当に新しい分類なのかで、その後の直し方が変わります。

学習ラベルにrefundを追加すれば対応表の問題は変わりますが、それだけで分類器にrefundの見分け方が身につくわけではありません。分類器の訓練にその種類の例が含まれるか、評価用の正解が定義されているかを別に確認する必要があります。

検証側でfitし直すと、動いても番号の意味がずれる

エラーを見て、検証側にもfit_transformを使いたくなるかもしれません。別のLabelEncoderを検証側でfitすれば、その三種類を番号へ変換できます。しかし学習側と検証側で別の対応表ができるため、同じラベルでも番号が一致するとは限りません。

この例では、学習側のusageは1ですが、検証側を別々にfitするとusageは2になります。さらに検証側の1はrefundです。モデルが出した1を、学習時のusageとして読むのか、検証時のrefundとして読むのかで意味が変わります。

test_encoder = LabelEncoder().fit(y_test)
assert test_encoder.classes_.tolist() == ["billing", "refund", "usage"]
assert le.transform(["usage"]).item() == 1
assert test_encoder.transform(["usage"]).item() == 2
assert le.inverse_transform([1]).item() == "usage"
assert test_encoder.inverse_transform([1]).item() == "refund"
print("同じ1でも、別の対応表では違う種別になります")

数字の配列として同じ形をしていても、意味が揃っているとは限りません。正解と予測を比較する前に、同じ対応表から作った番号かを確認しましょう。行数だけ合わせて比較すると、計算は完了しても別の種別同士を比べた評価になる恐れがあります。

同じエンコーダーへ検証側をfitし直す方法も、元のclasses_を上書きします。学習済みモデルの出力は古い番号の意味で、表示だけが新しい対応表になる問題が起こり得ます。学習時に決めた対応表を再利用することが、変換と逆変換の一貫性につながります。

前処理のfitとtransformを分ける考え方は、StandardScalerを学習側だけでfitする確認にも共通します。ただし目的変数の分類体系と、特徴量から平均などを学ぶ処理は同じものではありません。何を固定し、何をデータから学ぶかを区別します。

未知ラベルを先に抽出して、空白や表記違いと分ける

未知の値を検出するだけなら、変換を試す前にclasses_との差を確認できます。今回の三件ではrefundが一件です。未知の種類数と未知の行数は別の数なので、同じ未知値が十行あるケースでは、両方の内訳を残すと原因を追いやすくなります。

文字列の空白も目で見落としやすい原因です。usageと末尾に空白があるusageは、同じ文字列ではありません。例外メッセージを眺めるだけでなくrepr形式で表示すると、空文字や前後の空白を確認できます。実データに個人名などがある場合は、公開ログへ値を出さず、短い架空例へ置き換えます。

known = set(le.classes_)
unknown = sorted(set(y_test) - known)
mask = [value in known for value in y_test]
assert unknown == ["refund"]
assert mask == [True, False, True]
assert sum(mask) == 2 and len(mask) == 3

messy = ["usage", "usage ", "", "refund"]
print([repr(v) for v in messy if v not in known])
assert "usage " not in known

空白を取り除くことが正しいかも、元データの規則次第です。担当者が入力する種別欄なら表記揺れとして修正できる場合がありますが、空白を含む識別子では別の意味かもしれません。検証側だけを整形せず、学習時と同じ整形規則を適用しているかを確認します。

未知値が空文字だけなら、新カテゴリとして登録するより、元の未入力処理を見直す方が適切な場合があります。逆にrefundが新しいサービス種別なら、既存ラベルへの置換で隠すと業務上の情報を失います。値が似ているかではなく、同じ分類として扱ってよい根拠を持ちましょう。

全カテゴリを先に登録する場合も、モデルの学習範囲は別に見る

業務で分類体系が事前に確定している場合は、学習データに偶然出現した名前だけでなく、その体系を対応表の基準にする設計もあります。これはテストデータを見て、その都度都合よく種類を足す運用とは区別します。分類の定義と版を先に決めることが前提です。

例えばbilling、refund、usageが事前に定義された三種類なら、catalogという一覧から番号を用意できます。ただし今回の学習用正解四件にはrefundがありません。変換を通せるようになっても、学習データへrefundの例が追加されたわけではない点に注目してください。

catalog = ["billing", "refund", "usage"]
catalog_encoder = LabelEncoder().fit(catalog)
encoded_train = catalog_encoder.transform(y_train)
encoded_test = catalog_encoder.transform(y_test)
assert encoded_train.tolist() == [0, 2, 0, 2]
assert encoded_test.tolist() == [2, 1, 0]
assert set(encoded_train) == {0, 2}
assert 1 not in encoded_train  # refundの訓練例は増えていない

この状態で性能を評価するときは、refundの正解を含む評価が何を意味するかを確認します。未学習の種類を通常の分類器がどう扱うかは推定器の設計にもよります。単に番号が存在することを理由に、新しい分類への対応が完了したと説明しないでください。

学習用と検証用を結合してから前処理をfitする方法を、未知値対策の標準手順として一律には勧めません。Xなら検証側の情報を前処理へ取り込む問題があり、yでも分類体系を事後変更すると評価条件が変わります。事前の分類定義と、観測データから学ぶ処理を分けて記録します。

Xの未知カテゴリと、未知yを含む評価を分けて扱う

Xのカテゴリなら、OrdinalEncoderの未知値設定を検討する

地域などの説明変数Xを整数へ変換したいなら、OrdinalEncoderのような特徴量用の道具を比較します。これは複数の特徴列を二次元の表として受け取り、列ごとのカテゴリを扱えます。LabelEncoderのtransformが通らないから同じ名前の引数を付ける、という手順ではありません。

以下はEastとWestを持つ学習側のXに対し、検証側にNorthが現れる教材です。handle_unknownをuse_encoded_value、unknown_valueを-1にすると、未知カテゴリを-1として表現できます。ここでの-1は、新しい地域を正しく予測したという意味ではなく、既知の地域にないという記号です。

from sklearn.preprocessing import OrdinalEncoder

X_train = [["East"], ["West"], ["East"]]
X_test = [["North"], ["East"]]
enc = OrdinalEncoder(
    handle_unknown="use_encoded_value", unknown_value=-1
).fit(X_train)
assert enc.categories_[0].tolist() == ["East", "West"]
assert enc.transform(X_test).ravel().tolist() == [-1.0, 0.0]
assert enc.inverse_transform([[-1], [0]]).tolist() == [[None], ["East"]]

この整数表現を後続のモデルがどう使うかは、別に考えます。名義カテゴリへ0と1を割り当てることで、モデルによっては大小や距離の意味を持ち込んでしまいます。OneHotEncoderとの比較や、利用する推定器の入力要件を確認して、エラーが消えるだけで道具を決めないようにします。

unknown_valueは既知カテゴリに割り当てる値と衝突しないものにします。また、欠損と未知カテゴリを同じ記号にするかは目的次第です。今回は欠損を含めず、既知のEastとWest、未知のNorthだけを確認しています。実データに欠損が来る場合は、別のテストとして追加してください。

OrdinalEncoderを使えば未知のyも学習済みの分類にできる、という解釈はしないでください。この例はXの表現方法を決めるものです。yのrefundを-1にして通常の評価へ混ぜても、分類器にrefundを学習させたことにはなりません。

未知の正解を除いた評価では、全三件の性能と言わない

未知の正解が含まれる評価データでは、まずその件数を報告します。原因調査として既知ラベルだけを取り出すことはできますが、その結果は既知の範囲に限った評価です。全件を評価した結果として報告すると、難しいケースを除いて良く見せたことになりかねません。

今回、既知の二件について正解と予測が一致する仮定を置くと、既知範囲のaccuracyは1.0になります。しかし元の評価対象は三件あり、refundの一件はその計算に含まれていません。実測の成果やモデル性能の主張ではなく、分母の違いを説明する架空の例です。

from sklearn.metrics import accuracy_score

predicted = ["usage", "billing", "billing"]  # 説明用の仮定
known_true = [v for v, ok in zip(y_test, mask) if ok]
known_pred = [v for v, ok in zip(predicted, mask) if ok]
assert accuracy_score(known_true, known_pred) == 1.0
assert accuracy_score(y_test, predicted) == 2 / 3
print({"all_rows": 3, "known_rows": 2, "unknown_rows": 1})

正解と予測を文字列のまま比較した全三件では、refundの一件を誤りとして数え、二件正解です。一方、実際のプロジェクトで未知の種類をどう採点するかは、用途と評価仕様によって決める必要があります。本稿の数字だけを、未知カテゴリ対策を施したモデルの実績として使わないでください。

未知ラベルを「その他」へまとめる方法も、業務上その分類が定義され、訓練例と評価基準がある場合に検討します。エラーを止めるためだけに正解を書き換えると、何を予測するモデルかが変わります。変更前後の分類定義と、各種類の件数を記録してください。

train_test_splitでクラス件数を確認する記事も合わせて、分割後に学習側から種類が消えていないかを点検します。件数が少ない種類を含めるための分割調整と、存在しない訓練例を補ったことは別の話です。

inverse_transformにも、同じ対応表と有効な番号を使う

モデルの結果を人が読めるラベルへ戻すときは、学習時に使った対応表でinverse_transformします。別の表で戻せば、先ほどの例のように番号1がusageにもrefundにもなります。予測が正しくても、表示側の対応表が違えば別の種別を表示してしまいます。

さらに、対応表にない番号を逆変換することはできません。今回のleは0と1だけなので、99を渡すと例外になります。これを「99という新種別がある」と解釈するのではなく、モデルと対応表の版、出力の範囲、入力の取り違えを調べます。

pred_code = le.transform(["usage", "billing"])
assert le.inverse_transform(pred_code).tolist() == ["usage", "billing"]
try:
    le.inverse_transform([99])
except ValueError:
    print("この対応表に99はありません")
else:
    raise AssertionError("逆変換する番号の範囲を確認してください")

番号をCSVへ保存して他の担当者へ渡すなら、対応表の版やラベル名も合わせて保管します。「1はいつもusage」と文書へ固定してしまうと、分類体系の変更や再学習で番号が変わったときに混乱します。利用する表と、その表を作った条件を結び付けることが大切です。

エンコーダーを保存して読み込む場合も、出所不明の学習済みファイルを実行環境へ読み込むことは避けます。まずこの教材のように、自分で作った短い対応表で往復を確認してください。保存方法そのものより、同じ値が同じ名前へ戻るという確認を先に完成させましょう。

対応表・未知値・評価範囲を、一つの確認メモへ残す

確認メモには、列の役割がXかyか、fitしたデータの範囲、classes_の内容、未知の種類と件数、逆変換に使う対応表を並べます。エラーを消した操作だけを残すと、あとから評価値が変わった理由を追いにくくなります。前処理が何を変えたかも説明できる状態を目指します。

今回なら「yの対応表はbilling・usage。検証三件のうちrefund一件が未知。検証側の別fitは採用しない。既知二件だけの計算には対象範囲を明記」と書けます。全三件を対象にするには分類体系、学習例、未知種類の評価方法を確認する必要があります。

対応表の確認は、新しいデータを受け取るたびに行います。たとえ列名が以前と同じでも、入力元で種別が追加されることがあります。未知の種類がゼロだった回も、その日付と対象件数を残しておくと、どの回から新しい値が入ったかを比較できます。エラーが出た日だけ調べる運用より、分類定義と観測データの違いを追いやすくなります。

自分のデータへ置き換えるときは、ラベルを増やすだけでなく、順序を変える、末尾空白を入れる、片方の分割から一種類をなくす、逆変換へ範囲外の番号を入れる、といったケースを試します。正常な往復だけでは、対応表の取り違えを見つけにくいためです。

整数化後の配列を見ただけで安心せず、元の名前、変換後の番号、戻した名前を数件並べます。元の名前と戻した名前が一致しない場合は、モデルの精度を調べる前に、前処理と表示の対応を確認します。この順序なら、改善する対象を間違えにくくなります。

機械学習の前処理を一通り学び直したい場合は、機械学習スクールの予習チェックと独学とスクールを比較する基準を使い、ラベルの役割や評価条件を自分で説明できるかを確認してください。小さな再現例で解決したなら、すぐに講座へ申し込まず、同じ確認を次の教材へ応用する選択もあります。

よくある質問と、未知ラベル対応の完了条件

質問と回答

Q. LabelEncoderにhandle_unknownを指定できますか?
A.

現行のLabelEncoderには、その未知値処理を指定する引数はありません。まず対象がyかXかを確認し、XならOrdinalEncoderなどの特徴量用の道具と設定を比較します。

Q. 検証側でもfit_transformすれば解決しますか?
A.

別の対応表ができ、同じラベルの番号が変わる場合があります。教材ではusageが学習側で1、検証側の別fitで2です。エラーが出なくても同じ意味の番号とは限りません。

Q. 学習用と検証用を全部合わせてfitすべきですか?
A.

未知値対策として一律には勧めません。事前に決めた分類体系と、観測した検証データから情報を取り込む処理を区別してください。変換できても、未学習クラスの訓練例は増えません。

Q. 未知の正解ラベルを削除して評価してよいですか?
A.

原因調査で既知範囲の評価を計算する場合も、除外した件数と対象範囲を明記します。教材の既知二件の結果を、元の三件全体の性能と報告してはいけません。

Q. OrdinalEncoderの-1は新しいクラスを学んだ意味ですか?
A.

この例ではXの既知カテゴリにない値を表す記号です。新しいyのクラスを学習した意味ではありません。後続のモデルでその表現をどう扱うかも別に確認します。

Q. inverse_transformでエラーになるときは?
A.

対応表にない番号、別のエンコーダー、モデルと対応表の版の違いを確認します。元ラベルから番号へ変換し、同じ表で元へ戻るかを短い例で照合してください。

作業を終える前に、未知のrefundがどこから来たか、既存ラベルの表記違いなのか、業務に追加された分類なのかを確認します。その理由で、整形規則を直すのか、分類体系や訓練データを見直すのかが変わります。例外を消す設定だけを探さず、列の意味へ戻って判断しましょう。

完了の目安は、学習と検証で同じ対応表を使い、未知値の内訳を説明でき、評価した対象と表示ラベルが一致していることです。今回の四件と三件の例でその違いを確認してから、実データの前処理へ適用してください。

目的変数と説明変数の使い分けから、機械学習の前処理を体系的に学び直したい場合は、Python WinnerのAI・機械学習マスターなども検討先です。公式の講座案内だけで、このLabelEncoderの課題を個別に扱えると判断せず、持ち込める質問の範囲、演習の対象、必要なPython・数学の知識、受講総額を申込前の受講相談で確認しましょう。すでに今回の往復確認を説明できるなら、次は異なる分類データで独学を続ける方法もあります。(公式情報確認日:2026年10月28日、Python Winner公式)。

広告:【PythonWinner】