DictVectorizer・FeatureHasherを使う場合
>>> from sklearn.feature_extraction import DictVectorizer
>>> D = [
... {'age': 23, 'gender': 'm', 'birthplace': 'US'},
... {'age': 34, 'gender': 'f', 'birthplace': 'JP'},
... {'age': 18, 'gender': 'f', 'birthplace': 'UK'},
... {'age': 50, 'gender': 'm', 'birthplace': 'US'}
... ]
>>> m = DictVectorizer(sparse=False)
>>> m.fit_transform(D)
array([[ 23., 0., 0., 1., 0., 1.],
[ 34., 1., 0., 0., 1., 0.],
[ 18., 0., 1., 0., 1., 0.],
[ 50., 0., 0., 1., 0., 1.]])
>>> m.feature_names_
['age', 'birthplace=JP', 'birthplace=UK', 'birthplace=US', 'gender=f', 'gender=m']
scikit-learnのDictVectorizerを使った場合、gender
についてはm
とf
の2値をとるのでgender=m
とgender=f
の2次元に変換され、birthplace
についてはUS
とJP
とUK
の3値なので3次元に変換される。
ここで、gender=m
とgender=f
の次元は完全相関しており、いわゆるmulticolinearityの状態になっている。
このデータを訓練データとして使うと学習と予測が不安定になることが想定される。
そもそもgender=m
またはgender=f
の1次元のみでよいはずで、birthplace
についても同様に2次元のみでよいはずである。
FeatureHasherについても同様にn個の値をとるカテゴリ変数はn次元に変換される(マッピングが無いので分かりづらいが)。
>>> from sklearn.feature_extraction import FeatureHasher
>>> m = FeatureHasher(n_features=15)
>>> m.fit_transform(D).toarray()
array([[ 0., 0., 0., 0., 23., 0., 0., 0., 0., 0., -1.,
0., -1., 0., 0.],
[ 0., 0., -1., 0., 34., 0., 0., 0., 1., 0., 0.,
0., 0., 0., 0.],
[ 0., 0., 0., 1., 18., 0., 0., 0., 1., 0., 0.,
0., 0., 0., 0.],
[ 0., 0., 0., 0., 50., 0., 0., 0., 0., 0., -1.,
0., -1., 0., 0.]])
n個の値をとるカテゴリ変数はn-1次元に変換するにはどうすればよいか?
pandas.get_dummiesを使う
pandas.get_dummiesでdrop_first=True
にするとn-1次元に変換することができる。
>>> import pandas as pd
>>> df = pd.DataFrame.from_dict(D)
>>> pd.get_dummies(df[['birthplace', 'gender']], prefix_sep='=', drop_first=True)
birthplace=UK birthplace=US gender=m
0 0 1 1
1 0 0 0
2 1 0 0
3 0 1 1
どの値が省かれてn-1次元になるかについては、ドキュメントには
Whether to get k-1 dummies out of k categorical levels by removing the first level.
とあるが、first_levelが何かについては不明。。