特徴量選択
田中VPoE:「モデルの精度を左右するのは、アルゴリズムの選択よりも、どんなデータを入力するかだ。『Garbage in, garbage out』という言葉があるように、入力の品質がすべてを決める。」
あなた:「特徴量が多ければ多いほど良いわけではないんですか?」
田中VPoE:「むしろ逆だ。ノイズとなる特徴量が多いと、モデルの精度は下がる。本当に予測に役立つ特徴量を選び抜くことが重要だ。」
特徴量選択とは
特徴量選択(Feature Selection)は、利用可能なすべての特徴量から、モデルの予測に有効なものを選び出す手法です。
なぜ特徴量選択が必要か
- 過学習の防止: 不要な特徴量はノイズとなり過学習を引き起こす
- 計算コストの削減: 特徴量が少ないほど学習・推論が高速
- 解釈性の向上: 重要な特徴量が明確になりビジネスへの説明が容易
- 多重共線性の回避: 相関の高い特徴量の重複を排除
フィルタ法(Filter Method)
モデルを使わず、統計的な基準で特徴量を選択する方法です。
相関分析による選択
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# NetShop顧客データの例
df = pd.DataFrame({
'purchase_count': np.random.poisson(5, 1000),
'avg_amount': np.random.normal(5000, 2000, 1000),
'days_inactive': np.random.exponential(30, 1000),
'support_tickets': np.random.poisson(1, 1000),
'page_views': np.random.poisson(20, 1000),
'membership_months': np.random.exponential(12, 1000),
'is_churned': np.random.binomial(1, 0.08, 1000),
})
# 目的変数との相関
correlations = df.corr()['is_churned'].drop('is_churned').abs().sort_values(ascending=False)
print("目的変数との相関係数(絶対値):")
print(correlations)
# 相関が0.05以上の特徴量を選択
selected = correlations[correlations > 0.05].index.tolist()
print(f"\n選択された特徴量: {selected}")
分散による選択
分散がほぼゼロの特徴量は情報量がないため除外します。
from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.01)
X_selected = selector.fit_transform(X)
# 選択された特徴量
selected_mask = selector.get_support()
print(f"元の特徴量数: {X.shape[1]}")
print(f"選択後の特徴量数: {X_selected.shape[1]}")
カイ二乗検定(カテゴリカル特徴量)
from sklearn.feature_selection import chi2, SelectKBest
selector = SelectKBest(chi2, k=5)
X_selected = selector.fit_transform(X_non_negative, y)
scores = pd.Series(selector.scores_, index=feature_names)
print("カイ二乗スコア:")
print(scores.sort_values(ascending=False))
ラッパー法(Wrapper Method)
モデルの精度を基準に特徴量を追加・削除する方法です。
再帰的特徴量削減(RFE)
from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, random_state=42)
rfe = RFE(estimator=model, n_features_to_select=5, step=1)
rfe.fit(X_train, y_train)
# 選択された特徴量
selected_features = [f for f, s in zip(feature_names, rfe.support_) if s]
print(f"選択された特徴量: {selected_features}")
# ランキング
ranking = pd.Series(rfe.ranking_, index=feature_names).sort_values()
print(f"\n特徴量ランキング:")
print(ranking)
ラッパー法は精度が高いですが、計算コストが大きい点に注意が必要です。
埋め込み法(Embedded Method)
モデルの学習過程で自動的に特徴量選択が行われる方法です。
L1正則化(Lasso)
from sklearn.linear_model import LogisticRegression
# L1正則化で不要な特徴量の係数を0にする
model = LogisticRegression(penalty='l1', solver='liblinear', C=0.1)
model.fit(X_train, y_train)
# 係数が0でない特徴量を選択
importance = pd.Series(np.abs(model.coef_[0]), index=feature_names)
selected = importance[importance > 0].sort_values(ascending=False)
print("選択された特徴量と係数:")
print(selected)
ランダムフォレストの特徴量重要度
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
importance = pd.Series(model.feature_importances_, index=feature_names)
importance = importance.sort_values(ascending=False)
plt.figure(figsize=(10, 6))
importance.plot(kind='barh')
plt.title('特徴量重要度(ランダムフォレスト)')
plt.xlabel('重要度')
plt.tight_layout()
plt.show()
3つの手法の使い分け
| 手法 | 速度 | 精度 | 適用場面 |
|---|---|---|---|
| フィルタ法 | 高速 | 中程度 | 大量の特徴量から大幅に絞り込む |
| ラッパー法 | 低速 | 高い | 少数の特徴量から最適な組み合わせを探す |
| 埋め込み法 | 中程度 | 高い | モデル学習と同時に特徴量選択したい |
実務では、フィルタ法で大幅に絞り込み、埋め込み法で最終選択するのが一般的です。
まとめ
- 特徴量選択はモデル精度と解釈性の向上に重要
- フィルタ法: 統計的基準で高速に選択(相関、分散、カイ二乗検定)
- ラッパー法: モデル精度を基準に選択(RFE)
- 埋め込み法: 学習過程で自動選択(L1正則化、特徴量重要度)
- 実務ではフィルタ法と埋め込み法の組み合わせが効率的
チェックリスト
- 特徴量選択の3つの手法の違いを説明できる
- 相関分析による特徴量選択のコードを書ける
- RFE の仕組みを理解した
- 各手法の使い分けが判断できる
次のステップへ
次のレッスンでは、カテゴリカル変数のエンコーディング手法を学びます。文字列データをモデルが扱える数値に変換する方法を身につけましょう。
推定読了時間: 30分