pandasでカテゴリ変数を数値データに変換する

pandasのDataFrameに格納されているカテゴリ変数(質的データ)を数値データ(量的データ)に変換します。

目次

  1. カテゴリ変数に単純に数値を割り当てる弊害
  2. one-hotエンコーディング(ダミー変数化)してみる
  3. 特定の列だけダミー変数化する
  4. 最初のカテゴリを除外する
  5. 欠損値もダミー変数化する
  6. 主な関数やメソッド

カテゴリ変数に単純に数値を割り当てる弊害

下表は、penguins.csvというペンギンの分類データのデータセットの一部です。

species

island

bill_length_mm

bill_depth_mm

flipper_length_mm

body_mass_g

sex

0

Adelie

Torgersen

39.1

18.7

181.0

3750.0

Male

1

Adelie

Torgersen

39.5

17.4

186.0

3800.0

Female

2

Adelie

Torgersen

40.3

18.0

195.0

3250.0

Female

3

Adelie

Torgersen

NaN

NaN

NaN

NaN

NaN

4

Adelie

Torgersen

36.7

19.3

193.0

3450.0

Female

speciesは文字列のデータになっています。speciesはペンギンの種類を分類している項目で、Adelie(アデリーペンギン)、Gentoo(ジェンツーペンギン)、Chinstrap(ヒゲペンギン)の3種類に分類されます。

このような、値の間で比較のできないデータをカテゴリ変数(質的データ)と呼びます。

このようなデータを数値で表したいときに、単純にAdelieに1、Gentooに2、Chinstrapに3を割り当ててしまうと、本来大小関係の無い3種に数値割り当てによる大小関係ができてしまいます。

そこで、DataFrameに新しくspecies_Adelie、species_Gentoo、species_Chinstrapという列を作り、speciesがAdelieの行はspecies_Adelieのみ1にして他2列は0にする。speciesがGentooの行はspecies_Gentooのみ1にして他2列は0にする。という方法で数値化をします。

これを、one-hotエンコーディングとかダミー変数化と呼びます。

実際には、下表のようになります。

species_Adelie

species_Gentoo

secies_Chinstrap

island

bill_length_mm

bill_depth_mm

flipper_length_mm

body_mass_g

sex

0

1

0

0

Torgersen

39.1

18.7

181.0

3750.0

Male

1

1

0

0

Torgersen

39.5

17.4

186.0

3800.0

Female

2

1

0

0

Torgersen

40.3

18.0

195.0

3250.0

Female

3

1

0

0

Torgersen

NaN

NaN

NaN

NaN

NaN

4

1

0

0

Torgersen

36.7

19.3

193.0

3450.0

Female

これなら、AdelieとGentooとChinstrapの間の大小関係は生じませんね。

one-hotとは

one-hotというのは、1つだけHigh(1)で他が全てLow(0)のビット列のことを言います。一つだけ1なので、one-hotです。

逆に1つだけ0で他が1のビット列をone-coldと呼びます。

one-hotエンコーディング(ダミー変数化)してみる

penguinsデータセットを読み込んで、ダミー変数化してみます。get_dummies()関数を使うと、ダミー変数化されたDataFrameが得られます。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('penguins')
df2 = pd.get_dummies(df)
print(df2.head(5))
   bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g  species_Adelie  species_Chinstrap  species_Gentoo  island_Biscoe  island_Dream  island_Torgersen  sex_Female  sex_Male
0            39.1           18.7              181.0       3750.0               1                  0               0              0             0                 1           0         1
1            39.5           17.4              186.0       3800.0               1                  0               0              0             0                 1           1         0
2            40.3           18.0              195.0       3250.0               1                  0               0              0             0                 1           1         0
3             NaN            NaN                NaN          NaN               1                  0               0              0             0                 1           0         0
4            36.7           19.3              193.0       3450.0               1                  0               0              0             0                 1           1         0

全てのカテゴリ変数がダミー変数化されました。

特定の列だけダミー変数化する

特定の列だけダミー変数化したい場合があります。そういう場合は、get_dummies()関数のcolumns引数にダミー変数化したい列を指定します。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('penguins')
df2 = pd.get_dummies(df, columns=['species','sex'])
print(df2.head(5))

speciesとsexだけがダミー変数化されました。

最初のカテゴリを除外する

speciesが3種類のカテゴリに分類されますが、GentooとChinstrapが共に0ならばAdelieが1、GentooかChinstrapのどちらかが1ならばAdelieは0なわけです。つまり、ダミー変数が2つでも大丈夫な場合があります。

k個のカテゴリに対してダミー変数をk-1個にしたい場合には、get_dummies()関数のdrop_first引数にTrueを渡します。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('penguins')
df2 = pd.get_dummies(df, columns=['species'], drop_first=True)
print(df2.head(5))
      island  bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g     sex  species_Chinstrap  species_Gentoo
0  Torgersen            39.1           18.7              181.0       3750.0    Male                  0               0
1  Torgersen            39.5           17.4              186.0       3800.0  Female                  0               0
2  Torgersen            40.3           18.0              195.0       3250.0  Female                  0               0
3  Torgersen             NaN            NaN                NaN          NaN     NaN                  0               0
4  Torgersen            36.7           19.3              193.0       3450.0  Female                  0               0

speciesのダミー変数が2つになってますね。

欠損値もダミー変数化する

penguinsデータセットの最初の5行はこのようになっています。

  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g     sex
0  Adelie  Torgersen            39.1           18.7              181.0       3750.0    Male
1  Adelie  Torgersen            39.5           17.4              186.0       3800.0  Female
2  Adelie  Torgersen            40.3           18.0              195.0       3250.0  Female
3  Adelie  Torgersen             NaN            NaN                NaN          NaN     NaN
4  Adelie  Torgersen            36.7           19.3              193.0       3450.0  Female

インデックスが3の行のsexのデータが欠損値(NaN)になっています。

sex列を単純にダミー変数化すると、このようになります。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('penguins')
df2 = pd.get_dummies(df, columns=['sex'])
print(df2.head(5))
  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g  sex_Female  sex_Male
0  Adelie  Torgersen            39.1           18.7              181.0       3750.0           0         1
1  Adelie  Torgersen            39.5           17.4              186.0       3800.0           1         0
2  Adelie  Torgersen            40.3           18.0              195.0       3250.0           1         0
3  Adelie  Torgersen             NaN            NaN                NaN          NaN           0         0
4  Adelie  Torgersen            36.7           19.3              193.0       3450.0           1         0

インデックが3の行のsex列のダミー変数は、両方とも0になっています。

そこで、欠損値もダミー変数にしたいと思います。欠損値もダミー変数にするには、get_dummies()関数のdummy_na引数にTrueを渡します。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('penguins')
df2 = pd.get_dummies(df, columns=['sex'], dummy_na=True)
print(df2.head(5))
  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g  sex_Female  sex_Male  sex_nan
0  Adelie  Torgersen            39.1           18.7              181.0       3750.0           0         1        0
1  Adelie  Torgersen            39.5           17.4              186.0       3800.0           1         0        0
2  Adelie  Torgersen            40.3           18.0              195.0       3250.0           1         0        0
3  Adelie  Torgersen             NaN            NaN                NaN          NaN           0         0        1
4  Adelie  Torgersen            36.7           19.3              193.0       3450.0           1         0        0

sex_nanが追加されました。

主な関数やメソッド

pandas.get_dummies()

import pandas as pd

df = pd.get_dummies(data, [prefix], [prefix_sep], [dummy_na], [columns], [sparse], [drop_first], [dtype])

変数

内容

data

DataFrame,Series,array

変化するデータ

prefix

str,list,dict

省略可。既定値はNone。ダミー変数化した列の列名の接頭語の指定。

prefix_sep

str

省略可。既定値は_。ダミー変数化した列の接頭語とカテゴリをつなぐ文字の指定。

dummy_na

bool

省略可。既定値はFalse。欠損値をダミー変数化するかどうか。

columns

list

省略可。既定値はNone。ダミー変数化する列名のリスト。Noneの場合は全てのobjectおよびcategory型の列が対象。

sparse

bool

省略可。既定値はFalse。

drop_first

bool

省略可。既定値はFalse。k個のカテゴリに対して、ダミー変数をk-1個にするかどうか。

dtype

dtype

省略可。既定値はnp.uint8。ダミー変数の型。

df

DataFrame

ダミー変数化されたデータフレーム

公開日

広告