机器学习特征工程:缩放、编码、聚合、嵌入与自动化

张开发
2026/4/10 5:32:39 15 分钟阅读

分享文章

机器学习特征工程:缩放、编码、聚合、嵌入与自动化
本文转自DeepHub IMBA好模型的秘诀不在于更花哨的算法而在于更好的特征。第1部分数值特征1. 1 缩放多数机器学习算法对尺度敏感。一个取值范围在0到1,000,000的列会在训练中压制一个取值范围仅0到1的列。常用的三种缩放器各有适用场景StandardScaler适合近似正态分布的数据也是最常见的选择MinMaxScaler将值压缩到0和1之间适合神经网络RobustScaler基于中位数和四分位距IQR而非均值在数据中存在明显异常值时更为稳健。from sklearn.preprocessing import RobustScaler df[salary_scaled] RobustScaler().fit_transform(df[[salary]])⚠️ 缩放器只能在训练集上拟合。在完整数据集上拟合会引入信息泄漏。1. 2 对数变换数值列严重右偏时——收入、价格、营收都是典型例子——对数变换可以拉平分布。import numpy as np df[revenue_log] np.log1p(df[revenue]) # log1p可以安全处理零值1. 3 分箱连续数值有时转换为类别反而更有用。pd.cut()生成等宽分箱适合分布均匀的数据pd.qcut()按分位数切分每个箱中样本量相等更适合偏斜分布。df[age_group] pd.cut(df[age], bins[0, 18, 35, 55, 100], labels[teen, young_adult, adult, senior])1. 4 交互特征两个特征组合后的表达能力往往超过各自单独使用。df[price_per_sqft] df[price] / df[sqft] df[debt_to_income] df[debt] / df[income]线性模型中多项式特征有助于捕获非线性关系from sklearn.preprocessing import PolynomialFeatures poly PolynomialFeatures(degree2, include_biasFalse) # Creates: age, salary, age², salary², age × salary1. 5 裁剪异常值与其删除异常值不如将它们截断到合理的百分位范围。lower df[salary].quantile(0.01) upper df[salary].quantile(0.99) df[salary_clipped] df[salary].clip(lowerlower, upperupper)第2部分类别特征2. 1 独热编码将每个类别展开为独立的0/1列适用于没有内在顺序的名义类别。df_encoded pd.get_dummies(df, columns[city], drop_firstTrue)⚠️ 如果某列包含500个唯一类别独热编码会产生500列。这种情况应改用目标编码。2. 2 标签编码为每个类别赋一个整数仅限数据确实存在顺序关系的场景。df[education] df[education].map({ High School: 0, Bachelor: 1, Master: 2, PhD: 3 })不要对城市名一类的名义数据做标签编码——模型会错误地推断 London Mumbai。2. 3 目标编码用对应分组的目标变量均值替换每个类别值处理高基数列时收效明显。from category_encoders import TargetEncoder df[city_encoded] TargetEncoder().fit_transform(df[city], df[churn])⚠️ 风险在于数据泄漏。生产环境中应采用交叉折叠目标编码。2. 4 频率编码用每个类别的出现频率替换原始值。做法简单但在树模型中的效果常常出人意料。freq_map df[city].value_counts(normalizeTrue) df[city_freq] df[city].map(freq_map)2. 5 二进制编码介于标签编码与独热编码之间的折中方案在保持较少列数的前提下处理高基数特征。from category_encoders import BinaryEncoder df_encoded BinaryEncoder().fit_transform(df[[city]]) # 100 categories → only 7 binary columns第3部分日期时间特征原始日期对多数模型没有意义需要把其中蕴含的时间信息提取出来。3. 1 标准提取df[order_date] pd.to_datetime(df[order_date]) df[month] df[order_date].dt.month df[day_of_week] df[order_date].dt.dayofweek df[is_weekend] df[day_of_week].isin([5, 6]).astype(int) df[quarter] df[order_date].dt.quarter df[days_since] (df[order_date] - pd.Timestamp(2024-01-01)).dt.days3. 2 周期编码 月份如果作为普通数字输入模型会认为十二月12和一月1距离很远——但它们只隔一个月。用正弦和余弦变换可以保留周期结构import numpy as np df[month_sin] np.sin(2 * np.pi * df[month] / 12) df[month_cos] np.cos(2 * np.pi * df[month] / 12)同样的思路适用于一天中的小时除以24。3. 3 工作日历特征import holidays indian_holidays holidays.India(years2025) df[is_holiday] df[order_date].apply(lambda d: d in indian_holidays).astype(int) df[is_month_end] df[order_date].dt.is_month_end.astype(int)第4部分文本特征4. 1 基础统计特征在引入任何NLP手段之前先提取简单的统计量。实际效果往往超出预期。df[word_count] df[review].str.split().str.len() df[avg_word_len] df[review].str.len() / df[word_count] df[has_question] df[review].str.contains(r\\\\?).astype(int) df[uppercase_ratio] df[review].apply( lambda x: sum(c.isupper() for c in str(x)) / max(len(str(x)), 1) )4. 2 TF-IDFTF-IDF将文本转换为按词项重要性加权的数值表示。from sklearn.feature_extraction.text import TfidfVectorizer tfidf TfidfVectorizer(max_features100, ngram_range(1, 2), stop_wordsenglish) X_tfidf tfidf.fit_transform(df[review])4. 3 情感得分from textblob import TextBlob df[sentiment] df[review].apply(lambda x: TextBlob(str(x)).sentiment.polarity) # 范围从-1非常消极到1非常积极4. 4 句子嵌入更现代的做法是用预训练模型将文本压缩为稠密向量从而捕获语义信息。在深度学习场景下这比TF-IDF的表达能力高出一个量级。from sentence_transformers import SentenceTransformer model SentenceTransformer(all-MiniLM-L6-v2) embeddings model.encode(df[review].tolist()) # Shape: (n_rows, 384) — each row becomes 384 numerical features第5部分地理空间特征5. 1 距离特征一个数据点与关键地标之间的距离本身就是一个信息量很大的特征。from math import radians, sin, cos, sqrt, atan2 def haversine(lat1, lon1, lat2, lon2): R 6371 lat1, lon1, lat2, lon2 map(radians, [lat1, lon1, lat2, lon2]) a sin((lat2-lat1)/2)**2 cos(lat1)*cos(lat2)*sin((lon2-lon1)/2)**2 return R * 2 * atan2(sqrt(a), sqrt(1-a)) city_centre (28.6139, 77.2090) df[dist_to_centre_km] df.apply( lambda r: haversine(r[lat], r[lon], *city_centre), axis1 )5. 2 GeohashGeohash将经纬度编码为短字符串每个前缀对应一个地理区域天然适合做位置聚合。import pygeohash as pgh df[geohash_5] df.apply(lambda r: pgh.encode(r[lat], r[lon], precision5), axis1) # precision 5 roughly 5km area第6部分聚合特征在生产环境的机器学习系统中聚合类特征的价值极高尤其是在客户行为和交易数据上。6. 1 分组聚合stats df.groupby(customer_id).agg( total_orders(order_id, count), total_spent(amount, sum), avg_order_value(amount, mean), max_order(amount, max) ).reset_index() df df.merge(stats, oncustomer_id, howleft)6. 2 滞后和滚动特征序列数据中过去N个时间段内发生了什么往往是预测能力最强的信号。df df.sort_values([customer_id, order_date]) df[prev_order_amount] df.groupby(customer_id)[amount].shift(1) df[amount_change] df[amount] - df[prev_order_amount] df[rolling_30d_spend] ( df.groupby(customer_id)[amount] .transform(lambda x: x.rolling(3).sum()) )第7部分特征选择构造特征只是工作的一半另一半是筛掉无用的。7.1 删除低方差特征如果一列的值几乎不变化模型从中学不到任何东西。from sklearn.feature_selection import VarianceThreshold selector VarianceThreshold(threshold0.01) X_reduced selector.fit_transform(X)7.2 删除高相关特征高度相关的特征本质上是冗余信息。保留一个其余丢弃。corr df.corr().abs() upper corr.where(np.triu(np.ones(corr.shape), k1).astype(bool)) to_drop [col for col in upper.columns if any(upper[col] 0.95)] df.drop(columnsto_drop, inplaceTrue)7.3 特征重要性用树模型对特征排序重要性接近零的直接去掉。from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier(n_estimators100, random_state42) model.fit(X_train, y_train) importance pd.Series(model.feature_importances_, indexX_train.columns) print(importance.sort_values(ascendingFalse).head(20))7.4 SHAP值SHAP不仅能揭示哪些特征重要还能解释每个特征对单条预测结果的具体影响方向和幅度。import shap explainer shap.TreeExplainer(model) shap_values explainer.shap_values(X_train) shap.summary_plot(shap_values, X_train)第8部分自动化特征工程当候选组合数量庞大时手动构造特征不再现实。更好的做法是用程序批量生成再交由特征选择环节做筛选。import featuretools as ft es ft.EntitySet(idorders) es es.add_dataframe(dataframe_nameorders, dataframedf, indexorder_id, time_indexorder_date) feature_matrix, feature_defs ft.dfs( entitysetes, target_dataframe_nameorders, agg_primitives[sum, mean, count, max, std], trans_primitives[month, weekday, is_weekend], max_depth2 ) print(fGenerated {len(feature_defs)} features automatically)跑完之后依次过方差过滤、相关性过滤再看特征重要性得分留下来的就是值得用的。总结特征工程是领域知识和技术能力的交叉地带。算法再精妙也无法弥补特征层面的粗糙。持续产出高质量模型的工程师往往不是掌握算法最多的人而是对数据理解最深的人。从简单的特征开始量化每一步的收益只在简单版本不够用的时候才引入复杂度。by ATNOEND欢迎加入Imagination GPU与人工智能交流2群入群请加小编微信eetrend89添加请备注公司名和职称推荐阅读Imagination D-Series GPU 实机演示支持DirectX 游戏边缘AI时代的流片风险GPU IP的优势所在Imagination Technologies 是一家总部位于英国的公司致力于研发芯片和软件知识产权IP基于Imagination IP的产品已在全球数十亿人的电话、汽车、家庭和工作场所中使用。获取更多物联网、智能穿戴、通信、汽车电子、图形图像开发等前沿技术信息欢迎关注 Imagination Tech

更多文章