Quantcast
Channel: pandas - よちよちpython
Viewing all articles
Browse latest Browse all 30

【Pandas】カテゴリカルデータのダミー変数化(one-hot)する pandas.get_dummies()

$
0
0

Pandasを使って文字列のカテゴリーデータを「ダミー変数化」または「one-hotエンコーディング」と呼ばれる0か1に変換する方法。
pandas.get_dummies()を使います。簡単。

はじめに

前回は、sklearnに付属するアヤメの分類データを使って、アヤメの種類の正解ラベルが文字列表記されたカテゴリーデータを数値化する方法をやりました。超簡単便利。応用でいろいろ使えそうです。
【Pandas】文字列のラベルを自動で数値化するpd.factorize(文字列配列) - よちよちpython



そのデータのアヤメの種類は3種類で、sklearn付属のものはそれぞれ0、1、2と番号で割り振ってある。数値は文字列のカテゴリカルデータを便宜上数字に置き換えているだけであり、本来は数字の大小は意味しないのですが、機械学習分類モデルによっては数値の大小が分類精度に関わる場合がある。

そこで、前処理として、カテゴリーデータを0か1だけで表現する方法が今回のダミー変数化です。

実行環境

  • Androidスマホ
  • Termux
  • Jupyter Notebook6.4.0
  • Python3.9.6
  • 外部ライブラリ
    • Pandas



データの表示

sklearn付属のアヤメの分類データで、正解ラベル(アヤメの種類)は既に0,1,2と数値化されていたと思います。
今回使うデータはネットからダウンロードしたもので、文字列で表記されております。表示します。

import pandas as pd

# アヤメのデータ (ネットからダウンロードしたもの
fname = "iris.csv"# csvを開く
df = pd.read_csv(fname)
df
sepal.lengthsepal.widthpetal.lengthpetal.widthvariety
05.13.51.40.2Setosa
14.93.01.40.2Setosa
24.73.21.30.2Setosa
34.63.11.50.2Setosa
45.03.61.40.2Setosa
..................
1456.73.05.22.3Virginica
1466.32.55.01.9Virginica
1476.53.05.22.0Virginica
1486.23.45.42.3Virginica
1495.93.05.11.8Virginica

150 rows × 5 columns

一番右の列「variety」はアヤメの種類名が文字列で入っている。1列で表されています。

種類名を確認しておきます。

# variety列のユニーク(アヤメの種類名print(df["variety"].unique())

# variety列のユニーク数print(df["variety"].nunique())
['Setosa''Versicolor''Virginica']
3

3種類。文字列。



カテゴリカルデータのダミー変数化(one-hot エンコーディング)

分類の正解ラベル(目的変数)となる「variety」列は1列です。これをダミー変数化すると、種類と同じ数の列に置き換えられます。つまり3列になる。
pd.get_dummies()を使います。



その前に、簡単な例で練習。

# リスト(適当
arr = "卵 牛乳 小麦粉 砂糖".split()

# データフレームで表示
pd.DataFrame(arr)
0
0
1牛乳
2小麦粉
3砂糖

一列です。ダミー変数化すると、↓のように増えます。

# ダミー変数化
pd.get_dummies(arr)
小麦粉牛乳砂糖
01000
10010
20100
30001

0か1で表された。その代わり、列が増えた。4種類あるので4列です。
1になっている時はその列のカラム名が指す種類であることを示しています。

しかし、もし卵以外が0なら確実に卵は1になると分かりますので、列を1つ減らせる。pd.get_dummies()の引数でdrop_first=Trueを指定すると出来る。

# ダミー変数化
pd.get_dummies(arr, drop_first=True)
小麦粉牛乳砂糖
0000
1010
2100
3001

「卵」列が消えてしまった。だが卵である場合の表現はこれだけで出来る。
「小麦粉」「牛乳」「砂糖」が0なら、残る「卵」が確実に1だと分かる。

では本番、ダウンロードしたアヤメのデータでやります。

# ダミー変数化
pd.get_dummies(df)
sepal.lengthsepal.widthpetal.lengthpetal.widthvariety_Setosavariety_Versicolorvariety_Virginica
05.13.51.40.2100
14.93.01.40.2100
24.73.21.30.2100
34.63.11.50.2100
45.03.61.40.2100
........................
1456.73.05.22.3001
1466.32.55.01.9001
1476.53.05.22.0001
1486.23.45.42.3001
1495.93.05.11.8001

150 rows × 7 columns

pd.get_dummies()の引数にデータフレーム全体を渡しました。
元々数値化された列はそのままで、「variety」1列だけが「varietyナンチャラ」の3列に変わった。

上でやったようにdrop_first=Trueで1つ次元を減らします。

# ダミー変数化
pd.get_dummies(df, drop_first=True)
sepal.lengthsepal.widthpetal.lengthpetal.widthvariety_Versicolorvariety_Virginica
05.13.51.40.200
14.93.01.40.200
24.73.21.30.200
34.63.11.50.200
45.03.61.40.200
.....................
1456.73.05.22.301
1466.32.55.01.901
1476.53.05.22.001
1486.23.45.42.301
1495.93.05.11.801

150 rows × 6 columns

「variety_Setona」が消え、3種類が2列で表現された。簡単でした。



おわりに

使用したデータは「variety」列だけが文字列の、しかもたった3種類のカテゴリカルデータだったので、ダミー変数化しても列はそれほど増えませんでした。
しかし、もしカテゴリーの数がもっと多く、さらに説明変数にもカテゴリカルデータが含まれその種類も多いとなれば、その分だけ計算量が爆発的に増加する。

たとえは、タイタニックの乗客の生存率を予測する時に使うデータでは、「性別」「客室のグレード」「客室の場所」「出身地」などの文字列カテゴリーデータを含みます。これらは体脂肪率や避難の優先度、身体能力、避難のしやすさ、などに関わる と考えられる。
このような要素とカテゴリー数が増えれば増えるほど特徴量も爆増し、計算量も増える。

果たしてそのデータは予測モデルの精度を上げる為に必要か、計算量をどうしたら削減できるか、といったことを考えるのが「特徴量エンジニアリング」というもののようです。機械学習アルゴリズムの深い理解と共にデータ内容のドメイン知識や分析目的の理解も要求されるようで非常に難解。読んでもわからん ( ;∀;)



燃料や電気代の値上がりの話がありますけど、コロナの分析みたいな「不毛」とクラスタリングされた分野のデータ分析にコンピューターパワーを使えなくなってくるのかも…と思ったり。

以上です。


Viewing all articles
Browse latest Browse all 30

Trending Articles