You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Keras损失函数中集成tf.where与odds的实现难题

自定义Keras投注盈亏损失函数实现

核心逻辑梳理

我们需要基于实际赛果、模型预测结果、主队获胜赔率计算投注盈亏,并将其转化为可用于训练的损失函数(模型最小化损失等价于最大化盈利)。常见的投注盈亏逻辑如下:

  • 若预测主队获胜且实际主队获胜:盈利 = (赔率 - 1) × 投注额
  • 若预测主队获胜但实际客队获胜:亏损 = 1 × 投注额
  • 未投注时盈亏为0

解决KerasTensor输入报错问题

之前使用tf.where触发ValueError,本质是损失函数中混合了非张量操作,或未正确处理Keras的张量类型。解决方法是全程使用TensorFlow张量操作,避免Python原生条件判断。

集成赔率的两种实现方式

方式1:将赔率作为模型额外输入

适合需要单独处理特征与赔率的场景:

import tensorflow as tf

# 定义带赔率参数的损失函数
def betting_loss(odds_tensor):
    def loss(y_true, y_pred):
        # 1. 生成投注掩码:预测主队获胜概率≥0.5时投注(可根据需求调整阈值)
        bet_mask = tf.cast(y_pred >= 0.5, tf.float32)
        # 2. 计算单样本盈亏:主胜时盈利(odds-1)*投注,客胜时亏损1*投注
        profit = tf.where(
            y_true == 1,
            (odds_tensor - 1) * bet_mask,
            -1 * bet_mask
        )
        # 3. 损失取总盈利的负值(最小化损失=最大化盈利)
        return -tf.reduce_mean(profit)
    return loss

# 构建包含赔率输入的模型
feature_input = tf.keras.Input(shape=(10,))  # 假设特征维度为10
odds_input = tf.keras.Input(shape=(1,))
x = tf.keras.layers.Dense(64, activation='relu')(feature_input)
output = tf.keras.layers.Dense(1, activation='sigmoid')(x)  # 输出主队获胜概率

model = tf.keras.Model(inputs=[feature_input, odds_input], outputs=output)
model.compile(optimizer='adam', loss=betting_loss(odds_input))

# 训练示例
import numpy as np
X_train = np.random.rand(1000, 10)
odds_train = np.random.uniform(1.5, 5, (1000, 1))
y_train = np.random.randint(0, 2, (1000, 1))

model.fit([X_train, odds_train], y_train, epochs=10, batch_size=32)

方式2:将赔率并入真实标签

适合简化模型输入的场景,把真实赛果和赔率打包成二维标签:

import tensorflow as tf

def betting_loss(y_true, y_pred):
    # 拆分真实标签:第一列是实际赛果,第二列是主队赔率
    actual_result = y_true[:, 0]
    odds = y_true[:, 1]
    # 用预测概率作为投注权重(更平滑,适合梯度下降)
    profit = y_pred * tf.where(actual_result == 1, (odds - 1), -1)
    # 损失取平均盈利的负值
    return -tf.reduce_mean(profit)

# 构建普通单输入模型
inputs = tf.keras.Input(shape=(10,))
x = tf.keras.layers.Dense(64, activation='relu')(inputs)
output = tf.keras.layers.Dense(1, activation='sigmoid')(inputs)

model = tf.keras.Model(inputs=inputs, outputs=output)
model.compile(optimizer='adam', loss=betting_loss)

# 训练示例
X_train = np.random.rand(1000, 10)
# 真实标签:[实际赛果, 主队赔率]
y_train = np.hstack([np.random.randint(0,2,(1000,1)), np.random.uniform(1.5,5,(1000,1))])

model.fit(X_train, y_train, epochs=10, batch_size=32)

关键注意点

  • 若追求更平滑的梯度,建议用y_pred(预测概率)直接作为投注权重,而非固定阈值的硬掩码
  • 所有计算必须使用TensorFlow张量操作(如tf.where、tf.cast),避免Python的if/else或循环
  • 损失函数返回的是平均盈利的负值,确保模型训练时朝着最大化盈利的方向优化

内容的提问来源于stack exchange,提问作者KaiHoogenhoud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:40:21