如何提取LightGBM模型的预测规则(系数)
保险行业LightGBM模型可解释性解决方案
我从事保险行业,受严格监管要求,需要提取LightGBM模型的可解释决策规则(格式如:若特征1、特征2、特征3同时满足,则预测值y_pred=104.62),同时明确模型的决策逻辑。
关键说明
LightGBM是基于树的集成模型,没有线性回归那样的全局系数,每个叶子节点对应一条决策路径,最终预测值是基准值加上所有树叶子节点的贡献之和。我们可以通过解析树结构提取符合监管要求的自然语言规则。
一、完整实现代码(含规则提取)
以下是带中文注释的训练代码,新增了规则提取逻辑,直接生成可读的决策规则:
import time import pandas as pd import lightgbm as lgb from sklearn.metrics import d2_tweedie_score # 定义Tweedie分布参数与特征单调性约束 tweedie_p = 1.50568 # 单调性约束:前4个特征正相关,第5-6个负相关,其余无约束 mono_constraints = (1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) start_time = time.time() print("开始LightGBM模型训练") # 模型核心参数配置 params = { 'task': 'train', 'boosting': 'gbdt', 'num_leaves': 174, 'max_depth': 11, 'n_jobs': 6, 'n_estimators': 1000, 'subsample_for_bin': 200000, 'learning_rate': 0.06308264944407528, 'random_state': seed2, # 需提前定义随机种子变量seed2 'min_gain_to_split': 9.540907629434999, 'min_data_in_leaf': 1800, 'bagging_fraction': 1.00, 'bagging_seed': 49, 'bagging_freq': 1, 'feature_fraction': 1.00, 'feature_fraction_seed': 1958, 'extra_trees': True, 'extra_seed': 1975, 'lambda_l1': 70, 'lambda_l2': 0, 'importance_type': 'gain', # 'init_model': model_saved, # 可选:加载预训练模型 'monotone_constraints': mono_constraints, 'monotone_constraints_method': 'advanced' } # 初始化Tweedie回归模型 mdl = lgb.LGBMRegressor( **params, objective='tweedie', tweedie_variance_power=tweedie_p ) # 训练模型,加入早停机制防止过拟合 mdl.fit( X_train, y_train, sample_weight=w_train, eval_set=[(X_valid, y_valid), (X_train, y_train)], eval_sample_weight=[w_valid, w_train], eval_metric=['auc', 'tweedie'], callbacks=[lgb.early_stopping(40)] ) # 验证集预测与模型评估 y_pred = mdl.predict(X_valid, num_iteration=mdl.best_iteration_) d2_score = d2_tweedie_score(y_valid, y_pred, sample_weight=w_valid, power=tweedie_p) run_time = round(time.time() - start_time, 3) print(f"训练耗时 = {run_time}") # 示例输出:训练耗时 = 7.203 print(f"最佳迭代次数 = {mdl.best_iteration_}") # 示例输出:最佳迭代次数 = 56 print(f"最佳评估分数 = {mdl.best_score_}") print(f"\tD2 Tweedie分数: {d2_score:.5f}") # ------------------------------ # 核心功能:提取可解释决策规则 # ------------------------------ def extract_interpretable_rules(model, feature_names): """ 从LightGBM模型中提取自然语言格式的决策规则 """ rules = [] # 导出训练好的树结构 tree_info = model.booster_.dump_model(num_iteration=model.best_iteration_) # 获取模型基准预测值 base_score = float(model.booster_.params.get('base_score', 0.0)) # 遍历每一棵决策树 for tree_idx, tree in enumerate(tree_info): def traverse_tree(node, current_path): # 到达叶子节点,生成规则 if 'leaf' in node: # 计算该叶子节点的实际贡献(学习率加权) leaf_contribution = node['leaf'] * model.learning_rate # 拼接路径条件 condition_str = "且".join(current_path) if condition_str: rule = f"【树{tree_idx+1}】若{condition_str},则贡献值为{leaf_contribution:.4f}" else: rule = f"【树{tree_idx+1}】默认贡献值为{leaf_contribution:.4f}" rules.append(rule) return # 处理分裂节点,递归遍历左右子树 split_feature = feature_names[node['split_feature']] split_threshold = node['threshold'] # 左子树:满足特征≤阈值的条件 left_path = current_path + [f"{split_feature} ≤ {split_threshold:.4f}"] traverse_tree(node['left_child'], left_path) # 右子树:满足特征>阈值的条件 right_path = current_path + [f"{split_feature} > {split_threshold:.4f}"] traverse_tree(node['right_child'], right_path) # 开始遍历当前树的根节点 traverse_tree(tree['tree_structure'], []) # 添加全局规则说明 rules.insert(0, f"模型最终预测值 = 基准值{base_score:.4f} + 所有树的贡献值之和") return rules # 提取规则(需确保X_train有列名) feature_names = X_train.columns.tolist() model_rules = extract_interpretable_rules(mdl, feature_names) # 打印前10条规则示例 print("\n===== 模型决策规则示例 =====") for idx, rule in enumerate(model_rules[:10]): print(f"{idx+1}. {rule}")
二、规则使用说明
- 规则含义:每条规则对应单棵树的一个决策路径,最终预测值是基准值加上所有匹配规则的贡献之和
- 监管适配:可以过滤出现频率较低的规则,保留覆盖多数样本的核心规则,或者合并相似规则简化输出
- 系数替代方案:如果需要类似线性系数的全局特征重要性,可以使用
mdl.feature_importances_获取基于增益的特征重要性值
内容的提问来源于stack exchange,提问作者Philip Wang
相关产品推荐
相关产品推荐

