机器学习特征工程实战:方法与避坑指南

📅 2026/7/3 4:26:30
机器学习特征工程实战:方法与避坑指南
1. 特征工程的核心价值第一次接触机器学习项目时我犯了个典型错误——把所有时间都花在模型调参上结果准确率死活上不去。直到导师提醒我垃圾进垃圾出(Garbage in, garbage out)才意识到特征质量才是模型效果的天花板。特征工程就像厨师处理食材再厉害的厨艺也救不了变质的原料。在实际工业场景中数据科学家70%的时间都花在数据清洗和特征工程上。好的特征不仅能提升模型效果还能降低计算成本。去年我们团队做过对比实验在同一个电商推荐项目中仅通过特征优化就将AUC从0.72提升到0.81同时推理耗时减少了40%。2. 特征构建方法论2.1 数值型特征处理连续数值的尺度问题是最常见的坑。上周刚处理过一个传感器数据集温度值范围在-20~300之间而湿度值只有0~1。如果不做标准化直接喂给模型相当于告诉算法温度比湿度重要几百倍。我常用的标准化组合拳from sklearn.preprocessing import StandardScaler, MinMaxScaler # 对正态分布特征用Z-score标准化 scaler StandardScaler() df[temperature_normalized] scaler.fit_transform(df[[temperature]]) # 对存在边界值的特征用MinMax scaler MinMaxScaler(feature_range(0,1)) df[humidity_scaled] scaler.fit_transform(df[[humidity]])特别注意一定要用训练集的统计量来转换测试集我在早期项目里犯过用全数据集做标准化的错误导致线上效果严重虚高。2.2 类别型特征编码One-Hot编码虽然经典但在高基数(high-cardinality)特征上会引发维度灾难。去年处理用户地域特征时200多个城市的one-hot直接让特征矩阵膨胀到内存装不下。现在我的编码策略会根据特征基数动态调整基数10One-Hot10基数50Target Encoding基数50哈希编码(Hashing Trick)# Target Encoding示例 from category_encoders import TargetEncoder encoder TargetEncoder(cols[city]) train_df encoder.fit_transform(train_df, train_df[target]) test_df encoder.transform(test_df)2.3 时间特征分解原始时间戳是最糟糕的特征形式。处理订单数据时我会把datetime拆解成多个有业务意义的维度df[order_hour] df[order_time].dt.hour df[is_weekend] df[order_time].dt.weekday 5 df[day_of_month] df[order_time].dt.day最近还发现个有意思的pattern把小时转换为三角坐标可以保留周期性df[hour_sin] np.sin(2*np.pi*df[order_hour]/24) df[hour_cos] np.cos(2*np.pi*df[order_hour]/24)3. 特征选择实战技巧3.1 统计过滤法相关系数矩阵是最快的初筛工具但要注意两点只能检测线性关系对异常值敏感我通常会结合方差阈值先过滤掉不变的特征from sklearn.feature_selection import VarianceThreshold selector VarianceThreshold(threshold0.01) selected_features selector.fit_transform(df)3.2 模型特征重要性树模型的特征重要性是最直观的但要注意不同模型可能给出不同结果。我的做法是用多个模型交叉验证from sklearn.ensemble import RandomForestClassifier from xgboost import XGBClassifier models [RandomForestClassifier(), XGBClassifier()] for model in models: model.fit(X_train, y_train) print(pd.Series(model.feature_importances_, indexX.columns))3.3 递归特征消除(RFE)RFE就像反向的特征达尔文主义——从全量特征开始逐步淘汰弱者。在信贷风控项目中我们用RFE将特征从120个精简到35个KS值反而提升了5个百分点。from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression rfe RFE( estimatorLogisticRegression(), n_features_to_select30 ) X_rfe rfe.fit_transform(X, y)4. 高级特征工程技巧4.1 交互特征挖掘特征交叉是提升模型表现的大杀器。在广告CTR预测中用户职业和广告类别的组合特征比单特征重要得多。但要注意组合爆炸问题。我的经验法则是先做业务逻辑强相关的交叉再用统计方法验证效果最后考虑二阶/三阶组合# 用PolynomialFeatures自动生成交互项 from sklearn.preprocessing import PolynomialFeatures poly PolynomialFeatures(degree2, interaction_onlyTrue) X_interact poly.fit_transform(X[[age, income]])4.2 自动特征生成工具现在越来越依赖FeatureTools这类自动化工具了。最近一个零售项目里用深度特征合成(DFS)自动生成了用户最近3次购买的平均间隔这类时序特征效果远超手工设计。import featuretools as ft es ft.EntitySet(idtransactions) es es.entity_from_dataframe( entity_idtrans, dataframetrans_df, time_indexpurchase_time, variable_types{user_id: ft.variable_types.Categorical} ) features, _ ft.dfs( entitysetes, target_entitytrans, max_depth2 )4.3 特征存储方案随着特征工程越来越复杂我建立了特征库来管理不同版本的特征集。使用Feast框架后线上线下的特征一致性有了保障from feast import FeatureStore store FeatureStore(repo_path.) training_df store.get_historical_features( entity_dfentity_df, features[ user_stats:avg_order_value, user_stats:last_purchase_category ] ).to_df()5. 避坑指南与性能优化5.1 数据泄露预防最惨痛的教训来自一个时间序列预测项目不小心用未来数据做了标准化导致验证集表现好得离谱。现在我的黄金法则是任何涉及统计量计算的操作都要分训练/测试集时间序列必须严格按时间切分用Pipeline封装所有预处理步骤from sklearn.pipeline import Pipeline pipe Pipeline([ (scaler, StandardScaler()), (model, LogisticRegression()) ]) pipe.fit(X_train, y_train) # 自动防止数据泄露5.2 计算效率优化当特征维度超过百万时传统方法就会遇到瓶颈。我的应对策略稀疏矩阵存储对于one-hot后的高维数据增量学习处理超出内存的大数据集并行化用Dask或Spark加速from scipy.sparse import csr_matrix sparse_matrix csr_matrix(one_hot_encoded_df)5.3 监控与迭代特征工程不是一劳永逸的。我们建立了特征监控看板跟踪特征缺失率变化数值分布漂移重要性排名波动当监控到某个关键特征的分布发生显著变化时用KS检验检测就需要重新评估特征有效性。