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

如何将体育博彩自定义损失函数改造为Keras可微分版本?

问题描述

我正在构建一个预测网球比赛盈利投注场次的模型,为此将投注赔率纳入yTrue变量,示例如下:

yTrue = np.array([[0,1,1.38,3.05],[1,0,1.05,7.85],[1,0,1.04,10.24],[1,0,1.22,3.71],[1,0,1.06,6.69],[1,0,1.48,2.46],[0,1,1.61,2.22]])

其中yTrue[:,0]和yTrue[:,1]代表热门选手/冷门选手的胜负标签(1表示获胜),yTrue[:,2]和yTrue[:,3]分别对应热门、冷门选手的投注赔率。假设单场投注额为1000单位:

  • 数据集里第1场和最后1场冷门选手获胜,其余场次热门选手获胜,全对投注可获最大利润4120.0单位;
  • 若预测结果为:
yPred = np.array([[0,1], [0,1],[1,0],[1,0],[0,1],[1,0],[1,0]])

则仅4次预测正确,总亏损为-210.0单位。

我已写出普通Python版本的损失函数:

import numpy as np
yTrue = np.array([[0,1,1.38,3.05],[1,0,1.05,7.85],[1,0,1.04,10.24],[1,0,1.22,3.71],[1,0,1.06,6.69],[1,0,1.48,2.46],[0,1,1.61,2.22]])
yPred = np.array([[0,1], [0,1],[1,0],[1,0],[0,1],[1,0],[1,0]])

def myLoss(yTrue, yPred):
        maxPotentialProfit = 0
        realProfit = 0
        betUnits = 1000
        for a in range(0,len(yTrue)):
                bet = yTrue[a]
                pred = yPred[a]
                favOdds = bet[2]-1
                dogOdds = bet[3]-1
                if bet[0] == 1:
                        maxPotentialProfit += favOdds*betUnits
                else:
                        maxPotentialProfit += dogOdds*betUnits

                if bet[0] == 1 and pred[0] == 1:
                        realProfit += favOdds*betUnits
                elif bet[1] == 1 and pred[1] == 1:
                        realProfit += dogOdds*betUnits
                else:
                        realProfit -=betUnits

        return maxPotentialProfit - realProfit

现在需要将该损失函数改造为可微分版本,使其适配Keras框架。


可微分损失函数改造方案

要适配Keras,必须用TensorFlow的张量运算替代Python循环和硬条件判断(这类操作不可微分),核心思路是将逻辑转化为张量的逐元素运算:

步骤1:拆解yTrue的各个分量

从yTrue中提取胜负标签和净赔率(赔率-1,即每单位投注的盈利):

  • fav_win = yTrue[:, 0]:热门选手获胜标签
  • dog_win = yTrue[:, 1]:冷门选手获胜标签
  • fav_odds = yTrue[:, 2] - 1.0:热门选手净赔率
  • dog_odds = yTrue[:, 3] - 1.0:冷门选手净赔率

步骤2:计算最大潜在利润

最大潜在利润是每场都投注正确的总盈利,用张量求和直接计算:

max_potential = K.sum(
    fav_win * fav_odds * bet_units + dog_win * dog_odds * bet_units
)

步骤3:计算实际预测利润

原逻辑中,正确预测赚对应赔率的利润,错误则亏投注额。将该逻辑转化为张量运算:

  • 预测热门的盈利/亏损:yPred[:,0] * (fav_win*fav_odds*bet_units - (1-fav_win)*bet_units)
  • 预测冷门的盈利/亏损:yPred[:,1] * (dog_win*dog_odds*bet_units - (1-dog_win)*bet_units)
  • 总实际利润为两者之和(每场只会预测其中一个选项)

步骤4:完整的Keras损失函数

结合以上步骤,最终可微分损失函数如下:

import tensorflow as tf
from tensorflow.keras import backend as K

def keras_bet_loss(yTrue, yPred):
    bet_units = 1000.0  # 转为浮点数避免整数运算问题
    
    # 拆解yTrue分量
    fav_win = yTrue[:, 0]
    dog_win = yTrue[:, 1]
    fav_odds = yTrue[:, 2] - 1.0
    dog_odds = yTrue[:, 3] - 1.0
    
    # 计算最大潜在利润
    max_potential = K.sum(
        fav_win * fav_odds * bet_units + dog_win * dog_odds * bet_units
    )
    
    # 计算实际利润
    fav_profit = yPred[:, 0] * (fav_win * fav_odds * bet_units - (1 - fav_win) * bet_units)
    dog_profit = yPred[:, 1] * (dog_win * dog_odds * bet_units - (1 - dog_win) * bet_units)
    real_profit = K.sum(fav_profit + dog_profit)
    
    # 返回损失:最大潜在利润与实际利润的差值,模型需最小化该值
    return max_potential - real_profit

关键注意事项

  • 所有运算必须使用TensorFlow/Keras的张量函数(如K.sum),不能用Python原生循环或NumPy函数,否则无法自动求导。
  • 确保变量为浮点类型,避免整数运算导致的梯度消失。
  • 若模型输出是概率(如Softmax激活),yPred为0-1之间的浮点值,损失函数仍可微分,模型会自动学习让概率倾向于高利润选项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:08:16