Python Pandasでカテゴリデータを数値に変換する:One-Hot EncodingとLabel Encodingのレシピ
はじめに
データ分析や機械学習のタスクにおいて、データセットには「性別」「商品カテゴリ」「評価(良い、普通、悪い)」といったカテゴリ(質的)データが含まれることが少なくありません。しかし、多くの統計モデルや機械学習アルゴリズムは数値データを入力として想定しており、これらのカテゴリデータをそのままでは扱えないという課題があります。
この記事では、Pythonのデータ分析ライブラリであるPandasとscikit-learnを用いて、カテゴリデータを数値データに変換する主要な二つの手法、「One-Hot Encoding(ワンホットエンコーディング)」と「Label Encoding(ラベルエンコーディング)」について、その概念から具体的なコード例、そしてそれぞれの適切な利用シーンまでを丁寧に解説します。このレシピを活用いただくことで、皆様のデータ分析プロセスにおけるカテゴリデータの扱いにまつわる課題を効率的に解決できることでしょう。
問題提起:カテゴリデータの数値変換の必要性
私たちが日常的に扱うデータには、数値で表せない「カテゴリ」の情報が豊富に含まれています。例えば、顧客の居住地、購入した商品の種類、アンケートの選択肢などがこれに該当します。これらのカテゴリデータは、それ自体が重要な情報源となりますが、コンピューターや数理モデルが直接処理するには不向きな形式であることがほとんどです。
- 機械学習モデルの要件: 多くの機械学習アルゴリズムは、入力データとして数値形式を要求します。テキスト形式のカテゴリデータは直接的な計算ができないため、事前に数値への変換が必要です。
- 分析の効率化: 数値に変換することで、統計的な手法や数理的な操作を適用しやすくなり、データ分析の幅が広がります。
- 順序性の問題: カテゴリデータの中には「低、中、高」のように順序を持つものもあれば、「赤、青、黄」のように順序がないものもあります。変換方法を誤ると、モデルが誤った解釈をしてしまう可能性があります。
このような背景から、カテゴリデータを適切に数値へと変換する技術は、データ分析において不可欠なスキルであると言えます。特に、どの変換方法を選択するかが、その後の分析結果やモデルの性能に大きく影響するため、それぞれの特性を理解することが重要です。
解決策(コードレシピ)
ここでは、One-Hot EncodingとLabel Encodingの二つの変換手法を、具体的なコード例と共に解説します。サンプルデータを用意し、それぞれの変換を適用して結果を確認します。
1. 必要なライブラリのインポート
データ操作のためにPandas、そしてLabel Encodingのためにscikit-learnのLabelEncoder
をインポートします。
import pandas as pd
from sklearn.preprocessing import LabelEncoder
2. サンプルデータの準備
顧客の情報を模したサンプルデータを作成します。このデータには、性別
(カテゴリ、順序なし)と満足度
(カテゴリ、順序あり)の2種類のカテゴリ列が含まれています。
# サンプルデータの作成
data = {
'顧客ID': [1, 2, 3, 4, 5, 6, 7, 8],
'年齢': [25, 30, 35, 40, 45, 28, 33, 38],
'性別': ['男性', '女性', '男性', '女性', '男性', '女性', '男性', '女性'],
'満足度': ['普通', '良い', '悪い', '良い', '普通', '良い', '悪い', '普通'],
'購入額': [1000, 2500, 500, 3000, 1500, 2000, 700, 1200]
}
df = pd.DataFrame(data)
print("元のデータフレーム:")
print(df)
3. One-Hot Encodingの適用
One-Hot Encodingは、順序のないカテゴリデータに適しています。各カテゴリ値を新しい列として追加し、該当する行に1、それ以外に0を割り当てます。Pandasのget_dummies
関数を使用します。
# '性別'列にOne-Hot Encodingを適用
df_onehot = pd.get_dummies(df, columns=['性別'], prefix='性別')
print("\nOne-Hot Encoding適用後のデータフレーム(性別):")
print(df_onehot)
もし元の列を削除し、かつダミー変数の多重共線性を避けるためにカテゴリの数-1のダミー変数にしたい場合は、drop_first=True
を指定します。
# '性別'列にOne-Hot Encodingを適用し、最初のカテゴリ列を削除
df_onehot_drop_first = pd.get_dummies(df, columns=['性別'], prefix='性別', drop_first=True)
print("\nOne-Hot Encoding適用後のデータフレーム(性別、drop_first=True):")
print(df_onehot_drop_first)
4. Label Encodingの適用
Label Encodingは、順序のあるカテゴリデータに適しています。各カテゴリ値を0から始まる整数値に変換します。scikit-learnのLabelEncoder
を使用します。
# '満足度'列にLabel Encodingを適用
le = LabelEncoder()
df_label = df.copy() # 元のデータフレームをコピーして操作
df_label['満足度_encoded'] = le.fit_transform(df_label['満足度'])
print("\nLabel Encoding適用後のデータフレーム(満足度):")
print(df_label[['満足度', '満足度_encoded']].drop_duplicates()) # 変換結果の対応を確認
print("\nデータフレーム全体:")
print(df_label)
# 変換された数値から元のカテゴリに戻すことも可能
print("\nエンコードされた値から元のカテゴリに戻す例:")
print(le.inverse_transform([0, 1, 2])) # 例として[0, 1, 2]を変換
コードの詳細解説
One-Hot Encoding (pd.get_dummies
)
pd.get_dummies
は、指定されたDataFrameのカテゴリ列をOne-Hotエンコードするための非常に便利な関数です。
-
df_onehot = pd.get_dummies(df, columns=['性別'], prefix='性別')
df
: 変換対象のDataFrameを指定します。columns=['性別']
: One-Hotエンコードを適用したい列名をリストで指定します。複数の列を指定することも可能です。prefix='性別'
: 生成される新しいダミー変数列の名前の接頭辞(プレフィックス)を指定します。これにより、どの元の列から生成されたか識別しやすくなります。例えば、性別_男性
、性別_女性
といった列が作成されます。
-
drop_first=True
の利用pd.get_dummies(..., drop_first=True)
は、各カテゴリ列について、最初のカテゴリに対応するダミー変数の列を削除します。例えば、「性別」が「男性」と「女性」の場合、性別_男性
または性別_女性
のどちらか一方のみを生成します。- これは「多重共線性(multicollinearity)」の問題を回避するために用いられることがあります。多重共線性とは、複数の説明変数間に高い相関がある場合に発生し、回帰モデルの推定を不安定にすることがあります。カテゴリの数-1のダミー変数で元のカテゴリ情報を完全に表現できるため、一つを削除しても情報は失われません。
One-Hot Encodingは、カテゴリに順序関係がない場合に特に有効です。「男性」「女性」のようなカテゴリに数値的な大小関係を持たせてしまうと、モデルが誤った解釈をする可能性があるため、この手法が適しています。
Label Encoding (sklearn.preprocessing.LabelEncoder
)
LabelEncoder
は、カテゴリ値を0からn_categories-1
までの整数に変換するために使用されます。
-
le = LabelEncoder()
LabelEncoder
のインスタンスを作成します。これは変換器オブジェクトであり、このオブジェクトがカテゴリと数値の対応関係を学習・保持します。
-
df_label['満足度_encoded'] = le.fit_transform(df_label['満足度'])
fit_transform
メソッドは、以下の二つの処理を一度に行います。fit
: 指定された列のユニークなカテゴリ値を学習し、それぞれに一意の整数を割り当てます。例えば「悪い」を0、「普通」を1、「良い」を2といった対応関係を内部に保持します。transform
: 学習した対応関係に基づいて、元のカテゴリ値を対応する整数値に変換します。
- 変換された結果は新しい列
満足度_encoded
としてDataFrameに追加されます。
-
le.inverse_transform([0, 1, 2])
LabelEncoder
は、変換された数値から元のカテゴリラベルに戻すinverse_transform
メソッドも提供しています。これにより、モデルの予測結果を元のカテゴリラベルで解釈することが可能になります。
Label Encodingは、カテゴリに明確な順序関係がある場合に適しています。「悪い」「普通」「良い」のように順序がある場合、その順序を数値の大小関係(例: 0, 1, 2)で表現することで、モデルがその順序性を学習できる可能性があります。 ただし、順序がないカテゴリにLabel Encodingを適用すると、モデルがその数値の大小関係に意味があると誤解してしまうリスクがあるため、注意が必要です。例えば、「赤」「青」「黄」を0, 1, 2に変換すると、モデルは「赤 < 青 < 黄」のような順序があると解釈する可能性があり、これは不適切です。
まとめ
この記事では、Pythonにおけるカテゴリデータの数値変換の重要性、そしてその主要な手法であるOne-Hot EncodingとLabel Encodingについて、実用的なコードレシピとともに詳細を解説いたしました。
- One-Hot Encodingは、順序関係のないカテゴリデータ(例: 性別、地域)を扱う際に強力なツールとなります。
pd.get_dummies
を使用することで、各カテゴリを独立した二値の特徴量に変換し、モデルがカテゴリ情報を正確に解釈できるようになります。多重共線性の回避にはdrop_first=True
の利用も検討すると良いでしょう。 - Label Encodingは、順序関係のあるカテゴリデータ(例: 満足度、学歴)に適しています。
sklearn.preprocessing.LabelEncoder
を使用することで、カテゴリの順序性を数値の大小関係として表現し、モデルがその情報を利用することを可能にします。
これらの変換手法を適切に使い分けることで、非数値データが混在するデータセットにおいても、多くの機械学習モデルや統計分析手法を適用することが可能になります。ぜひ、ご自身のデータ分析タスクにこれらのレシピを応用し、より深い洞察を得るための一助としてください。