機械学習や統計の重回帰分析などで使われているダミー変数はPandasでも手軽に作ることが可能です。

ダミー変数はカテゴリーデータを0と1だけで構成されているカテゴリーごとの列データに変換したもののことを指します。

主に、非数値データをベクトル化して扱いたい時に使われる手法となっており重回帰分析では有名な手法となっています。

機械学習の前処理でもよく使われる手法となっています。

get_dummies関数

APIドキュメント

get_dummies関数のAPIドキュメントは以下の通りです。

pandas.get_dummies(data,prefix=None,prefix_sep=’_‘,dummy_na=False,columns=None,sparse=False,drop_first=False,dtype=None)

params:

パラメータ名 概要
data 配列,Series
またはDataFrame
ダミー変数を作成したいデータを選択します。
prefix str,strのリスト,
strの辞書
(省略可能)初期値None
DataFrameのカラムラベルに付け加える文字列を指定します。
prefix_sep str (省略可能)初期値’_‘
prefixで指定された文字列を付け加える際に橋渡しとなる文字列を指定します。
dummy_na bool値 (省略可能)初期値False
欠損値もダミー変数として処理するかどうかを指定します。
columns リスト (省略可能)初期値None
ダミー変数に変換したい列データを指定します。指定されない場合は全てのデータを対象にダミー変数を作成します。
sparse bool値 (省略可能)初期値False
SparseDataFrameとして返り値を返すかどうかを指定します。
drop_first bool値 (省略可能)初期値False
カテゴリー数がk個あった時、k-1個のダミー変数を作成するかどうかを指定します。
dtype データ型 (省略可能)初期値np.uint8
新たなカラムのデータ型を指定します。

returns:

ダミー変数が含まれたDataFrameかSparseDataFrameが返されます。

ダミー変数を作成する

まずは簡単な例でダミー変数を作成してみます。

In [1]: import pandas as pd

In [2]: sr = pd.Series(['A','A','B','A','C'])

In [3]: pd.get_dummies(sr) # ダミー変数を作成
Out[3]:
   A  B  C
0  1  0  0
1  1  0  0
2  0  1  0
3  1  0  0
4  0  0  1

このようにA,B,Cそれぞれのカラムが作られ、その値が見られたら1を返し、見られなかったら0を返しています。

DataFrameから作成してみます。

In [4]: df = pd.DataFrame({'col1':['A','B','A','D','A'],
   ...:                    'col2':['B','C',None,'B','D']})
   ...:                    

In [5]: df
Out[5]:
  col1  col2
0    A     B
1    B     C
2    A  None
3    D     B
4    A     D

In [6]: pd.get_dummies(df) # まとめてダミー変数の作成
Out[6]:
   col1_A  col1_B  col1_D  col2_B  col2_C  col2_D
0       1       0       0       1       0       0
1       0       1       0       0       1       0
2       1       0       0       0       0       0
3       0       0       1       1       0       0
4       1       0       0       0       0       1

このようにDataFrameでダミー変数を作成すると、新たに返されるDataFrameのカラムラベルは元のデータのカラムラベルが先頭につくようになっています。

特定の列データのみ変換する

先ほどの例ですとDataFrameをダミー変数に変換すると全ての列データがダミー変数に変換されます。

そのため、一部の列データだけ変換したい時はcolumnsで指定することが可能です。

列データだけを抽出して入れないことのメリットとして指定した列データのみがダミー変数に変換されるため、変換された後に元のデータにマージする手間が省けることがあります。

コードが一行で済んでしまう上にデータの不整合が起こる心配がないため使えると非常に便利です。

In [8]: pd.get_dummies(df,columns=['col1'])
Out[8]:
   col2  col1_A  col1_B  col1_D
0     B       1       0       0
1     C       0       1       0
2  None       1       0       0
3     B       0       0       1
4     D       1       0       0

In [9]: pd.get_dummies(df,columns=['col2'])
Out[9]:
  col1  col2_B  col2_C  col2_D
0    A       1       0       0
1    B       0       1       0
2    A       0       0       0
3    D       1       0       0
4    A       0       0       1

欠損値をダミー変数として認識する

先ほどのデータの中には1つだけ欠損値が紛れ込んでいました。

In [10]: df
Out[10]:
  col1  col2
0    A     B
1    B     C
2    A  None
3    D     B
4    A     D

この欠損値もダミー変数として認識させることが可能です。 dummy_na引数をTrueにしましょう。

In [11]: pd.get_dummies(df['col2'],dummy_na=True)
Out[11]:
   B  C  D  NaN
0  1  0  0    0
1  0  1  0    0
2  0  0  0    1
3  1  0  0    0
4  0  0  1    0

多重共線性を防ぐ

例えば[‘A’,’B’,’C’,’D’]の4つのカテゴリーしかないデータがあり、全てのデータがこのどれか1つのカテゴリーに属しているとすると、[‘B’,’C’,’D’]に存在しているかどうかがはっきりしていれば’A’に属しているかどうかははっきりします。

このような時4クラス分のダミー変数があったとするとお互いの変数に拘束関係が働いてしまうため回帰分析がうまくできないといったケースが起こり得ます。これを多重共線性と呼びます。

そのため、1つクラスを削り情報量を最低限とすることで回帰がうまくいくようにすることができます。

pandasではdrop_first=Trueにすることで対処できます。また、この場合は’A’クラスと欠損値が同等に扱われてしまう(どちらも全部0になるため)ので、dummy_na=Trueにしておくことをオススメします。

In [15]: sr
Out[15]:
0    A
1    A
2    B
3    A
4    C
dtype: object

In [16]: pd.get_dummies(sr,drop_first=True) # B,Cのみダミー変数となる
Out[16]:
   B  C
0  0  0
1  0  0
2  1  0
3  0  0
4  0  1

欠損値が含まれている時はdummy_na=Trueにしましょう。

In [17]: df
Out[17]:
  col1  col2
0    A     B
1    B     C
2    A  None
3    D     B
4    A     D

In [18]: pd.get_dummies(df['col2'],drop_first=True) # 欠損値が含まれているとAとNaNとの区別がつかない
Out[18]:
   C  D
0  0  0
1  1  0
2  0  0
3  0  0
4  0  1

In [20]: pd.get_dummies(df['col2'],drop_first=True,dummy_na=True) # 欠損値との区別可能
Out[20]:
   C  D  NaN
0  0  0    0
1  1  0    0
2  0  0    1
3  0  0    0
4  0  1    0

ダミー変数ラベルの先頭につける文字列を変更する

次は生成されるダミー変数ラベルの先頭につける文字列を変更します。prefixで変更可能です。

1つだけ指定すると全て同じものに変わってしまうため、DataFrameでまとめたダミー変数に変更する場合は気をつけましょう。

In [21]: pd.get_dummies(df,prefix='data')
Out[21]:
   data_A  data_B  data_D  data_B  data_C  data_D
0       1       0       0       1       0       0
1       0       1       0       0       1       0
2       1       0       0       0       0       0
3       0       0       1       1       0       0
4       1       0       0       0       0       1

In [22]: pd.get_dummies(df, prefix=['one','two']) # 列ごとに変える
Out[22]:
   one_A  one_B  one_D  two_B  two_C  two_D
0      1      0      0      1      0      0
1      0      1      0      0      1      0
2      1      0      0      0      0      0
3      0      0      1      1      0      0
4      1      0      0      0      0      1

まとめ

今回はダミー変数を作成するget_dummies関数について解説しました。統計分野や機械学習の分野では必ずお世話になる関数になると思うのでぜひ使い方をマスターしましょう。

参考