
本次大赛需要参赛选手建立用户平等的促销策略模型,提交的策略模型将在仿真消费环境中进行促销投放测试,虚拟消费者会对促销策略进行反馈,以最终的虚拟促销投入产出结果来评估策略得分。在比赛的最后阶段,我们会依据测试环境的测试结果,形成最终排名,并取Top5队伍作为获奖队伍。欢迎大家在讨论区进行讨论。
【一】赛题和数据
1.1【比赛数据说明】
当前,各商家正面临着从以往针对消费者个性化促销到平等化促销的过渡转变。此前,如图1所示,商家针对不同消费者投放了不同的促销折扣,由此收集到个性化促销及消费者反馈的数据。而如何基于此类历史数据,来制定出未来对于消费者进行平等式的促销决策,即如图2所示,为每一个消费者发放相同的促销激励,是各商家面临的严峻挑战。因此,本比赛的目的旨在通过开放部分个性化促销形式的交互历史数据,由各参赛队进行策略学习,从而制定出面向消费者的平等促销策略。

图1(上图)对于每个用户发放不同促销动作及各消费者反馈数据流程图。离线数据来自此过程产生的历史2个月时期的“促销动作-用户动作”的交互数据。

图2(上图) 对于每个用户发放相同促销动作及各消费者反馈数据流程图。
比赛所开放的数据是历史2个月的投放数据,其中包含对于每个用户发放的个性化促销决策以及消费者的相应反馈,以csv格式文件存储。初赛阶段,所提供的数据包含1,000位虚拟消费用户的“促销-消费”交互数据。复赛阶段,所提供的数据包含10,000位虚拟消费用户的“促销-消费”交互数据。
注:该数据权利归主办方所有,仅用于本次比赛,参赛者不得对该数据进行传播。
1.2【离线数据】
csv文件列名说明如下:
1、【index】:用户ID。
2、【day_deliver_coupon_num】:营销平台当天发放的优惠券张数。注意,每张优惠券的有效期为当日。
3、【coupon_discount】:营销平台当天发放的优惠券折扣。
4、【day_order_num】:用户当天订单次数。优惠券默认会随着订单使用,直到优惠券用完。
5、【day_average_order_fee】:用户当天所有订单折扣前的平均金额。
6、【step】:天数,范围0-59。
7、【date】:日期,范围为2021/03/192021/05/17。
例如,对于用户ID 0,部分数据内容如下图所示:

以第一行为例,该行数据说明 2021年3月19日为用户发放了0张优惠券(此时折扣率无效),该日用户消费了0单。次日(第二行),发放给该用户2张65折优惠券,该日用户消费了1单,折扣前订单金额为33.5元。
1.3【策略测试过程】
我们期待参赛者根据离线数据训练用户平等的促销策略,并在如图2所示的决策流程中进行投放测试。
参赛者需根据平台上所下载的 “个性化促销”的离线数据,自行定义促销策略的用户状态输入,进行策略训练。在策略提交测试时,以天为间隔,由您自行设计的用户状态经过所提交的促销策略,输出针对所有用户的促销动作,即一天中给所有用户统一的优惠券折扣和张数。但在不同日期可投放不同的促销动作。在仿真用户环境中,会对此促销动作返回当天每个用户相应的用户动作。
参赛者的策略将在用户环境中进行从2021年5月18日开始的交互测试。
【1】初赛阶段将进行未来14天(即5月18日到5月31日)的1,000名虚拟用户的“促销-消费”交互测试,测试结果将反馈给参赛者,测试得分也会显示在排行榜上。
【2】复赛阶段提交的策略模型,将反馈未来14天(即5月18日到5月31日)10,000名虚拟用户的“促销-消费”交互测试,并按该测试结果显示在排行榜上。
【3】复赛最终结果,是对最终提交的策略在未来30天(即5月18日到6月17日)通过10,000名虚拟用户进行评估的结果。最终提交的策略即是在复赛最后一日所提交的策略模型。
根据参赛队伍所提交的策略在测试环境中的测试结果,在排行榜中实时更新排名,需要强调的是,每支队伍每天仅限提交一次。
1.4【评价规则】
奖赏目标为:在测试期内,在Total_ROI>=6.5的前提下,最大化Total_GMV。
注:初赛阶段评估在仿真环境中测试14天,复赛阶段评估在仿真环境中测试14天,复赛阶段最终提交的策略评估在仿真环境中测试30天。若Total_ROI<6.5,则得分为0,否则得分为Total_GMV值。
以一个用户一天为例,相关定义为:
优惠订单数(coupon_order_num):
coupon_order_num = min(day_deliver_coupon_num, day_order_num)
成本(coupon_order_fee):
coupon_order_fee = coupon_order_num×day_average_order_fee ×(1- coupon_discount)
单人营收(Per_GMV):
Per_GMV = day_order_num×day_average_order_fee - coupon_order_fee
总营收(Total_GMV):
Total_GMV = 所有用户所有天(14或30天)的Per_GMV之和
总成本(Total_Cost):
Total_Cost = 所有用户所有天(14或30天)的coupon_order_fee之和
总盈利率(Total_ROI):
Total_ROI = Total_GMV / max(Total_Cost, 1)
优惠券的作用规则如下:
(1)每张优惠券的有效期都是1天,过了有效期的券无法再使用。
(2)用户一天内可以使用任意张数的优惠券。
(3)当有优惠券时,订单自动使用优惠券。
1.5【提交方式】
参赛者基于大赛提供的接口,上传测评代码以及相关模型压缩文件, 解压后项目最外层目录定义好入口文件policy_validation.py, 并根据我们提供的模板,实现抽象类PolicyValidation,完成policy_validation.py。
policy_validation.py内容及说明如下图,参赛者主要需实现:
get_next_states (cur_states, coupon_action, user_actions)
输入当天所有用户的动作,输出由参赛者自行定义的次日用户状态。
get_action_from_policy (user_states)
输入当天用户状态,由参赛者策略输出当天所有用户的促销动作。
class PolicyValidation:
"""定义评测程序所需接口的虚拟类。
"""
"""initial_states 是参赛者根据离线数据定义的评测第一天(自5月18日开始)的用户状态。
"""
initial_states: Any = None
@abstractmethod
def __init__(self, *args, **kwargs):
"""根据自身需求初始化模型所需变量。参赛者可以为此构造函数提供一些形参,
但必须在 get_pv_instance() 函数中自行填充策略类所需的实参。
"""
@abstractmethod
def get_next_states(self, cur_states: Any, coupon_action: np.ndarray, user_actions: List[np.ndarray]) -> Any:
"""基于当天全体用户状态、当天的发券动作、与当天响应的用户动作, 生成次日用户状态。
Args:
cur_states (Any): 当天全体用户状态,具体形式由参赛者定义。
coupon_action (np.ndarray): 当天发券动作。
example: np.array([2.0, 0.70]), 即当天给所有用户发2张7折优惠券。
user_actions (List[np.ndarray]): 环境返回的当天所有用户动作, 具体形式和离线数据中一致。
example: [np.array([1.0, 22.34]), np.array([0, 0]), ... , np.array([2.0, 54.21])], 列表大小
和离线数据中用户数一致, 且按顺序一一对应,即 user_actions[0] 对应离线数据中 index 为0的用户。
Return:
next_states (Any): 次日全体用户状态,具体形式由参赛者定义。
"""
@abstractmethod
def get_action_from_policy(self, user_states: Any) -> np.ndarray:
"""基于当天全体用户状态输出当天发券动作
Args:
user_states (Any): 当天全体用户状态,具体形式由参赛者定义。
Return:
coupon_action (np.ndarray): 当天由参赛者策略给出的发券动作(所有用户相同), 具体形式和离线数据保持一致。
example: np.array([2.0, 0.70]), 即当天给所有用户发两张7折优惠券。
"""
class MyPolicyValidation(PolicyValidation):
"""在此继承 PolicyValidation 接口类,实现参赛者自己的策略模型。
"""
pass
def get_pv_instance() -> PolicyValidation:
"""返回一个符合 PolicyValidation 接口类的实例。该函数会被评测程序调用,用于获取参赛者的策略实现。"""
return MyPolicyValidation()
平台的策略测试评估核心代码如下
def validate(self, pv):
"""在平台真实环境中评估策略性能
Args:
pv (PolicyValidation): 参赛者实现的类型为PolicyValidation的实例化对象
Return:
Total_ROI, Total_GMV: 参赛者的策略在测试期的总ROI和总GMV
"""
Total_GMV = 0.0
Total_Cost = 0.0
user_states = pv.initial_states
for day_index in range(self.validation_length):
print('Day', day_index+1)
self.reset()
coupon_action = pv.get_action_from_policy(user_states)
Cost, GMV, user_actions = self.step(coupon_action)
user_states = pv.get_next_states(user_states, coupon_action, user_actions)
Total_GMV += GMV
Total_Cost += Cost
Total_ROI = Total_GMV / max(Total_Cost, 1)
return Total_ROI, Total_GMV
Reference
【竞赛组织】

江苏省人工智能学会
江苏省人工智能学会(JSAI)成立于 2017 年 8 月 28 日,省一流学会、省5A级学会,独立社团法人,江苏省科学技术协会团体会员。学会由省内人工智能及相关领域广大科技工作者和高校、科研院所、领军企业等自愿组成的学术性、专业性、非营利性社会组织。南京大学计算机科学与技术系主任、人工智能学院院长、欧洲科学院院士周志华教授当选首任理事长。 学会的宗旨是团结组织广大人工智能领域科技工作者,积极开展国内人工智能领域学术交流,发现和推荐人工智能领域优秀科技人才,不断提升人工智能理论研究水平,促进人工智能技术普及和推广,促进人工智能产业繁荣和发展。
江苏省人工智能学会 http://www.jsai.org.cn
南栖仙策
南栖仙策 (Polixir)是南京大学人工智能创新研究院技术孵化企业,专注于通用智能决策领域,通过环境模型学习技术的突破,率先实现了智能决策的落地应用。南栖仙策致力于在广泛的业务中释放人工智能的决策力量,成为人工智能工业革命的领导者。
南栖仙策 http://polixir.ai/