# 機械学習のための特徴量エンジニアリング:技術面接で差をつけるテクニック2026 > Pythonによる実践的な特徴量エンジニアリングの手法を解説。エンコーディング、スケーリング、特徴量選択、scikit-learnパイプライン構築、そしてデータサイエンス面接の頻出問題まで網羅します。 - Published: 2026-05-08 - Updated: 2026-05-08 - Author: SharpSkill - Tags: feature engineering, machine learning, scikit-learn, data science, interview preparation, python - Reading time: 5 min --- 機械学習モデルの性能を決定する最も重要な要素の一つが特徴量エンジニアリング(Feature Engineering)です。優れたアルゴリズムを使用しても、入力データの品質が低ければ期待する結果は得られません。本記事では、2026年の技術面接で頻出する特徴量エンジニアリングの主要テクニックを、実践的なコード例とともに解説します。 データサイエンティストやMLエンジニアの採用面接では、単にライブラリの使い方を知っているだけでは不十分です。各手法の理論的背景、適用すべき状況、そして本番環境での実装における注意点まで理解していることが求められます。 > **特徴量エンジニアリングの重要性** > > Kaggleの上位入賞者の多くが、モデル選択よりも特徴量エンジニアリングに多くの時間を費やしていると報告しています。適切な特徴量設計により、シンプルなモデルでも複雑なモデルを凌駕する性能を発揮することがあります。 ## カテゴリカル変数のエンコーディング戦略 カテゴリカル変数(Categorical Variables)を機械学習モデルで扱うためには、数値形式への変換が必要です。しかし、変換手法の選択を誤ると、モデルが誤った関係性を学習してしまう可能性があります。 順序尺度(Ordinal)の変数には、その順序関係を保持するLabel Encodingが適しています。例えば、サイズ(small, medium, large)のように自然な順序がある場合です。一方、名義尺度(Nominal)の変数、つまり順序関係のない変数にはOne-Hot Encodingを使用します。色(red, blue, green)のように、どの値が「大きい」とも言えない場合がこれに該当します。 ```python # encoding_strategies.py import pandas as pd from sklearn.preprocessing import LabelEncoder, OneHotEncoder from sklearn.compose import ColumnTransformer df = pd.DataFrame({ "size": ["small", "medium", "large", "medium", "small"], "color": ["red", "blue", "green", "red", "blue"], "price": [10, 25, 40, 22, 12] }) # Label encoding for ordinal feature (size has natural order) le = LabelEncoder() df["size_encoded"] = le.fit_transform(df["size"]) # large=0, medium=1, small=2 # One-hot encoding for nominal feature (color has no order) ct = ColumnTransformer( transformers=[ ("onehot", OneHotEncoder(drop="first", sparse_output=False), ["color"]) ], remainder="passthrough" # Keep other columns unchanged ) result = ct.fit_transform(df[["color", "price"]]) # Produces: color_green, color_red columns (blue dropped as reference) ``` One-Hot Encodingでは、`drop="first"`オプションを使用することで、ダミー変数の罠(Dummy Variable Trap)を回避しています。これは多重共線性(Multicollinearity)を防ぐための標準的な手法です。カテゴリ数が多い場合は、次元数の爆発を避けるためにTarget EncodingやFrequency Encodingの使用を検討する必要があります。 > **Target Encodingとデータリーケージ** > > Target Encodingは高カーディナリティ変数に有効ですが、目的変数の情報を直接特徴量に埋め込むため、データリーケージ(Data Leakage)のリスクがあります。必ずクロスバリデーション内で計算し、学習データとテストデータを厳密に分離してください。Out-of-Fold(OOF)方式での実装が推奨されます。 ## 特徴量スケーリングの選択基準 特徴量のスケール(尺度)を統一することは、勾配降下法を使用するアルゴリズムや距離ベースのアルゴリズムにおいて非常に重要です。しかし、どのスケーリング手法を選択するかは、データの分布特性に依存します。 StandardScalerは平均0、標準偏差1に変換しますが、外れ値(Outliers)の影響を強く受けます。MinMaxScalerは指定範囲(通常は0から1)にスケーリングしますが、やはり外れ値に敏感です。外れ値が存在するデータセットでは、中央値と四分位範囲(IQR)を使用するRobustScalerが適切な選択となります。 ```python # feature_scaling.py import numpy as np from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler # Simulated dataset: salary with outliers data = np.array([[35000], [42000], [55000], [67000], [450000]]) # 450k is an outlier # StandardScaler: mean=0, std=1 (sensitive to outliers) standard = StandardScaler().fit_transform(data) # Result: [-0.72, -0.68, -0.60, -0.53, 2.53] — outlier distorts the scale # MinMaxScaler: maps to [0, 1] (very sensitive to outliers) minmax = MinMaxScaler().fit_transform(data) # Result: [0.0, 0.017, 0.048, 0.077, 1.0] — most values crushed near zero # RobustScaler: uses median and IQR (robust to outliers) robust = RobustScaler().fit_transform(data) # Result: [-0.77, -0.5, 0.0, 0.46, 15.38] — outlier isolated, core data preserved ``` 上記の例では、45万という外れ値が存在する給与データを処理しています。StandardScalerとMinMaxScalerでは、この外れ値によってデータ全体のスケールが歪められ、大多数のデータポイントが狭い範囲に圧縮されてしまいます。RobustScalerを使用することで、外れ値を分離しながら、コアとなるデータの分布を適切に保持できます。 なお、決定木ベースのアルゴリズム(Random Forest、XGBoost、LightGBMなど)はスケーリングの影響を受けないため、これらのモデルを使用する場合はスケーリングを省略できます。 ## 歪んだ分布の数学的変換 実世界のデータセットでは、収入、人口、取引金額など、右に歪んだ分布(Right-Skewed Distribution)を示す変数が頻繁に見られます。このような歪度(Skewness)の高い変数は、多くの機械学習アルゴリズムの性能に悪影響を与える可能性があります。 対数変換(Log Transformation)は、右に歪んだ分布を正規分布に近づけるための最もシンプルで効果的な手法です。`np.log1p()`関数を使用することで、ゼロ値を含むデータも安全に処理できます。 より高度な手法として、Box-Cox変換とYeo-Johnson変換があります。Box-Cox変換は最適なパワーパラメータ(lambda)を自動的に見つけますが、正の値のみに適用可能です。Yeo-Johnson変換はゼロや負の値にも対応できるため、より汎用的に使用できます。 ```python # skew_transformations.py import numpy as np from sklearn.preprocessing import PowerTransformer # Right-skewed income data (common in real datasets) income = np.array([[25000], [32000], [41000], [55000], [72000], [150000], [320000], [890000]]) # Log transform: simple, effective for right-skewed data log_income = np.log1p(income) # log1p handles zero values safely # Box-Cox: finds optimal power parameter automatically pt = PowerTransformer(method="box-cox") # Requires strictly positive values income_boxcox = pt.fit_transform(income) print(f"Optimal lambda: {pt.lambdas_[0]:.3f}") # Shows learned parameter # Yeo-Johnson: works with zero and negative values too pt_yj = PowerTransformer(method="yeo-johnson") income_yj = pt_yj.fit_transform(income) ``` PowerTransformerは学習したパラメータを保持するため、テストデータに対しても一貫した変換を適用できます。これは本番環境でのデプロイメントにおいて重要な特性です。 ## 特徴量選択のアプローチ 高次元データを扱う場合、特徴量選択(Feature Selection)は過学習の防止とモデルの解釈性向上のために不可欠です。特徴量選択の手法は、フィルター法(Filter Methods)、ラッパー法(Wrapper Methods)、埋め込み法(Embedded Methods)の3つのカテゴリに分類されます。 フィルター法は、モデルに依存しない統計的手法を使用して特徴量をランク付けします。ANOVA F検定やカイ二乗検定が代表的です。計算コストが低い一方、特徴量間の相互作用を考慮できないという欠点があります。 ラッパー法は、実際のモデルを使用して特徴量のサブセットを評価します。前向き選択(Forward Selection)や後向き除去(Backward Elimination)が含まれます。精度は高いですが、計算コストが高くなります。 埋め込み法は、モデルの学習プロセス自体に特徴量選択を組み込みます。L1正則化(Lasso)は、重要でない特徴量の係数をゼロに押し下げることで、自動的に特徴量選択を行います。 ```python # feature_selection.py from sklearn.datasets import make_classification from sklearn.feature_selection import ( SelectKBest, f_classif, # Filter method SequentialFeatureSelector, # Wrapper method SelectFromModel # Embedded method ) from sklearn.ensemble import RandomForestClassifier from sklearn.linear_model import LassoCV # Dataset: 20 features, only 5 are informative X, y = make_classification( n_samples=1000, n_features=20, n_informative=5, n_redundant=3, random_state=42 ) # Filter: ANOVA F-test selects top k features by statistical significance selector_filter = SelectKBest(f_classif, k=8) X_filtered = selector_filter.fit_transform(X, y) print(f"Selected features: {selector_filter.get_support(indices=True)}") # Embedded: L1 regularization (Lasso) zeros out irrelevant feature weights lasso = LassoCV(cv=5, random_state=42).fit(X, y) selector_embedded = SelectFromModel(lasso, prefit=True) X_lasso = selector_embedded.transform(X) print(f"Lasso kept {X_lasso.shape[1]} features out of {X.shape[1]}") ``` このコード例では、20個の特徴量のうち5個のみが真に有用なデータセットを生成しています。フィルター法(SelectKBest)は統計的有意性に基づいて上位8個の特徴量を選択し、埋め込み法(Lasso)はクロスバリデーションを通じて最適な正則化強度を決定し、不要な特徴量を自動的に除外しています。 ## 本番環境向けパイプライン構築 本番環境では、前処理とモデルを統合したパイプライン(Pipeline)を構築することが標準的なプラクティスです。scikit-learnのPipelineとColumnTransformerを組み合わせることで、データ型ごとに異なる前処理を適用し、再現性のある予測システムを実現できます。 パイプライン設計において最も重要な点は、前処理のパラメータ(平均値、標準偏差、エンコーディングのカテゴリなど)が学習データのみから計算されることです。これにより、テストデータや本番データに対するデータリーケージを防止できます。 ```python # production_pipeline.py import pandas as pd from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from sklearn.impute import SimpleImputer from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.ensemble import GradientBoostingClassifier from sklearn.model_selection import cross_val_score # Define column groups by type numeric_features = ["age", "income", "credit_score"] categorical_features = ["education", "employment_type", "region"] # Numeric pipeline: impute missing values, then scale numeric_pipeline = Pipeline([ ("imputer", SimpleImputer(strategy="median")), # Median resists outliers ("scaler", StandardScaler()) ]) # Categorical pipeline: impute missing, then one-hot encode categorical_pipeline = Pipeline([ ("imputer", SimpleImputer(strategy="most_frequent")), ("encoder", OneHotEncoder(handle_unknown="ignore", sparse_output=False)) ]) # Combine into a single preprocessor preprocessor = ColumnTransformer([ ("num", numeric_pipeline, numeric_features), ("cat", categorical_pipeline, categorical_features) ]) # Full pipeline: preprocessing + model in one object full_pipeline = Pipeline([ ("preprocessor", preprocessor), ("classifier", GradientBoostingClassifier(n_estimators=200, random_state=42)) ]) # Cross-validation applies preprocessing correctly within each fold scores = cross_val_score(full_pipeline, X, y, cv=5, scoring="roc_auc") print(f"AUC: {scores.mean():.3f} +/- {scores.std():.3f}") ``` このパイプラインでは、数値型特徴量には中央値による欠損値補完とStandardScalerによるスケーリングを、カテゴリカル特徴量には最頻値による欠損値補完とOne-Hot Encodingを適用しています。`handle_unknown="ignore"`オプションにより、学習時に存在しなかったカテゴリが本番環境で出現しても、エラーなく処理できます。 クロスバリデーションをパイプライン全体に対して実行することで、各フォールド内で前処理パラメータが独立して計算され、評価スコアの信頼性が向上します。 ## 自動特徴量エンジニアリング リレーショナルデータベースから特徴量を自動生成するFeaturetoolsは、複雑なドメイン知識を持たない場合でも、有用な特徴量を効率的に作成できるツールです。Deep Feature Synthesis(DFS)アルゴリズムにより、テーブル間の関係性を活用した集約特徴量を自動的に生成します。 顧客と取引という2つのテーブルがある場合、Featuretoolsは顧客ごとの取引回数、平均取引金額、最大取引金額などの集約特徴量を自動的に計算します。さらに、日時データから月や曜日を抽出する変換も行えます。 ```python # automated_feature_engineering.py import featuretools as ft import pandas as pd # Define entities from relational tables customers = pd.DataFrame({ "customer_id": [1, 2, 3], "signup_date": pd.to_datetime(["2024-01-15", "2024-03-22", "2024-06-01"]), "region": ["US", "EU", "APAC"] }) transactions = pd.DataFrame({ "txn_id": range(1, 8), "customer_id": [1, 1, 1, 2, 2, 3, 3], "amount": [50, 120, 30, 200, 85, 340, 15], "category": ["food", "tech", "food", "tech", "travel", "food", "tech"] }) # Create an EntitySet with relationships es = ft.EntitySet(id="retail") es = es.add_dataframe(dataframe=customers, dataframe_name="customers", index="customer_id", time_index="signup_date") es = es.add_dataframe(dataframe=transactions, dataframe_name="transactions", index="txn_id") es = es.add_relationship("customers", "customer_id", "transactions", "customer_id") # DFS generates features: COUNT, MEAN, MAX, STD of transactions per customer feature_matrix, feature_defs = ft.dfs( entityset=es, target_dataframe_name="customers", max_depth=2, # Controls complexity of generated features trans_primitives=["month", "weekday"], # Transformation primitives agg_primitives=["count", "mean", "std", "max"] # Aggregation primitives ) print(f"Generated {len(feature_defs)} features from 2 tables") ``` `max_depth`パラメータは生成される特徴量の複雑さを制御します。深さを増やすと、より複雑な特徴量(例:「各顧客の月曜日の平均取引金額」)が生成されますが、計算コストと過学習のリスクも増加します。実務では、生成された特徴量を特徴量選択手法でフィルタリングすることが推奨されます。 > **面接での差別化ポイント** > > 面接では、単にツールの使い方を説明するだけでなく、実務での課題と解決策を具体的に語れることが重要です。例えば、「Featuretoolsで生成した500個の特徴量から、LassoとPermutation Importanceを組み合わせて50個に絞り込んだ」といった経験を共有できると、実践力をアピールできます。 ## 面接で頻出する質問と回答のポイント 特徴量エンジニアリングに関する技術面接では、理論と実践の両面から質問されることが一般的です。以下に、代表的な質問と回答のポイントを紹介します。 「One-Hot EncodingとLabel Encodingの使い分けを説明してください」という質問に対しては、変数の性質(順序尺度か名義尺度か)に基づいて判断することを説明し、高カーディナリティ変数に対するTarget EncodingやHash Encodingにも言及できると良いでしょう。 「外れ値がある場合のスケーリング手法は何を選びますか」という質問では、RobustScalerの使用を推奨しつつ、外れ値の処理方針(除去、クリッピング、変換)についても議論できることが望まれます。 「特徴量選択の3つのアプローチの違いを説明してください」という質問に対しては、フィルター法、ラッパー法、埋め込み法それぞれの特徴、利点、欠点を説明し、実務でどのように組み合わせるかを述べられると高評価につながります。 「本番環境での特徴量エンジニアリングの注意点は何ですか」という質問では、データリーケージの防止、欠損値や未知のカテゴリの処理、パイプラインのバージョン管理、モニタリングなどの観点から回答することが期待されます。 詳細な面接質問と回答例については、[特徴量エンジニアリングの面接問題集](/technologies/data-science/interview-questions/feature-engineering)も参照してください。 関連するトピックとして、[機械学習アルゴリズムの詳細解説](/blog/data-science/machine-learning-algorithms-explained)や[Pythonデータサイエンスの基礎](/blog/data-science/python-data-science-numpy-pandas-scikit-learn-2026)も併せて学習することをお勧めします。 ## まとめ 本記事では、2026年のデータサイエンス面接に向けて、特徴量エンジニアリングの主要テクニックを解説しました。 - **カテゴリカルエンコーディング**:変数の性質(順序尺度・名義尺度)に応じてLabel EncodingとOne-Hot Encodingを使い分け、高カーディナリティ変数にはTarget Encodingを検討する - **特徴量スケーリング**:外れ値の有無に応じてStandardScaler、MinMaxScaler、RobustScalerを選択し、決定木ベースのモデルではスケーリングは不要 - **分布変換**:右に歪んだ分布にはLog変換やBox-Cox/Yeo-Johnson変換を適用し、正規分布に近づける - **特徴量選択**:フィルター法(統計的検定)、ラッパー法(モデルベース評価)、埋め込み法(正則化)を目的に応じて使い分ける - **パイプライン構築**:ColumnTransformerとPipelineを使用して、データ型ごとの前処理を統合し、データリーケージを防止する - **自動特徴量エンジニアリング**:Featuretoolsを活用してリレーショナルデータから特徴量を自動生成し、特徴量選択でフィルタリングする これらのテクニックを体系的に理解し、実際のコードで実装できることが、技術面接での成功につながります。 --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ja/blog/data-science/feature-engineering-machine-learning-techniques-interview-2026