0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

データの前処理まとめ2(カテゴリ変数)

Posted at

今回はカテゴリ変数の変換についてまとめます。
使用するデータはHouse Prices - Advanced Regression Techniquesのtrain.csvです。
また、着目する変数はHouseStyleとします。
以下kaggleのdata_description.txtより

HouseStyle: Style of dwelling
1Story One story
1.5Fin One and one-half story: 2nd level finished
1.5Unf One and one-half story: 2nd level unfinished
2Story Two story
2.5Fin Two and one-half story: 2nd level finished
2.5Unf Two and one-half story: 2nd level unfinished
SFoyer Split Foyer
SLvl Split Level

データについて

data.ipynb
df['HouseStyle'].describe()
#以下出力
count       1460
unique         8
top       1Story
freq         726
Name: HouseStyle, dtype: object

#1.なぜ変換を行うのか
上のデータの例から分かるように、変数が文字列で表されているデータはほとんどの場合そのまま分析に使うことができません。そこで、モデルに適した形への変換が必要となります。(*数値型であっても、電話番号、郵便番号などの大小関係や連続的な意味を持たないものはカテゴリ変数として扱う)
#2.変換手法
##2.1.one-hot encoding
one-hot encodingでは、n個(今回のケースではn=8)の水準を持つカテゴリ変数をその水準かどうかを二値変数(0or1)を用いることで表現します。
実際に変換して最初の部分だけ表示すると、以下のようになります。

Onehot_Encoding.ipynb
pd.get_dummies(df['HouseStyle']).head()
1.5Fin 1.5Unf 1Story 2.5Fin 2.5Unf 2Story SFoyer SLvl
0 0 0 0 0 0 1 0 0
1 0 0 1 0 0 0 0 0
2 0 0 0 0 0 1 0 0
3 0 0 0 0 0 1 0 0
4 0 0 0 0 0 1 0 0
カテゴリ変数の水準名から自動でデータフレーム型を返してくれるので便利です。
(*使い方に注意が必要、こちらのブログに詳細

one-hot encodingの欠点は、特徴量の数がカテゴリ変数の水準数に応じて増えてしまう点にあります。これにより、学習にかかる計算時間や必要なメモリが大きく増えたり、モデルの性能に悪影響を及ぼす可能性が生じます。
この問題に対する対処法は主に3つ考えられます。
1.他の変換手法を試す
2.ある規則でグルーピングして、水準数を減らす
3.頻度の少ないカテゴリを「その他」にまとめる
今回のケースでは直感的に3の対処法が使えそうです。
実際の頻度は以下

n_value.ipynb
df['HouseStyle'].value_counts()
#以下出力結果
1Story    726
2Story    445
1.5Fin    154
SLvl       65
SFoyer     37
1.5Unf     14
2.5Unf     11
2.5Fin      8
Name: HouseStyle, dtype: int64

以上より、SFoyer以下はその他としても良さそうです.
#2.2.label encoding
LabelEncodingとは単純に各水準を数字に置き換えるというものです。
今回のデータではカテゴリ変数が0から7までの数値に置き換えられます。
実際にやってみると以下の通りになります。

Label_Encoding
from sklearn.preprocessing import LabelEncoder

feature = ['HouseStyle']
for c in feature:
    lbl = LabelEncoder()
    df[c] = lbl.fit_transform(df[c].values)

df['HouseStyle'].value_counts()
#以下出力結果
2    726
5    445
0    154
7     65
6     37
1     14
4     11
3      8
Name: HouseStyle, dtype: int64

上で述べた通り、インデックスの数値が水準を区別する以外の意味を持たないため、このまま訓練データに用いることはあまり適切ではありません。しかし、決定木をベースとした手法では分岐を繰り返すことでこれらの数値を予測に反映することができるので、学習データとして活用できます。(特にGBDTではよく使われている印象がある)

#参考文献
門脇、阪田、保坂、平松 「Kaggleで勝つデータ分析の技術」 技術評論社 (2019/10/9)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?