ツリーモデルと非ツリーモデルを中心に特徴量エンジニアリングのパターンを特徴量のデータ型と手法選択の考え方をまとめます。地味だけど脱初心者には重要なスキルです。
Contents
数値データ
ツリーモデルでは不要、非ツリーモデルでは不要。
正規化
特徴量の最大値が1、最小値が0になるように変換すること。(-1、1)の場合もある。外れ値がある場合、外れ値との相対的な距離は大きいままなので、外れ値処理が必要。
1 2 3 4 5 6 7 |
from sklean.preprocessing import MinMaxScaler mmscaler = MinMaxScaler() # インスタンスの作成 mmscaler.fit(x) # xの最大・最小を計算 y = mmscaler.transform(x) # xを変換 |
標準化
特徴量の平均0、分散1になるように変換すること。外れ値がある場合、外れ値との相対的な距離は大きいままなので、外れ値処理が必要。
1 2 3 4 5 6 7 |
from sklean.preprocessing import StandardScaler sscaler = StandardScaler() # インスタンスの作成 sscaler.fit(x) # xの最大・最小を計算 y = sscaler.transform(x) # xを変換 |
ウィンザー化
特徴量を1%~99%パーセンタイルの範囲など一定の範囲外のデータを除外すること。外れ値処理などに活用できる。
1 2 3 4 5 6 7 8 9 10 11 12 |
# パーセンタイルの取得 Q1 = series.quantile(.25) #25% Q3 = series.quantile(.75) #75% # 閾値の算出 IQR = Q3 - Q1 threshold = Q3 + 1.5 * IQR # 外れ値の検出 df_outlier = df[df['A'].apply(lambda x:x > threshold)] |
参考:https://qiita.com/koga1020/items/9710cb3f7f65a00808e4
順位変換
特徴量の値に基づいて順位付けすること。データの間隔が全て1になるため外れ値の影響も小さくなる。
1 2 3 |
df['col1'].rank(method='average', ascending=False) # 同一値の場合その平均値,昇順 |
参考:https://note.nkmk.me/python-pandas-rank/
対数変換
特徴量を対数(log( x + 1 ))で変換する。+1はx=0の場合発散防止のために追加している。xのスケールが大きいときはその範囲を縮小し、小さいときは拡大する。
非線形変換で外れ値を他の値に近づけることができる。回帰分析などは正規分布を前提にしている場合が多いのですが、正規分布が右にゆがんでいる分布などときに有効。
1 2 3 |
np.log(x+1) |
参考: https://qiita.com/gyu-don/items/ecd483fd94f446b576a3
カテゴリカル/順序変数
label encoding
カテゴリカル変数を、アルファベット順やある特定に基準で順位付けする。非ツリーモデルでは使えない。ツリーモデルの場合、ラベルエンコーディングは順序情報を持っているため、ワンホットエンコーディングより精度が高くなる。
1 2 3 4 5 6 7 8 9 10 11 12 |
from sklearn.preprocessing import LabelEncoder #LabelEncoderのインスタンスを生成 le = LabelEncoder() #ラベルを覚えさせる le = le.fit(df['label']) #ラベルを整数に変換 df['label'] = le.transform(df['label']) |
参考:https://qiita.com/uratatsu/items/8bedbf91e22f90b6e64b
freqency encoding
特徴量の各値の出現頻度で置き換える。出現頻度とターゲット変数で相関があるとき効果的。
1 2 3 4 5 6 7 8 |
#各カテゴリーの出現回数を計算 grouped = df.groupby("category").size().reset_index(name='category_counts') #元のデータセットにカテゴリーをキーとして結合 df = df.merge(grouped, how = "left", on = "category") df["frequency"] = df["category_counts"]/df["category_counts"].count() |
参考:https://mikebird28.hatenablog.jp/entry/2018/05/19/213047
ranked frequency encoding
特徴量の各値の出現頻度で順位付けし、その順位に置き換える。
one hot encoding
特徴量の値を新しい特徴量とし、該当する場合1、しない場合0に変換する。
一つのカテゴリ変数から複数の変数(カラム)を作るため、大きなスパースなデータとなりメモリの消費が大きくなる。また、カテゴリ数の膨大なカテゴリ変数をワンホットエンコーディングすると、ランダムフォレストなどランダムに特徴量を選択するアルゴリズムの場合、数値変数などの非カテゴリカル変数の選択率が減少して精度が落ちる問題がある。
(この選択率、ハイパーパラメータでチューニングできる。xgboostでは、colsample_bytreeランダムフォレストでは、max_feature)
線形の依存関係がある特徴量の場合、線形モデルの回帰係数が一意に定まらない問題があることに注意(多重共線性)。多重共線性を避けるためには、k個のカテゴリがある場合一つカテゴリを削除してk-1とするダミーエンコーディングを使う。
参考:https://xica.net/vno4ul5p/
ラベルエンコーディングでは発生頻度の低い稀なカテゴリなどが取りにくく、重要な変数がうまく取れない場合があるため、One hot encodingはの処理に役立つ。
1 2 3 |
pd.get_dummies(df, columns=['col1'], drop_first=True) |