はじめに
機械学習のコンペや実務で「なかなかスコアが上がらない」という壁にぶつかったとき、最初に見直すべきなのが特徴量エンジニアリングです。
僕もSignateのコンペで何度も経験しましたが、アルゴリズムを変えてもスコアが伸びないとき、特徴量を工夫するだけで一気に改善することがあります。この記事では、実際に使える特徴量エンジニアリングの手法を解説します。
特徴量エンジニアリングとは
特徴量エンジニアリングとは、モデルの予測精度を上げるために、元のデータから新しい特徴量(変数)を作ったり、既存の特徴量を変換したりする作業のことです。
例えば「購買日時」というデータがあれば、「曜日」「時間帯」「月末かどうか」といった特徴量を新たに作ることで、モデルがより多くのパターンを学習できるようになります。
コンペの上位入賞者の解法を見ると、特徴量エンジニアリングが勝敗を分けていることがほとんどです。同じアルゴリズムを使っていても、特徴量の作り方で大きな差が出ます。
数値変数の変換
対数変換
売上や価格など、右に裾が長い分布(外れ値が多い)には対数変換が有効です。
import numpy as np
df['price_log'] = np.log1p(df['price']) # log(1+x) で0を処理
二乗・平方根変換
df['area_sq'] = df['area'] ** 2
df['area_sqrt'] = np.sqrt(df['area'])
交互作用項(2変数の掛け合わせ)
2つの変数を組み合わせることで、単体では捉えられないパターンを学習できます。
df['price_per_area'] = df['price'] / df['area']
df['income_x_age'] = df['income'] * df['age']
カテゴリ変数の変換
One-Hotエンコーディング
カテゴリ数が少ない場合の定番手法です。
df = pd.get_dummies(df, columns=['prefecture'], drop_first=True)
Target Encoding(ターゲットエンコーディング)
カテゴリごとの目的変数の平均値に置き換える手法です。カテゴリ数が多い場合に特に有効です。ただしデータリークに注意が必要で、交差検証と組み合わせて使うのが基本です。
from category_encoders import TargetEncoder
te = TargetEncoder(cols=['prefecture'])
X_train_encoded = te.fit_transform(X_train, y_train)
X_test_encoded = te.transform(X_test)
日時データからの特徴量生成
日時データは非常に多くの特徴量を生み出せます。
df['datetime'] = pd.to_datetime(df['datetime'])
df['year'] = df['datetime'].dt.year
df['month'] = df['datetime'].dt.month
df['day'] = df['datetime'].dt.day
df['hour'] = df['datetime'].dt.hour
df['day_of_week'] = df['datetime'].dt.dayofweek # 0=月曜
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
df['quarter'] = df['datetime'].dt.quarter
製造業のデータでは「月末・月初」や「夜勤帯かどうか」なども有効な特徴量になることがあります。
集計特徴量の作成
グループごとの統計量を特徴量にする方法です。例えば「顧客ごとの購買回数」「製品ごとの平均不良率」などです。
# 顧客ごとの購買金額の平均・合計・標準偏差
agg = df.groupby('customer_id')['amount'].agg(['mean', 'sum', 'std'])
agg.columns = ['amount_mean', 'amount_sum', 'amount_std']
df = df.merge(agg, on='customer_id', how='left')
特徴量選択の重要性
特徴量をやみくもに増やせばいいわけではありません。不要な特徴量が増えると過学習のリスクが高まり、計算コストも増加します。
ランダムフォレストなどの特徴量重要度を見ながら、重要度の低い特徴量は削除することが大切です。
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
importances = pd.Series(
model.feature_importances_,
index=X_train.columns
).sort_values(ascending=False)
print(importances.head(10)) # 重要度TOP10を確認
まとめ
特徴量エンジニアリングで押さえるべきポイントをまとめます。
- 数値変数は対数変換・二乗・交互作用項で変換する
- カテゴリ変数はOne-HotかTarget Encodingを使い分ける
- 日時データからは曜日・時間帯・月末フラグなどを生成する
- グループ集計で統計量を特徴量にする
- 特徴量重要度を見ながら不要なものは削除する
特徴量エンジニアリングに「これが正解」という方法はありません。データの特性とドメイン知識を組み合わせて試行錯誤することが大切です。まずは基本的な手法を覚えて、コンペや実務で積極的に試してみてください。
自分らしく働けるエンジニア転職を目指すなら【strategy career】
年収1000万・残業月30時間以下・リモート可の求人多数
※アフィリエイト広告を含みます
![]()


コメント