在数据科学和机器学习项目中特征工程往往是决定模型性能上限的关键环节但也是一个耗时且需要大量领域知识的“脏活累活”。传统自动化特征工程AutoFE工具虽然能减轻负担但通常严重依赖数据集的元数据如列名、数据类型、统计信息来生成特征这在面对缺乏清晰元数据的原始数据或需要跨领域迁移时效果会大打折扣。近期一种名为SIGMA的新方法进入了研究者的视野它巧妙地结合了SHAP可解释性技术与LLM的强大生成能力旨在实现一种“免元数据”的自动化特征工程。本文将深入拆解 SIGMA 的核心思想、技术实现路径并提供一个基于开源工具的可复现实践指南帮助开发者理解并尝试这一前沿方向。1. SIGMA 方法的核心概念与背景1.1 什么是“免元数据”的 AutoFE在常规的 AutoFE 流程中系统需要预先知道数据的结构哪些是数值列、哪些是分类列、列与列之间可能存在的业务关系等。这些信息就是“元数据”。然而在真实场景中数据可能来自日志文件、爬虫结果或未经清洗的数据库导出列名可能是无意义的编码如f1,f2或者数据类型混杂。传统的基于规则或搜索的 AutoFE 方法在这种“盲”环境下很难有效工作。SIGMA提出的“免元数据”Metadata-Free目标是希望不依赖这些先验的结构化描述仅通过分析数据本身的分布、模式以及其与预测目标的关系来自动推导并生成有价值的特征。这更像是一个数据科学家在面对未知数据集时的探索过程。1.2 核心组件SHAP 与 LLM 的角色SIGMA 的名称揭示了其两大技术支柱SHAP和LLM。SHAP (SHapley Additive exPlanations)这是一种来自博弈论的特征归因方法用于解释任何机器学习模型的预测。对于数据集中的每一个样本SHAP 值可以告诉我们每个特征对于该样本最终预测结果的贡献度是多少正贡献或负贡献。在 SIGMA 的语境下SHAP 值不再仅仅是“解释”工具而是成为了“指导”特征生成的“信号”。通过分析 SHAP 值在不同样本和特征间的分布模式可以识别出现有特征的不足或潜在的特征组合机会。LLM (Large Language Model)如 GPT、LLaMA 等大语言模型拥有强大的代码生成、逻辑推理和遵循指令的能力。在 SIGMA 中LLM 扮演着“特征工程师”的角色。它接收来自 SHAP 分析的“指导信号”以自然语言或结构化提示的形式并结合对原始数据样本的“观察”生成用于创建新特征的数据转换代码例如 Python 的 Pandas 或 NumPy 代码片段。1.3 SIGMA 的工作流程隐式轨迹生成“Implicit-Trajectory Generation”是 SIGMA 的另一大亮点。我们可以将其理解为一种动态的、目标驱动的特征构造路径。初始化在一个基础模型如简单的线性模型或树模型上使用原始特征进行训练并计算其 SHAP 值。分析指导信号分析 SHAP 值识别问题。例如特征重要性冲突某个特征对部分样本贡献很大对另一部分却为负这可能暗示需要对该特征进行分箱或与其他特征交互。预测偏差模型在某些样本子集上预测不准SHAP 显示现有特征解释力不足可能需要构造针对该子集的新特征。LLM 生成特征将上述分析结果、问题描述以及相关的数据样本或统计摘要构造为提示词Prompt提交给 LLM。LLM 的输出是一段可执行代码用于生成一个新的特征列。评估与迭代将新特征加入数据集重新训练模型并评估性能如 AUC、RMSE。如果提升显著则保留该特征并基于新的模型状态新的 SHAP 值开始下一轮迭代形成一条持续优化的“轨迹”。这个过程是“隐式”的因为它不是预先定义好的特征模板而是由数据本身和模型解释动态驱动的。2. 环境准备与工具选择要实践 SIGMA 的思想我们需要搭建一个包含机器学习、可解释性分析和代码生成的环境。2.1 基础环境配置建议使用 Python 作为主要语言。以下是核心库及其作用# 创建虚拟环境可选但推荐 python -m venv sigma_env source sigma_env/bin/activate # Linux/Mac # sigma_env\Scripts\activate # Windows # 安装核心依赖 pip install pandas numpy scikit-learn # 用于基础建模和评估 pip install xgboost lightgbm # 使用强大的树模型其 SHAP 值计算高效且解释性强 pip install shap # 核心库用于计算 SHAP 值 pip install openai # 如果使用 OpenAI GPT 系列 API # 或者安装其他 LLM 的本地库如 transformers, llama-cpp-python版本兼容性说明shap库与xgboost、lightgbm的版本有时存在兼容性问题。如果遇到500 internal server error或non-zero exit这类与进程终止相关的错误这在一些本地部署的 LLM 服务或特定计算中也可能出现首先应检查库版本。一个稳定的组合是xgboost1.7.6,shap0.44.0。2.2 LLM 接入选择你有两种路径选择云端 API便捷如 OpenAI GPT-4/3.5-Turbo Anthropic Claude。需要网络和 API Key。import openai openai.api_key your-api-key本地模型可控如使用transformers加载 LLaMA、Qwen 等开源模型或使用llama.cpp等工具部署。这需要一定的 GPU 资源或利用量化模型在 CPU 上运行。避免出现comfyui 与 llm 必须在同一台电脑上么的困惑对于 SIGMA 这类自动化流程LLM 作为代码生成服务最好与特征工程脚本在同一环境或可通过网络可靠调用。2.3 项目结构示意sigma_autofe_project/ ├── data/ │ ├── raw.csv # 原始数据 │ └── processed/ # 生成的特征数据 ├── src/ │ ├── sigma_pipeline.py # 主流程管道 │ ├── shap_analyzer.py # SHAP 分析与信号提取 │ ├── llm_feature_generator.py # LLM 提示与代码生成 │ └── evaluator.py # 特征与模型评估 ├── config.yaml # 配置文件API密钥、模型路径等 └── main.py # 主执行脚本3. 核心原理拆解从 SHAP 值到生成提示这是 SIGMA 方法最关键的环节即如何将 SHAP 的数值输出转化为 LLM 能理解并执行的任务描述。3.1 SHAP 值的深度分析计算 SHAP 值后我们得到的是一个形状为(n_samples, n_features)的矩阵。简单的全局特征重要性shap_values.abs.mean(axis0)不足以指导生成。我们需要更细粒度的洞察样本簇级别的洞察使用聚类算法如 K-Means对 SHAP 值矩阵进行聚类识别出具有相似特征贡献模式的样本组。对于某一簇样本如果某个特征f1的 SHAP 值普遍很高且为正而另一特征f2为负则可以假设f1和f2在该簇代表的子群体中存在某种交互或替代关系。特征交互检测计算 SHAP 交互值shap.TreeExplainer(model).shap_interaction_values(X)直接量化特征两两之间的交互效应。强交互效应是特征组合如乘积、比值的明确信号。残差分析将模型预测误差较大的样本残差大单独提取出来分析这些样本的 SHAP 值模式。可能发现某些特征对这些“难”样本的贡献模式与整体相反提示需要条件逻辑的特征。3.2 构造 LLM 提示词Prompt提示词的质量直接决定生成特征的相关性。一个有效的提示应包含角色与任务定义明确告诉 LLM 它是一名数据科学家。上下文信息简要描述数据集和目标分类/回归。问题诊断用自然语言描述从 SHAP 分析中发现的具体“问题”。示例“我们发现对于年收入高于 10 万的客户群体样本索引 120-200特征‘账户年龄’对预测‘是否购买’的贡献度SHAP值非常低甚至为负但这与业务直觉不符。可能‘账户年龄’在该群体中需要与‘登录频率’结合才能体现价值。”数据片段提供几行相关的原始数据df.iloc[sample_indices]让 LLM 有具体的操作对象。输出格式要求严格要求 LLM 只输出一个 Python 函数该函数以 pandas DataFrame 为输入返回一个新的 Series即新特征。约束条件禁止使用未来信息如目标变量确保生成代码的安全性和可执行性。# 提示词示例模板 prompt_template 你是一名资深数据科学家正在执行自动化特征工程任务。 **任务背景** 我们有一个数据集目标是预测{task_description}。原始特征包括{feature_list}。 **当前问题** 基于当前模型的 SHAP 可解释性分析我们发现{shap_insight}。 **相关数据样本前5行** {sample_data_head} **你的任务** 请编写一个 **单一的 Python 函数**命名为 create_new_feature。该函数 1. 输入一个 pandas DataFrame df包含上述所有原始特征列。 2. 处理在函数内部基于你的领域知识和上述问题分析通过对现有特征进行数学运算、条件判断、分组聚合等操作创造一个新的特征。 3. 输出返回一个新的 pandas Series长度与 df 相同即新特征的值。 4. 要求绝对不要使用目标变量列 {target_column}。确保函数能独立运行。 只输出这个函数的代码不要有任何额外的解释、注释或描述。 4. 完整实战案例房价预测数据集我们以经典的波士顿房价数据集简化版为例演示 SIGMA 思想的手动实现流程。假设数据已加载到 DataFramedf中目标变量是‘PRICE’。4.1 初始建模与 SHAP 分析import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor import shap # 1. 加载数据假设 df 已存在 X df.drop(columns[PRICE]) y df[PRICE] X_train, X_val, y_train, y_val train_test_split(X, y, test_size0.2, random_state42) # 2. 训练初始模型 initial_model RandomForestRegressor(n_estimators100, random_state42) initial_model.fit(X_train, y_train) # 3. 计算 SHAP 值 explainer shap.TreeExplainer(initial_model) shap_values explainer.shap_values(X_train) # 4. 分析找出对预测误差贡献复杂的特征 # 计算每个特征 SHAP 值的绝对均值作为重要性 shap_importance pd.DataFrame({ feature: X_train.columns, importance: np.abs(shap_values).mean(axis0) }).sort_values(importance, ascendingFalse) print(初始特征重要性) print(shap_importance) # 5. 深入分析例如发现‘RM’房间数和‘LSTAT’低收入人口比例的SHAP值散点图呈现非线性关系 # 我们可以手动模拟这个“洞察” shap_insight “特征‘RM’房间数与‘LSTAT’低收入人口比例的SHAP值在散点图上显示出明显的弯曲模式。当‘LSTAT’较低时‘RM’的正向贡献更强当‘LSTAT’很高时‘RM’的贡献减弱甚至反转。这表明两者存在交互效应单纯的线性模型可能无法捕捉。”4.2 调用 LLM 生成特征代码这里我们模拟调用 OpenAI API 的过程。import openai def generate_feature_code(shap_insight, sample_df, feature_list, target): prompt prompt_template.format( task_description房价, feature_list, .join(feature_list), shap_insightshap_insight, sample_data_headsample_df.head().to_string(), target_columntarget ) response openai.ChatCompletion.create( modelgpt-4, # 或 gpt-3.5-turbo messages[ {role: system, content: 你是一个只输出代码的助手。}, {role: user, content: prompt} ], temperature0.1, # 低温度保证输出确定性 max_tokens500 ) generated_code response.choices[0].message.content return generated_code # 准备数据 sample_indices X_train.sample(5, random_state42).index sample_data X_train.loc[sample_indices] feature_list X_train.columns.tolist() # 生成代码 generated_code generate_feature_code(shap_insight, sample_data, feature_list, PRICE) print(LLM 生成的特征函数代码) print(generated_code)假设 LLM 返回了如下代码def create_new_feature(df): # 创建一个交互特征房间数与低收入比例的组合效应 # 当低收入比例低时房间数的价值更高反之则折扣 interaction df[RM] * (1 / (df[LSTAT] 1)) # 避免除零加1平滑 # 进一步考虑房间数的非线性效应例如超过某个阈值后价值增长变缓 room_effect np.where(df[RM] 6, 6 (df[RM] - 6) * 0.5, df[RM]) # 组合成新特征 new_feature interaction * room_effect return new_feature4.3 执行生成代码并评估import warnings warnings.filterwarnings(ignore) # 1. 动态执行生成的代码获取函数对象 exec_globals {} exec(generated_code, {np: np, pd: pd}, exec_globals) create_new_feature_func exec_globals[create_new_feature] # 2. 应用函数创建新特征 X_train[RM_LSTAT_interaction] create_new_feature_func(X_train) X_val[RM_LSTAT_interaction] create_new_feature_func(X_val) # 3. 用新特征重新训练模型 new_model RandomForestRegressor(n_estimators100, random_state42) new_model.fit(X_train, y_train) # 4. 评估性能提升 from sklearn.metrics import mean_squared_error, r2_score initial_pred initial_model.predict(X_val.drop(columns[RM_LSTAT_interaction])) new_pred new_model.predict(X_val) print(f初始模型 RMSE: {mean_squared_error(y_val, initial_pred, squaredFalse):.4f}) print(f初始模型 R2: {r2_score(y_val, initial_pred):.4f}) print(f新特征模型 RMSE: {mean_squared_error(y_val, new_pred, squaredFalse):.4f}) print(f新特征模型 R2: {r2_score(y_val, new_pred):.4f}) # 5. 计算新特征的 SHAP 重要性验证其贡献 new_explainer shap.TreeExplainer(new_model) new_shap_values new_explainer.shap_values(X_val) # 查看新特征‘RM_LSTAT_interaction’的重要性排名4.4 迭代与轨迹形成如果新特征带来了性能提升我们可以将其纳入特征库。然后基于包含了新特征的X_train和新的new_model重新计算 SHAP 值开始下一轮的分析-生成-评估循环。这个过程就形成了一条由模型表现和可解释性信号共同驱动的“隐式特征生成轨迹”。5. 常见问题与排查思路在实现 SIGMA 思想的过程中你可能会遇到以下问题问题现象可能原因解决思路LLM 生成代码无法执行SyntaxError, NameError1. 提示词未明确约束库导入。2. LLM 使用了未提供的变量或函数。1. 在提示词中明确要求函数内部处理所有导入如import numpy as np。2. 在exec环境中预先注入必要的全局变量{np: np, pd: pd}。3. 增加代码语法检查步骤如ast.parse。生成的特征无效模型性能无提升1. SHAP 分析得出的“洞察”不准或太模糊。2. LLM 未能理解数据上下文。3. 新特征与现有特征高度共线性。1. 优化 SHAP 分析使用交互值、聚类等更精细的方法。2. 在提示词中提供更具体的数据统计摘要均值、方差、与目标的相关性。3. 生成后检查新特征与现有特征的相关系数过滤掉冗余特征。流程运行缓慢1. 每次迭代都重新训练模型和计算SHAP开销大。2. 调用云端 LLM API 网络延迟高。1. 考虑使用增量学习或特征重要性缓存策略。2. 对于本地模型确保硬件资源充足对于API考虑批量生成提示或使用异步调用。3. 设定性能提升阈值微小提升则停止迭代。遇到Exit Code 1或进程崩溃1. 本地 LLM 服务如llama.cpp内存不足。2.shap库与模型版本冲突。1. 检查系统内存和显存使用情况尝试使用量化模型或减小上下文长度。2. 确认shap,xgboost/lightgbm,scikit-learn版本兼容性。降级到稳定版本组合。LLM 生成代码包含危险操作提示词约束不足LLM 可能生成调用外部系统、删除文件等代码。1.至关重要在沙箱环境如 Docker 容器中执行生成的代码。2. 在提示词中严格禁止使用os,subprocess,shutil,open用于写文件等模块。3. 使用ast模块遍历生成的代码树检查是否有禁止的调用。6. 最佳实践与工程建议将 SIGMA 从实验思想转化为稳定可用的工程系统需要注意以下几点提示词工程标准化构建一个可复用的提示词模板库针对不同类型的 SHAP 洞察交互效应、非线性、条件逻辑等设计专门的提示词提高生成代码的准确率和相关性。生成代码的安全沙箱绝对不要在生产环境中直接exec未经审查的代码。必须使用安全的执行环境import ast import pandas as pd import numpy as np class CodeSanitizer: FORBIDDEN_MODULES {os, sys, subprocess, shutil, __import__} FORBIDDEN_CALLS {eval, exec, open} staticmethod def is_safe(code_str): try: tree ast.parse(code_str) for node in ast.walk(tree): # 检查是否有危险的导入 if isinstance(node, ast.Import): for alias in node.names: if alias.name in CodeSanitizer.FORBIDDEN_MODULES: return False # 检查是否有危险的函数调用 if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): if node.func.id in CodeSanitizer.FORBIDDEN_CALLS: return False return True except SyntaxError: return False # 使用示例 if CodeSanitizer.is_safe(generated_code): safe_globals {np: np, pd: pd} exec(generated_code, safe_globals) else: print(生成的代码包含潜在危险操作已拒绝执行。)特征评估与筛选流水线不是所有生成的特征都有用。需要建立自动评估流水线单特征预测力计算新特征与目标变量的相关性或互信息。增量贡献在控制其他特征的情况下看加入新特征后模型性能的增量变化如使用特征排列重要性。复杂度惩罚过于复杂的特征如多层嵌套的条件语句可能过拟合应给予惩罚。迭代控制与停止条件避免无限循环。设置停止条件最大迭代次数如10轮。性能提升平台期连续N轮验证集指标无显著提升。生成特征冗余度超过阈值。与现有 AutoFE 库结合SIGMA 可以作为补充策略与 FeatureTools、TSFresh 等基于元数据的 AutoFE 库结合使用。先使用传统方法生成一批基础特征再用 SIGMA 针对这些特征组合的不足进行“精修”。SIGMA 代表了一种将模型可解释性分析与生成式 AI 相结合的前沿特征工程范式。它不再将特征工程视为一个基于固定规则的搜索问题而是一个由数据驱动、模型反馈的创造性推理过程。虽然目前完整的 SIGMA 系统仍多在研究阶段但其核心思想——利用 SHAP 等工具诊断特征缺陷并引导 LLM 进行针对性修复——已经可以为数据科学家提供强大的半自动化辅助。你可以从本文提供的实践框架入手在一个安全可控的环境中尝试构建自己的“元数据无关”特征生成器探索如何让模型告诉你它需要什么样的特征。