如何构建绝不低估的回归模型?应急资源预测技术问询
应急资源预测中避免低估的解决方案
一、自定义不对称损失函数
这是引导模型避免低估的核心手段,通过增大对低估场景的惩罚权重,让模型主动倾向于保守(高估)预测。
1. 加权均方误差(Weighted MSE)
核心逻辑:当预测值低于真实值(低估)时,施加远高于高估的惩罚力度。
公式:
L(y, y_pred) = w * (y - y_pred)² 当 y_pred < y(低估) L(y, y_pred) = (y_pred - y)² 当 y_pred ≥ y(高估)
其中w为惩罚权重,通常取5~20,对零容忍低估的场景可进一步调大——w越大,模型规避低估的意愿越强。
代码示例(Keras 自定义损失)
import tensorflow as tf from tensorflow.keras.losses import Loss class UnderestimationPenaltyLoss(Loss): def __init__(self, penalty_weight=10.0): super().__init__() self.penalty_weight = penalty_weight def call(self, y_true, y_pred): # 标记所有低估样本 underestimation_mask = tf.cast(y_pred < y_true, tf.float32) # 计算带惩罚的损失 squared_error = tf.square(y_true - y_pred) loss = underestimation_mask * self.penalty_weight * squared_error + (1 - underestimation_mask) * squared_error return tf.reduce_mean(loss) # 在ANN中应用该损失函数 model = tf.keras.Sequential([ tf.keras.layers.Dense(64, activation='relu', input_shape=(10,)), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss=UnderestimationPenaltyLoss(penalty_weight=12))
2. 分位数损失(Quantile Loss)
如果需要保证一定比例的预测不低于真实值(比如90%的场景无低估),可采用分位数损失。选择较高分位数(如q=0.9),让模型偏向保守预测。
公式:
L_q(y, y_pred) = max(q*(y - y_pred), (q-1)*(y - y_pred))
当q=0.9时,低估的惩罚是0.9*(y-y_pred),高估的惩罚仅为0.1*(y_pred-y),模型会主动提升预测值来减少高权重的低估损失。
代码示例(XGBoost 分位数回归)
import xgboost as xgb from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split # 生成模拟应急资源数据 X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 配置XGBoost为分位数回归,q=0.9 params = { 'objective': 'reg:quantileerror', 'quantile_alpha': 0.9, 'eval_metric': 'quantileerror', 'max_depth': 3, 'learning_rate': 0.1, 'n_estimators': 100 } model = xgb.XGBRegressor(**params) model.fit(X_train, y_train)
二、偏差校正方法
若已训练常规回归模型,可通过后处理校正预测偏差,减少低估:
1. 残差偏移校正
- 操作步骤:
- 用常规模型(如决策树、ANN)在训练集得到预测值
y_pred_train - 计算所有低估样本的平均残差:
avg_underestimation = mean(y_train - y_pred_train[y_pred_train < y_train]) - 对所有预测值加上该偏移量,强制提升预测值以覆盖低估场景
- 用常规模型(如决策树、ANN)在训练集得到预测值
代码示例
from sklearn.tree import DecisionTreeRegressor # 训练常规决策树模型 dt_model = DecisionTreeRegressor(max_depth=5) dt_model.fit(X_train, y_train) # 计算训练集低估样本的平均残差 y_pred_train = dt_model.predict(X_train) underestimation_mask = y_pred_train < y_train avg_underest = (y_train[underestimation_mask] - y_pred_train[underestimation_mask]).mean() if any(underestimation_mask) else 0.0 # 校正测试集预测值 y_pred_test_corrected = dt_model.predict(X_test) + avg_underest
2. 校准回归
通过拟合一个简单线性模型,将原模型的预测值映射到更保守的结果:
- 以原模型的预测值为特征,真实值为目标,训练线性回归模型
calibrator,并约束其斜率≥1、截距≥0,确保校正后的预测值不低于原预测值。
三、模型训练辅助技巧
- 样本加权:给历史上因资源低估导致严重后果的样本赋予更高权重,让模型优先保障这类场景的预测准确性。
- 早停调整:训练ANN或树模型时,以“低估率”(低估样本占比)作为早停指标,当低估率降到阈值以下时停止训练,避免过度拟合引发的低估。
内容的提问来源于stack exchange,提问作者Malasani Gopi Chand oe18d019
相关产品推荐
相关产品推荐

