pandas.DataFrameのマルチラベルを簡単にバイナライズする方法


はじめに

機械学習をしていると、付与ラベルをone-hotベクトルに変換する必要がよく発生するのですが、pandasDataFramescikit-learnMultiLabelBinarizerを使えば簡単に変換できることを知りました。備忘録として記事にします。

変換対象のデータ

以下の表データが格納されたcsvファイル(sample.csv)をone-hotベクトルとしてバイナライズすることを目指します。ラベルデータは、セミコロンがデリミターとして格納されていることを想定します。

text labels
あいうえお ひらがな
カキクケコ カタカナ
ドラえもん カタカナ;ひらがな

バイナライズ後のデータは以下の通りです。labels列のデータはリスト形式になっているので、簡単に機械学習器のターゲット変数に入力することが可能になります。

text labels
あいうえお [1, 0]
カキクケコ [0, 1]
ドラえもん [1, 1]

数行でマルチバイナライズされたone-hotベクトル列を作成することができました。

ラベルデータのリスト化

リスト化はPythonの標準機能であるsplitを使えば簡単にできます。

>>> df = pd.read_csv('sample.csv')
>>> df
    text     labels
0  あいうえお       ひらがな
1  カキクケコ       カタカナ
2  さしスセソ  ひらがな;カタカナ
>>>
>>> df['labels'] = df['labels'].apply(lambda x: x.split(';'))
>>> df
    text        labels
0  あいうえお        [ひらがな]
1  カキクケコ        [カタカナ]
2  さしスセソ  [ひらがな, カタカナ]

この時点でlabels列に格納されているのは文字列ではなく配列になっています。

マルチバイナライズ化

マルチバイナライズは、scikit-learnMultiLabelBinarizerというクラスを使って行います。ラベルのリストはmlb.classes_という変数で確認することができます。

>>> from sklearn.preprocessing import MultiLabelBinarizer
>>>
>>> mlb = MultiLabelBinarizer()
>>>
>>> mlb.fit_transform(df['labels'])
array([[1, 0],
       [0, 1],
       [1, 1]])
>>> mlb.classes_
array(['ひらがな', 'カタカナ'], dtype=object)

Pandasに再格納

ziplistを使えば、pandas.DataFrameに再格納が可能です。

>>> df = pd.DataFrame(list(zip(df['text'], mlb.fit_transform(df['labels']))))
>>> df.columns = ['text', 'labels']
>>> df
    text  labels
0  あいうえお  [1, 0]
1  カキクケコ  [0, 1]
2  さしスセソ  [1, 1]

参考文献