pandasでカテゴリ変数を数値データに変換する
pandasのDataFrameに格納されているカテゴリ変数(質的データ)を数値データ(量的データ)に変換します。
目次
カテゴリ変数に単純に数値を割り当てる弊害
下表は、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 |
ダミー変数化されたデータフレーム |
公開日
広告
Pythonでデータ分析カテゴリの投稿
- DataFrameの欠損値を特定の値で置き換える
- Pythonでpandas入門1(データの入力とデータへのアクセス)
- Pythonでpandas入門2(データの追加と削除および並び替え)
- Pythonでpandas入門3(データの統計量の計算)
- Pythonでpandas入門4(データの連結と結合)
- Pythonでpandas入門5(欠損値(NaN)の扱い)
- Pythonでデータを学習用と検証用に分割する
- Pythonでデータ分析入門1(初めての回帰分析)
- Pythonでデータ分析入門2(初めてのロジスティック回帰(2クラス分類))
- Pythonでデータ分析入門3(初めての決定木(多クラス分類))
- Pythonで回帰モデルの評価関数
- Pythonで箱ひげ図を描く
- Python(pandas)でExcelファイルを読み込んでDataFrameにする
- pandasでカテゴリ変数を数値データに変換する
- pandasでクロス集計する
- pandasで同じデータ(要素)がいくつあるか調べる
- pandasで相関係数を計算する
- pandasとseabornでデータの可視化(散布図行列)
- pandasの学習用のデータセットを入手する
- scikit-learnのサンプルデータセットを入手する