超参数调优
hscredit.core.models.tuning 提供基于 Optuna 的超参数调优组件
(pip install hscredit[tune])。可从顶层
hscredit 懒加载导入 ModelTuner / AutoTuner / TuningObjective。
- class hscredit.core.models.tuning.tuning.ModelTuner(model_class, search_space=None, fixed_params=None, metric='ks', direction='maximize', metric_names=None, objective=None, objective_kwargs=None, eval_ratios=None, trial_points=None, sampler='tpe', sampler_kwargs=None, storage=None, study_name=None, load_if_exists=False, target='target', cv=5, n_jobs=-1, random_state=None, verbose=False, early_stopping_rounds=20, points_to_evaluate=None)[源代码]
基类:
object模型超参数调优器 - 支持单/多目标优化.
基于Optuna实现贝叶斯优化超参数搜索。 支持单目标优化和多目标优化(帕累托最优)。
参数
- 参数:
model_class (Type) -- 模型类 (如XGBoost)
search_space (Any | None) -- 参数搜索空间,默认None则使用预定义空间
fixed_params (Dict[str, Any] | None) -- 固定参数,不参与搜索
metric (str | Callable | List[str | Callable]) -- 优化指标(决定评估计算逻辑),可选: - 字符串: 'auc', 'ks', 'ks_diff', 'accuracy', 'precision', 'recall', 'f1', 'logloss' - 列表: 多个指标,用于多目标优化,如 ['ks', 'ks_diff'] - 函数: 自定义评估函数,接收(y_true, y_pred)返回float - 列表的函数: 多个自定义函数
direction (str | List[str]) -- 优化方向,'maximize'或'minimize',或列表(多目标时)
metric_names (List[str] | None) -- 指标显示名称列表(仅用于日志/报告/可视化的展示标签, 不参与任何计算逻辑),默认 None 时从 metric 自动推断 (内置字符串取其大写形式,自定义函数取其
__name__)。 与 metric 不重复:metric 决定"算什么",metric_names 只决定"叫什么"cv (int) -- 交叉验证折数,默认5
n_jobs (int) -- 当前 trial 中模型可使用的并行任务数,默认-1; trial 本身顺序执行,确保主动中断及时生效并让自适应采样器利用全部历史结果
random_state (int | None) -- 随机种子,默认None
verbose (bool) -- 是否逐 Trial 输出得分、参数、当前最佳结果及最终摘要,默认False
early_stopping_rounds (int) -- 早停轮数,默认20
min_resource -- 多目标优化时的最小资源,默认'auto'
objective (str | Callable | None)
objective_kwargs (Dict[str, Any] | None)
eval_ratios (List[float])
trial_points (Dict[str, Any] | List[Dict[str, Any]] | None)
sampler (str | Any | None)
sampler_kwargs (Dict[str, Any] | None)
storage (str | None)
study_name (str | None)
load_if_exists (bool)
target (str)
points_to_evaluate (Dict[str, Any] | List[Dict[str, Any]] | None)
搜索空间定义
搜索空间可使用参数字典,或使用每个维度都设置
name的 skopt 维度列表。 内部统一转换并由 Optuna Study 执行:整数参数: {'type': 'int', 'low': 1, 'high': 10, 'step': 1}
浮点参数: {'type': 'float', 'low': 0.01, 'high': 1.0, 'log': True}
类别参数: {'type': 'categorical', 'choices': ['a', 'b', 'c']}
同时兼容多种超参数框架的入参格式(无需安装对应库),传入后自动归一化:
bayesian-optimization 风格: {'max_depth': (2, 4, int), 'booster': ('gbtree', 'dart')}
scikit-optimize 风格: [Real(1e-3, 0.1, prior='log-uniform', name='learning_rate')]
sklearn 风格: {'C': [0.1, 1, 10]} 或 scipy 分布 {'C': scipy.stats.loguniform(1e-3, 1e1)}
hyperopt 风格: {'learning_rate': loguniform('learning_rate', log(1e-3), log(0.1)), 'penalty': choice('penalty', ['l1', 'l2'])}
optuna 分布对象: {'max_depth': optuna.distributions.IntDistribution(2, 4)}
内部建模经验
XGBoost参数经验: - max_depth: 风控场景通常2-4,防止过拟合 - min_child_weight: 8-256(step 4),越大越保守 - subsample: 0.35-0.85,colsample_bytree: 0.4-0.9 - gamma: 0.0-32.0,reg_lambda: 32.0-128.0(强 L2 正则) - scale_pos_weight: 16.0-32.0(适配低坏率不平衡) - learning_rate: 0.0001-0.01,较小学习率更稳定 - n_estimators: 32-256(step 16)
LightGBM参数经验(与 XGBoost 对齐): - num_leaves: 与max_depth相关,受 2**max_depth 上界约束 - max_depth: 风控场景通常2-4,防止过拟合 - learning_rate: 0.0001-0.01,较小学习率更稳定 - min_child_samples: 8-256(step 4)
LogisticRegression参数经验: - C: 0.01-32 离散网格,越小正则越强 - penalty: 'l2',class_weight: None/'balanced'/自定义权重字典 - solver: liblinear/sag/lbfgs/newton-cg,max_iter: 16-256
评估指标: - 主要用KS评估模型区分能力 - 同时考虑训练/测试KS差异防止过拟合
参考样例
>>> from hscredit.core.models import XGBoost, ModelTuner >>> # 单目标:最大化 KS >>> tuner = ModelTuner(XGBoost, metric='ks', direction='maximize', cv=5) >>> tuner.fit(X_train, y_train, n_trials=50) # 返回最佳参数 best_params_ >>> best_model = tuner.get_best_model() # 已使用完整训练集重训 >>> >>> # 多目标:同时优化 KS 与训练/测试 KS 差异(帕累托最优) >>> tuner = ModelTuner( ... XGBoost, ... metric=['ks', 'ks_diff'], ... direction=['maximize', 'minimize'], ... sampler='nsgaii', ... ) >>> tuner.fit(X_train, y_train, n_trials=100) >>> >>> # 自定义搜索空间 >>> space = {'max_depth': {'type': 'int', 'low': 2, 'high': 4}, ... 'learning_rate': {'type': 'float', 'low': 1e-3, 'high': 0.1, 'log': True}} >>> tuner = ModelTuner(XGBoost, search_space=space, metric='auc')
引用
基于 Optuna 超参数优化框架(默认 TPE 采样器),见 Akiba, T. et al. (2019). Optuna: A Next-generation Hyperparameter Optimization Framework. KDD;TPE 见 Bergstra, J. et al. (2011), Algorithms for Hyper-Parameter Optimization, NeurIPS。 文档:https://optuna.readthedocs.io/
- fit(X, y=None, n_trials=100, timeout=None, show_progress_bar=True, sample_weight=None)[源代码]
执行超参数调优.
支持两种调用风格:
sklearn风格:
tuner.fit(X_train, y_train, n_trials=100)
scorecardpipeline风格 (在__init__中指定target):
tuner = ModelTuner(..., target='label') tuner.fit(df) # df包含'label'列
- 参数:
X (ndarray | DataFrame) -- 特征矩阵,或包含目标列的DataFrame(scorecardpipeline风格)
y (ndarray | Series | None) -- 目标变量,可选。如果为None,则从X中提取target列
n_trials (int) -- 搜索次数,默认100
timeout (int | None) -- 超时时间(秒),默认None
show_progress_bar (bool) -- 是否显示进度条,默认True
sample_weight (ndarray | None) -- 样本权重,可选
- 返回:
最佳参数字典
- 返回类型:
Dict[str, Any]
- evaluate_trials(X, y=None, trial_points=None, sample_weight=None)[源代码]
评估指定超参数点的模型效果.
无需运行完整调优,直接评估给定超参数配置的性能。
支持两种调用风格:
sklearn风格:
results = tuner.evaluate_trials(X_train, y_train, trial_points)
scorecardpipeline风格 (在__init__中指定target):
tuner = ModelTuner(..., target='label') results = tuner.evaluate_trials(df, trial_points=trial_points)
- 参数:
X (ndarray | DataFrame) -- 特征矩阵,或包含目标列的DataFrame(scorecardpipeline风格)
y (ndarray | Series | None) -- 目标变量,可选。如果为None,则从X中提取target列
trial_points (List[Dict[str, Any]] | None) -- 超参数点列表,每个点是一个参数字典
sample_weight (ndarray | None) -- 样本权重,可选
- 返回:
包含评估结果的DataFrame
- 返回类型:
DataFrame
- evaluate_study_trials(trial_indices=None, X=None, y=None, sample_weight=None)[源代码]
评估已完成 study 中指定 trial 的模型效果.
从
self.``study_.trials[i]`` 取出对应超参数重新评估,便于复核某次 采样的稳定性、或在新数据集上对比若干历史 trial 的效果。与
evaluate_trials()的区别:本方法的超参数来自已学习完成的 study(按 trial 索引取),而非外部传入的参数点;结果额外包含每个 trial 的索引、状态及 study 记录的原始得分(study记录值列),便于与重新 评估的得分对照。- 参数:
trial_indices (int | Sequence[int] | None) -- 要评估的 trial 索引,可选: - None: 评估全部已完成(COMPLETE)的 trial - int: 评估单个 trial,如
0或tuner.``study_.best_trial.number`` - 序列: 评估多个 trial,如[0, 5, 10]X (ndarray | DataFrame | None) -- 特征矩阵,或包含目标列的DataFrame;默认复用 fit 时的训练数据
y (ndarray | Series | None) -- 目标变量,可选;默认复用 fit 时的标签
sample_weight (ndarray | None) -- 样本权重,可选;默认复用 fit 时的样本权重
- 返回:
包含评估结果的DataFrame,含
trial索引/trial状态/超参数/ 重新评估指标/study记录值列- 返回类型:
DataFrame
示例
>>> tuner.fit(X_train, y_train, n_trials=100) >>> # 评估最优 trial 与前两个 trial >>> tuner.evaluate_study_trials([tuner.study_.best_trial.number, 0, 1]) >>> # 在新数据集上复核全部 trial >>> tuner.evaluate_study_trials(X=X_oot, y=y_oot)
- enqueue_trial(params, user_attrs=None, skip_if_exists=False)[源代码]
按 Optuna
Study.enqueue_trial风格追加一个手工搜索点。params使用模型最终参数名和值。若某一声明需要内部潜变量采样,本方法 会先完成逆变换,再把内部参数传给 Study;公开记录仍保留最终值。- 参数:
params (Dict[str, Any])
user_attrs (Dict[str, Any] | None)
skip_if_exists (bool)
- 返回类型:
- enqueue_trials(trial_points=None, *, param_grid=None, x0=None, user_attrs=None, skip_if_exists=False)[源代码]
按 Optuna、GridSearch 或 skopt 格式追加一个或多个搜索点。
若 study 已创建(已调用过 fit),则立即通过
study.enqueue_trial入队, 在后续fit的采样中优先评估;否则缓存到self.trial_points, 在下次fit创建 study 后入队。- 参数:
trial_points (Dict[str, Any] | List[Dict[str, Any]] | None) -- Optuna/hscredit 格式,
dict或list[dict]param_grid (Dict[str, Sequence[Any]] | List[Dict[str, Sequence[Any]]] | None) -- GridSearch 格式,由
ParameterGrid展开x0 (Sequence[Any] | None) -- skopt 格式,单个值序列或多个值序列,顺序与搜索空间一致
user_attrs (Dict[str, Any] | None)
skip_if_exists (bool)
- 返回:
self,便于链式调用
- 返回类型:
- probe(params, lazy=True)[源代码]
按 bayesian-optimization
probe风格追加一个搜索点。lazy为兼容原方法保留;Optuna 后端无立即执行单点的等价操作,因此True与False都会进入同一个 Study 队列,并在下一次 optimize 时执行。- 参数:
params (Dict[str, Any] | Sequence[Any])
lazy (bool)
- 返回类型:
- get_param_importance(target=None)[源代码]
获取参数重要性.
- 参数:
target (int | None) -- 多目标时指定要分析的指标索引,默认第一个
- 返回:
参数重要性Series
- 返回类型:
Series | None
- plot_optimization_history(target=None, **kwargs)[源代码]
绘制优化历史.
- 参数:
target (int | None) -- 多目标时指定要绘制的指标索引,默认第一个
kwargs -- 绘图参数
- 返回:
plotly图形对象
- plot_param_importances(target=None, **kwargs)[源代码]
绘制参数重要性.
- 参数:
target (int | None) -- 多目标时指定要分析的指标索引,默认第一个
kwargs -- 绘图参数
- 返回:
plotly图形对象
- plot_slice(target=None, **kwargs)[源代码]
绘制参数切片图.
- 参数:
target (int | None) -- 多目标时指定要绘制的指标索引,默认第一个
kwargs -- 绘图参数
- 返回:
plotly图形对象
- plot_contour(params=None, target=None, **kwargs)[源代码]
绘制参数等高线图.
- 参数:
params (List[str] | None) -- 要绘制的参数列表,默认前两个
target (int | None) -- 多目标时指定要绘制的指标索引,默认第一个
kwargs -- 绘图参数
- 返回:
plotly图形对象
- class hscredit.core.models.tuning.tuning.AutoTuner[源代码]
基类:
object自动调优器 - 基于内部建模经验.
为常见模型提供预定义的搜索空间,并根据数据特征自动调整。
参考样例
>>> from hscredit.core.models import AutoTuner >>> >>> # 自动根据数据特征选择搜索空间 >>> tuner = AutoTuner.create('xgboost', metric='ks') >>> best_params = tuner.fit(X_train, y_train, n_trials=50) >>> >>> # 使用多目标优化(KS + 稳定性) >>> tuner = AutoTuner.create('lightgbm', metric=['ks', 'ks_diff']) >>> best_params = tuner.fit(X_train, y_train, n_trials=100) >>> >>> # 使用自定义指标 >>> def my_metric(y_true, y_pred): ... return custom_score(y_true, y_pred) >>> >>> tuner = AutoTuner.create('xgboost', metric=my_metric, direction='maximize') >>> best_params = tuner.fit(X_train, y_train, n_trials=100)
- classmethod create(model_type, metric='ks', direction='maximize', metric_names=None, target='target', cv=5, random_state=None, verbose=False, early_stopping_rounds=20, **kwargs)[源代码]
创建自动调优器.
- 参数:
model_type (str) -- 模型类型,可选: - 'xgboost' / 'xgb' - 'lightgbm' / 'lgb' - 'catboost' / 'cat' - 'ngboost' / 'ngb' - 'randomforest' / 'rf' - 'gradientboosting' / 'gbdt' - 'logisticregression' / 'lr' - 'svm' / 'svc' - 'decisiontree' / 'dt'
metric (str | Callable | List[str | Callable]) -- 优化指标,可以是字符串、函数或列表
direction (str | List[str]) -- 优化方向,单目标时str,多目标时list
metric_names (List[str] | None) -- 指标名称列表(多目标时用于显示)
target (str) -- 目标列名,用于scorecardpipeline风格的fit,默认'target'
cv (int) -- 交叉验证折数,默认5
random_state (int | None) -- 随机种子
verbose (bool) -- 是否输出详细信息
early_stopping_rounds (int) -- 早停轮数,默认20
kwargs -- 其他参数
- 返回:
ModelTuner实例
- 返回类型:
- class hscredit.core.models.tuning.tuning.TuningObjective[源代码]
基类:
object内置调参目标函数集合.
所有静态方法签名均为
(y_true, y_prob, **kwargs) -> float, 值越大越好(均已设计为 maximize 方向)。可通过字符串名称传给
ModelTuner(objective=...): -'ks': 标准 KS(默认) -'auc': ROC-AUC -'lift_head': 头部 LIFT(高概率前 ratio 比例) -'lift_tail': 尾部 LIFT(低概率前 ratio 比例的纯净度) -'lift_head_monotonic': KS × (1 - 违反单调比例 × penalty) -'ks_with_lift_constraint': 满足头部 LIFT 约束下的 KS -'head_ks': 仅头部 ratio 比例样本的 KS -'approval_bad_rate': 固定通过率下优化低风险通过客群坏率 -'expected_profit': 固定通过率下优化通过客群期望利润示例
>>> from hscredit.core.models import ModelTuner, XGBoost >>> tuner = ModelTuner( ... model_class=XGBoost, ... objective='lift_head', ... objective_kwargs={'ratio': 0.05}, ... ) >>> tuner.fit(X_train, y_train, n_trials=50)
- BUILTIN_OBJECTIVES = ['ks', 'auc', 'lift_head', 'lift_tail', 'lift_head_monotonic', 'ks_with_lift_constraint', 'head_ks', 'ks_lift_combined', 'tail_purity_ks', 'approval_bad_rate', 'expected_profit']
- static ks(y_true, y_prob, **kwargs)[源代码]
标准 KS 目标.
- 参数:
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static auc(y_true, y_prob, **kwargs)[源代码]
ROC-AUC 目标.
- 参数:
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static lift_head(y_true, y_prob, ratio=0.1, **kwargs)[源代码]
头部 LIFT 目标:优化预测概率最高 ratio 比例样本的 LIFT 值.
- 参数:
ratio (float) -- 覆盖率,默认 0.10(即 Top 10%)
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static lift_tail(y_true, y_prob, ratio=0.1, **kwargs)[源代码]
尾部 LIFT 目标:优化预测概率最低 ratio 比例样本(低风险客群)的纯净度.
纯净度定义为:(1 - 尾部坏率) / (1 - 整体坏率),值越大表示尾部越纯净。
- 参数:
ratio (float) -- 尾部覆盖率,默认 0.10
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static lift_head_monotonic(y_true, y_prob, n_bins=10, penalty=0.5, **kwargs)[源代码]
头部单调 LIFT 目标:KS × (1 - 违反单调性比例 × penalty).
单调性违反比例越低,目标越高;完全单调时等同于 KS 目标。
- 参数:
n_bins (int) -- 分箱数,默认 10
penalty (float) -- 单调性惩罚强度,默认 0.5
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static ks_with_lift_constraint(y_true, y_prob, min_lift_ratio=0.05, min_lift_value=2.0, **kwargs)[源代码]
KS + LIFT 约束:满足头部 LIFT >= min_lift_value 前提下最大化 KS.
若不满足约束,返回 0(惩罚)。
- 参数:
min_lift_ratio (float) -- 头部覆盖率,默认 0.05(Top 5%)
min_lift_value (float) -- 最低 LIFT 要求,默认 2.0
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static head_ks(y_true, y_prob, ratio=0.3, **kwargs)[源代码]
头部 KS:仅计算预测概率最高 ratio 比例样本的 KS(头部区分能力).
- 参数:
ratio (float) -- 头部覆盖率,默认 0.30
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static ks_lift_combined(y_true, y_prob, ks_weight=0.5, lift_ratio=0.05, **kwargs)[源代码]
KS + LIFT 联合目标:加权组合 KS 和头部 LIFT.
score = ks_weight × KS + (1 - ks_weight) × normalized_LIFT
- 参数:
ks_weight (float) -- KS 权重,默认 0.5
lift_ratio (float) -- LIFT 覆盖率,默认 0.05
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static tail_purity_ks(y_true, y_prob, tail_ratio=0.3, **kwargs)[源代码]
尾部纯净度 + 整体 KS 联合目标.
适用于「放量优先」场景:确保通过(低风险)部分的坏率尽量低,同时保持整体区分度. score = 0.5 × KS + 0.5 × tail_purity
- 参数:
tail_ratio (float) -- 尾部覆盖率,默认 0.30(即通过的低风险比例)
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static approval_bad_rate(y_true, y_prob, approval_rate=0.3, bad_rate_weight=1.0, **kwargs)[源代码]
通过率坏率目标:固定通过率下最大化通过收益、惩罚通过坏率.
默认把预测概率最低的
approval_rate样本视为通过客群。 score = approval_rate × (1 - 通过坏率 × bad_rate_weight)- 参数:
approval_rate (float) -- 通过率,默认 0.30
bad_rate_weight (float) -- 坏率惩罚权重,默认 1.0
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- static expected_profit(y_true, y_prob, approval_rate=0.3, good_profit=1.0, bad_loss=5.0, **kwargs)[源代码]
期望利润目标:固定通过率下最大化通过客群单位样本收益.
默认预测概率最低的样本为通过客群,好客户收益为
good_profit, 坏客户损失为bad_loss,拒绝样本收益记为 0。- 参数:
approval_rate (float) -- 通过率,默认 0.30
good_profit (float) -- 通过好客户收益,默认 1.0
bad_loss (float) -- 通过坏客户损失,默认 5.0
y_true (ndarray)
y_prob (ndarray)
- 返回类型:
float
- class hscredit.core.models.tuning.tuning.Metric(metric, name=None, direction=None)[源代码]
基类:
object评估指标包装类.
用于统一管理内置指标和自定义指标。
- 参数:
metric (str | Callable) -- 指标名称(str)或自定义函数(Callable)
name (str | None) -- 指标名称(用于显示)
direction (str | None) -- 优化方向,'maximize'或'minimize'
- BUILTIN_METRICS = {'accuracy': {'direction': 'maximize', 'scorer': 'accuracy'}, 'approval_bad_rate': {'direction': 'maximize', 'scorer': None}, 'auc': {'direction': 'maximize', 'scorer': 'roc_auc'}, 'expected_profit': {'direction': 'maximize', 'scorer': None}, 'f1': {'direction': 'maximize', 'scorer': 'f1'}, 'head_ks': {'direction': 'maximize', 'scorer': None}, 'ks': {'direction': 'maximize', 'scorer': None}, 'ks_diff': {'direction': 'minimize', 'scorer': None}, 'ks_lift_combined': {'direction': 'maximize', 'scorer': None}, 'ks_with_lift_constraint': {'direction': 'maximize', 'scorer': None}, 'lift_head': {'direction': 'maximize', 'scorer': None}, 'lift_head_monotonic': {'direction': 'maximize', 'scorer': None}, 'lift_tail': {'direction': 'maximize', 'scorer': None}, 'logloss': {'direction': 'maximize', 'scorer': 'neg_log_loss'}, 'precision': {'direction': 'maximize', 'scorer': 'precision'}, 'recall': {'direction': 'maximize', 'scorer': 'recall'}, 'tail_purity_ks': {'direction': 'maximize', 'scorer': None}}