Python基礎 副業で稼ぐ

【保存版】特徴量エンジニアリング入門:設計→実装→リーク対策→評価→自動化まで“精度が上がる”実務の型

アルゴリズムを変えても精度が伸びない…

結論:モデル精度の大半は特徴量設計リーク対策が結果の大半を決めます。
アルゴリズムを頻繁に変えるより、まずは土台を整えるのが近道です。

この記事で身に付く力

  • 現場で使える特徴量設計の“型”(時間窓・集約・比/差分)
  • リークを防ぐパイプライン構築(ColumnTransformer×Pipeline)
  • 評価と自動化(CV±std、Permutation Importance、スクリプト化)

関連記事:
>>【保存版】scikit-learn基礎:回帰・分類・前処理・パイプライン・交差検証を“実務の型”で習得
>>【保存版】モデル評価:指標の選び方・交差検証・閾値最適化・ビジネス接続を“実務の型”で解説
>>【保存版】ハイパーパラメータ入門:Grid/Random/Optunaの実務チューニング完全ガイド
>>【保存版】pandas基礎:データフレームの作成・整形・結合・集計を“実務の型”で身につける
>>【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得
>>【保存版】NumPy基礎:配列・ブロードキャスト・ベクトル化・乱数・線形代数を“実務の型”で最短習得
>>実務で使える統計の型12 | Pythonで最短習得
>>【保存版】可視化入門:Matplotlib/Plotlyの使い分けと“伝わるグラフ設計”10ステップ
>>はじめてのSQL:SELECT/WHERE/GROUP BYを最短で理解【コピペOK】
>>【保存版】SQLite×Pythonで作る“ローカルDWH”——ETL・集計・レポート自動化の最短手順
>>【保存版】Jupyter Notebookの基本:環境構築・使い方・再現性・“読みやすいノート”設計まで完全ガイド
>>【保存版】Git/GitHub入門:バージョン管理・ブランチ戦略・レビュー・自動化を“実務の型”で最短習得
>>【コピペOK】pytestで“壊れないPython”を作る12ステップ
>>【保存版】データ職のポートフォリオ完全ガイド|再現性・評価・LTまで

よくあるつまずき(3つ)と先に押さえる解決方針

闇雲にアルゴリズムを変えても、土台が整っていないと精度は伸びません。まずはここを直します。

  • リーク(情報漏れ):未来情報や目的変数の影響が混入→CVは良いのに本番で崩れる。
  • スケール不一致:桁がバラバラ→勾配・距離ベースの手法が不安定。
  • 高カーディナリティ:カテゴリが多すぎ→One-Hotが膨張。

解決の型:ColumnTransformer+Pipelineで“学習内の処理”に閉じ込み、交差検証で評価しながら小さく積む。

実務で効いた話(ふみと)

役員会向けの意思決定支援で刺さったのは、業務ロジック×時間軸を写した特徴量(例:直近4週移動平均/前年同週比/在庫ギャップ)。そして訓練データ内統計のみで変換するリーク対策。以降はこの方針でテンプレ化していきます。

実装テンプレ:特徴量“実務の型”10ブロック

以下のコードはそのままコピペでOK。学習内に前処理を閉じ込めるのが最大のポイントです。

1) データ要件とターゲット定義(最重要)

何を・いつまでに・誰の意思決定に使うのかを先に固定します。

予測日:YYYY-MM-DD
学習窓:予測日の過去N日(例:90日)
評価窓:直近L日(例:30日)
ターゲット:評価窓内の離反=1

目的と時間窓を先に決めると、“未来を見てしまう”事故を防げます。

2) 前処理の骨組み(ColumnTransformer×Pipeline)

目的:欠損補完・スケーリング・エンコードを訓練データでfit→検証/本番に適用できる形にする。

import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, StratifiedKFold


num_cols = ["qty","price","days_since_last","amount"]
cat_cols = ["store","category","area"]


# 数値: 欠損→中央値、→標準化
num_pipe = Pipeline([
("impute", SimpleImputer(strategy="median")),
("scale", StandardScaler()),
])


# カテゴリ: 欠損→最頻値、→One-Hot(未知カテゴリは無視、まれな値は束ねる)
cat_pipe = Pipeline([
("impute", SimpleImputer(strategy="most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore", min_frequency=5))
])


# 列ごとに処理を振り分ける
preprocess = ColumnTransformer([
("num", num_pipe, num_cols),
("cat", cat_pipe, cat_cols)
])


# 前処理→モデルを直列化
clf = Pipeline([
("prep", preprocess),
("model", LogisticRegression(max_iter=1000, n_jobs=-1))
])


cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)


# 不均衡分類ではPR-AUC推奨
scores = cross_val_score(clf, X, y, scoring="average_precision", cv=cv, n_jobs=-1)
print(scores.mean(), scores.std())

ここでやっていること

  • min_frequencyでレアカテゴリを自動で束ね、One-Hot爆発を緩和。
  • Impute/Scale/EncodeはすべてPipeline内fit訓練折のみで行われ、検証・本番には学習済みパラメータを適用→リーク防止

3) 時間特徴量(時系列の基本)

目的:季節性や周期性、直近の勢いを表現する。

df["date"] = pd.to_datetime(df["date"])
df["ym"] = df["date"].dt.to_period("M").astype(str)
df["dow"] = df["date"].dt.dayofweek

df = df.sort\_values("date")
df\["amt"] = df\["qty"]\*df\["price"]

# ラグ/移動平均(未来参照はNG)

df\["amt\_lag1"] = df.groupby("store")\["amt"].shift(1)
df\["amt\_ma4"] = df.groupby("store")\["amt"].rolling(4).mean().reset\_index(level=0, drop=True)

# 季節性

df\["month"] = df\["date"].dt.month

注意shift(-1)のように未来を見る操作は厳禁。学習期間と評価期間をまたぐ平均もNG。

4) 集約特徴量(個体×時間窓で完結)

目的

  • 過去一定期間の“量・頻度・平均”を個体(顧客/店舗など)単位で表す。
  • 同一個体内×指定期間で完結させ、他個体から情報が混ざらないようにする。
# 直近90日の顧客別集約例
win = df.groupby(["customer"]).rolling("90D", on="date")["amt"].agg(["sum","mean","count"]).reset_index()
win.columns = ["customer","date","amt_sum90","amt_mean90","txn90"]
df = df.merge(win, on=["customer","date"], how="left")

時間窓を限定し、同一個体内の統計を使う(クロス個体の情報混入に注意)。

5) 高カーディナリティ対策(Rare/Hash/Target Encoding)

目的:カテゴリが多い列の表現を安定させ、過学習とサイズ爆発を防ぐ。

  • Rare Bucketing:出現が少ない値を_OTHERに束ねる(min_frequencyで半自動)
  • Hashing:次元を固定して衝突を許容する(木系で有効なことが多い)
  • Target EncodingFold内平均でリークを避ける
import pandas as pd
from sklearn.model_selection import KFold

def kfold\_target\_encoding(X\_col, y, n\_splits=5, seed=42):
X\_col = pd.Series(X\_col)
kf = KFold(n\_splits=n\_splits, shuffle=True, random\_state=seed)
enc = pd.Series(index=X\_col.index, dtype=float)
for tr, va in kf.split(X\_col):
m = y.iloc\[tr].groupby(X\_col.iloc\[tr]).mean()
enc.iloc\[va] = X\_col.iloc\[va].map(m).fillna(y.iloc\[tr].mean())
return enc

X\["store\_te"] = kfold\_target\_encoding(X\["store"], y)

ポイント:全データ平均でのエンコードはリーク。必ずFold内で算出→検証へ適用します。

6) 欠損と外れ値(フラグを別列で持つ)

目的:欠損そのものが情報のときに“消えないように”扱う。

from sklearn.impute import SimpleImputer

# 欠損フラグを別に持つ

X\["qty\_isna"] = X\["qty"].isna().astype(int)

# 数値はmedian、カテゴリは最頻

imputer\_num = SimpleImputer(strategy="median")
imputer\_cat = SimpleImputer(strategy="most\_frequent")

7) 変換:スケーリング/ボックス変換/ビニング

目的:手法に合う分布・スケールに整形する。

  • StandardScaler:平均0・分散1(ロジ回/線形/距離系)
  • MinMaxScaler:0–1スケーリング(木系は不要なことが多い)
  • RobustScaler:外れ値に強い
  • PowerTransformer(Yeo-Johnson):分布の歪み是正
  • KBinsDiscretizer:連続値→離散化(境界はドメイン判断

すべてPipeline内で。外で一括実行はリークの温床です。

8) 相互作用・比・差分(業務ロジックを写す)

目的:現場の指標に近い形に落とす。

X["unit_price"] = X["amount"]/X["qty"]
X["stock_gap"] = X["forecast_stock"] - X["actual_stock"]
X["price_ratio"] = X["price"] / X.groupby("category")["price"].transform("median")

解釈:差分・比は直感的で、カテゴリ基準比は季節やトレンドの影響を相対化できます。

9) 特徴量選択(軽量セット)

目的:説明性と計算効率を両立する。

  • 高相関は片方を落とす(解釈重視なら有効)
  • L1正則化(Lasso/Logistic)でスパース化
  • Permutation ImportanceCVの外側で計算(内側だと楽観バイアス)
from sklearn.inspection import permutation_importance
clf.fit(X_tr, y_tr)
r = permutation_importance(clf, X_va, y_va, n_repeats=5, random_state=42)

10) 評価・改善・自動化(締め)

  • 評価:分類→PR-AUC/ROC-AUC、回帰→MAE/RMSE。CV±stdとTop-kでビジネス指標に接続。
  • 改善:特徴量の追加/削除→再CV。過学習は正則化・単純化で抑制。
  • 自動化Pipeline + GridSearchCV/RandomizedSearchCV再現可能に。

付録:よく使う拡張・チェック・テスト

A. ColumnTransformer×Datetime機能拡張例

目的:日付から月・曜日などの派生列を前処理パイプラインの中で生成する。

from sklearn.preprocessing import FunctionTransformer


# 入力: DataFrame(date列を含む)→ 出力: 追加する派生列だけ返す


def add_date_parts(d):
d = d.copy()
dt = pd.to_datetime(d["date"])
d["month"], d["dow"] = dt.dt.month, dt.dt.dayofweek
return d[["month","dow"]]


preprocess = ColumnTransformer([
("num", num_pipe, num_cols),
("cat", cat_pipe, cat_cols),
("date", FunctionTransformer(add_date_parts), ["date"]) # date→2列
])

B. リークのチェックリスト(保存版)

  • 未来日付/未来在庫を使っていない
  • Target EncodingはFold内平均で実施
  • 標準化/欠損補完は学習内でfit
  • 集約は同一個体/時間窓内で完結
  • 評価は時系列CV or KFoldで設計(シャッフル有無を吟味)

C. テスト最小セット(pytest)

# tests/test_features.py
import pandas as pd
from src.features import make_features

def test\_no\_future\_leak():
df = pd.DataFrame({"date": pd.date\_range("2025-01-01", periods=10, freq="D"),
"amt": range(10)})
X = make\_features(df)
\# lagは必ずNaNを含む(未来参照なしの証拠)
assert X.filter(like="lag").isna().sum().sum() > 0

読者タイプ別:最短で“刺さる”一手

  • 社会人(転職準備):時間窓×差分/比+Target Encoding(CV付き)。CVの平均±stdとTop-kで意思決定に接続。
  • 副業(すぐ成果):在庫ギャップ/需要移動平均/前年同週比などKPI直結の特徴量を優先。
  • 在宅(学習継続):まずはPipeline化して“ボタン一発”。欠損フラグ+RobustScalerで安定運用。

行動課題:ミニプロジェクト(提出推奨)

課題:「小売の需要予測(回帰)」を想定し、以下の特徴量を作成→CV(KFold)でMAE評価Permutation Importanceで上位5を報告。

  1. ラグamt_lag1, lag7
  2. 移動平均amt_ma4, ma12
  3. 季節month, dow
  4. カテゴリ基準比price_ratio
  5. 在庫ギャップstock_gap(あれば)
  6. 欠損フラグ*_isna
  • [ ] 未来参照なし(shiftは正方向のみ)
  • [ ] 前処理はPipelineに含めた
  • [ ] CV±stdを提示(回帰はneg_mean_absolute_error
  • [ ] Top-k特徴量の重要度を提示
  • [ ] Notebook→スクリプト化(run_all.py

伴走サポート(任意)

ロジックを数字に翻訳できると、精度と納得感が一気に上がります。リーク対策と評価設計まで含め、短期で“回る”仕組みを作るなら、レビュー付きスクールの活用が近道です。

TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

TechAcademy 無料相談

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

キカガク 無料相談

この記事から次に読むべきもの

モデル評価
【保存版】モデル評価:指標の選び方・交差検証・閾値最適化・ビジネス接続を“実務の型”で解説

精度が上がらない原因の多くは「評価設計の誤り」にあります。 評価は「何点取れたか」を競うものではなく、意思決定に耐えうるか を検証する営みです。本記事は、回帰/分類/ランキングの 指標選定 → 交差検 ...

ハイパーパラメータ入門
【保存版】ハイパーパラメータ入門:Grid/Random/Optunaの実務チューニング完全ガイド

チューニングのゴールは「スコアの数字遊び」ではありません。意思決定に耐える安定した最適化を短時間で作ること。 本記事は未経験〜初学者が週10時間×2週間で、GridSearchCV / Randomi ...

機械学習
【保存版】scikit-learn基礎:回帰・分類・前処理・パイプライン・交差検証を“実務の型”で習得

機械学習で迷子になる最大の理由は、前処理→学習→評価→改善の順番が曖昧なまま個々のアルゴリズムに飛びつくこと。 本記事は、未経験〜初学者が週10時間×2〜3週で到達できるscikit-learnの最短 ...

スキルアップ
【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得

基礎文法の次は、実務で毎回出る処理を“型”として覚える段階です。 本記事は、pandas 2.x を前提に、欠損・外れ値・結合・ウィンドウ関数・時系列・カテゴリ処理・集計の自動化・大規模データの分割処 ...

SQL
はじめてのSQL:SELECT/WHERE/GROUP BYを最短で理解【コピペOK】

データ分析・自動レポート・簡易アプリの土台はSQLです。Pythonだけで押し切るより、前処理の7割をDB側で完結させる方が速く・安定します。本記事は、未経験〜初 学者が週10時間×2〜3週で、SEL ...

最近のコメント

    • この記事を書いた人
    • 最新記事

    ふみと

    このブログでは、データサイエンティストとして市場価値を上げる方法を独自にまとめて発信しています。

    【プロフィール】
    ・大手企業データサイエンティスト/マーケティングサイエンティスト(10年、年収900万円台)/案件100件以上
    ・資格:JDLA E資格(日本ディープラーニング協会主催)/JDLA Community(CDLE会員)/Advanced Marketer/ビジネス統計スペシャリスト/統計検定2級/TOEIC 805
    ・スキル:Python/Tableau/SQL/機械学習/Deep Learning/RPA

    -Python基礎, 副業で稼ぐ