ぺんぎんさんのおうち

日記です。たまに日記じゃないこともあります。

Python pandasでラベルを数値に変換

前書き

機械学習において, 正解データのラベルが数値ではなく文字列("りんご", "ぶどう" など)になっていることがある.

2値分類であれば

y = np.where(y == "りんご", 0, 1); where y consists of ("りんご", ..., "ぶどう", ...)

とできるが, 3クラス以上の場合はどうすればいいのだろう. 助けて.

TL;DR

pandas.Series.map()pandas.Series.apply() を使う.
pandas関係のエントリはたくさんあるので探そう.



pd.get_dummies(df) をつかうと

["りんご",
"りんご",
"ぶどう",
"みかん",
"みかん",]

が

1 0 0
1 0 0
0 1 0
0 0 1
0 0 1

こんな感じになる. そうじゃない.

3クラス以上のラベルを数値に変換できるメソッドがあった気もするけれど, 見つからなかったので代替策としてpandasのmapとapplyを使うことにした.



pandas.Series.apply()

def label_to_int(label):
    if label == "りんご": return 0
    elif label == "ぶどう" : return 1
    elif label == "みかん" : return 2

    ... 

df[idx] = df[idx].apply(label_to_int)
# idxはラベルがある列番号

.apply()メソッドにラベル変換用の関数を渡してあげる.
もちろんlambdaを渡すこともできるが, クラス数が多くなってきたら後述のmap()を使った方が良さそう.

pandas.Series.map()

mapped = {"りんご" : 0, "ぶどう" : 1, "みかん" : 2}
df[idx] = df[idx].map(mapped)
# idxはラベルがある列番号

.map()メソッドに {変化させたいラベル:対応する値} の辞書を渡してあげれば良い.

有用かもしれないし無用かもしれないもの

変換されるラベルが2値のときは実数に, 3値以上は整数に変換される. なんか気持ち悪い.
f:id:ushiromiya3:20180601194751p:plain f:id:ushiromiya3:20180601195032p:plain 追記: set(y)ではなくnp.unique(y)を使った方が良い.

applyもmapも, 一致しない(指定されていない)ラベルはnanに置き換わる. 誤字とか気をつけよう.