有一次,一个朋友问我一个问题:“如果用户连续三天没有打开 App,我们应该发优惠券,还是发提醒消息?” 这听起来像一个很普通的产品问题。

但如果你认真想一想,会发现它其实很难回答。

因为:

CODE
发优惠券 → 用户可能回来,但也可能养成等优惠的习惯
不发优惠券 → 用户可能流失,但也可能自己回来

换句话说,一个动作的好坏,并不取决于它当下的效果,而取决于它之后会带来什么。

这正是今天这篇文章要讨论的核心:状态-动作值函数(State-Action Value Function)。

我们每天都在做一个“隐藏计算”

假设你在运营一个电商平台。现在有一个用户:

CODE
最近 7 天没有购买
过去 3 个月消费频繁
最近浏览了 2 次商品

这就是当前状态(State)。你有两个选择:

CODE
动作 A:发 20 元优惠券
动作 B:什么都不做

问题是,哪个更好?

注意,这不是一个即时问题。我们真正关心的是:未来 30 天的总收益,而不是今天的点击率。

强化学习真正关心的,从来不是下一步

强化学习关心的更多是长期回报(Return),但这里会出现一个新的问题:如果一个状态下有多个动作,我们该怎么比较?例如:

CODE
状态:库存紧张

可能有: 

CODE
动作 1:提价
动作 2:限购
动作 3:加急补货

这时候,我们就需要一个工具,评估“在这个状态下做这个动作,长期会发生什么”。

这个工具就是状态-动作值函数。

什么是状态-动作值函数?

假设你在做一个外卖平台。系统检测到:

CODE
当前时间:晚上 7 点
天气:下雨
骑手数量:偏少
订单量:快速上升

这是状态,现在系统有两个选择:

CODE
动作 A:提高配送费
动作 B:维持原价

我们可以观察历史数据,得到这样的结果:

1、如果执行提高配送费,未来可能发生:

CODE
订单减少
骑手上线增加
系统压力下降
最终收益:+120

2、如果执行维持原价,未来可能发生:

CODE
订单暴增
骑手不足
延迟增加
用户投诉
最终收益:+30

于是系统学会了一件事情:在这个状态下,提高配送费更好。这就是状态-动作值函数在工作。

因此,状态-动作值函数是用来衡量在某个状态下采取某个动作,未来长期收益是多少。数学上通常写成:

CODE
Q(s, a)

意思是:State s Action。a 对应的是Expected Return,你可以把它理解成一个动作的“长期评分”。

同一个动作,在不同状态下价值完全不同

举例来看,假设动作是:发优惠券。

在状态A:用户刚完成购买,价值可能是 -10 ,因为浪费成本。

但在状态B:用户 30 天未登录,价值可能是 +200 ,因为可能挽回用户。 

这就是为什么强化学习不会问“哪个动作最好”,而是问:在这个状态下,哪个动作最好。

一个简单的示意图

我们可以通过一个简单的示意图例子来直观理解:

CODE
状态:用户 7 天未登录
        发优惠券      不发
            │           │
        用户回归     用户继续沉默
            │           │
        再次购买      流失
            │           │
         +80          -50

系统会不断统计: 

CODE
Q(未登录, 发券) = +80
Q(未登录, 不发) = -50

然后选择发券。

Q Table

直接来看一个Q Table的例子:

CODE
状态            动作          价值
-------------------------------------
库存高          降价          120
库存高          不变           60
库存低          降价          -80
库存低          提价          100

这张表就叫Q Table,Q Table 本质就是把「状态 s 下做动作 a 的价值」全部存成一张表,所以它直接对应状态 - 动作值函数 Q (s,a)。

一个非常简化的 TensorFlow 示例

下面这段代码模拟的是系统不断更新动作价值:

CODE
import tensorflow as tf
import numpy as np
num_states = 4
num_actions = 2
Q = tf.Variable(
    tf.zeros([num_states, num_actions])
)
learning_rate = 0.1
gamma = 0.9
for step in range(200):
    state = np.random.randint(0, num_states)
    action = np.random.randint(0, num_actions)
    reward = np.random.randn()
    next_state = np.random.randint(0, num_states)
    best_next = tf.reduce_max(
        Q[next_state]
    )
    target = reward + gamma * best_next
    Q[state, action].assign_add(
        learning_rate *
        (target - Q[state, action])
    )

通过代码,你只需要理解的是,系统就是通过不断更新来计算这个动作到底值不值。

为什么这个概念对产品经理特别重要

我们以前做机器学习时:

CODE
输入 → 预测结果

现在变成: 

CODE
状态 + 动作 → 未来价值

也就是说,强化学习不是预测“会发生什么”,而是预测“这个选择值不值”。

这个概念对产品经理特别重要,因为你每天都在做同样的事情。例如:

CODE
是否给补贴
是否发推送
是否降价
是否上线新功能

这些决策,本质上都是选择一个动作,承担未来结果。

而状态-动作值函数的思维方式,就是不看短期指标,而看长期价值。


在很多系统里,我们习惯用指标来评价一个动作是否成功,比如点击率上升了,转化率提高了,收入增长了。但随着系统越来越复杂,你会慢慢发现,一个动作真正的意义,往往不会立刻显现。

它可能在未来几天、几周,甚至几个月后,才开始改变用户的行为路径。

状态-动作值函数,本质上提醒我们一件很朴素的事情:真正成熟的决策,不是看一次结果,而是看它对未来的影响。

而一个好的产品,也往往不是由一次正确的选择构成的,而是由一系列能够持续带来长期价值的选择,慢慢积累出来的。

附录:本文涉及的专有名词中英文对照(标红为最核心)

中文
English
说明
状态-动作值函数
State-Action Value Function
衡量在某个状态下执行某个动作的长期收益
Q函数
Q Function
状态-动作值函数的另一种名称
Q值
Q Value
某个状态和动作对应的预期回报
状态
State
当前环境情况
动作
Action
系统可以采取的行为