扑克概率神器揭秘!带你深入了解四二法则
2025年12月30日
德州扑克术语和策略指南来啦!想知道英文怎么说吗?
2025年12月30日


资料图
选自willtipton
机器之心编译
参与:Jane W、蒋思源
近来,强化学习也就是 RL 的成功,就像 AlphaGo 那样,获得了大众极高的关注,然而其基本的思路相当地简单。接下来,我们在一对一无限注德州扑克游戏当中进行强化学习。为了能够尽可能清晰明显地展示,我们会从零着手去开发一个解决方案,而并非需要预设的机器学习框架,像 Tensorflow 这种。那就让我们借助 Python3 的 Jupyter notebook 开始吧!
问题设置
规则提醒:该游戏是一个 2 人无限注的德扑游戏,其中:
游戏开启,有两名参与者,他们都具备S筹码,并且有着随机给予发放的2张底牌。
大盲注玩家,下了一个盲注的量,小盲注玩家,下了零点五个盲注的量 。
对于小盲注玩家而言,存在这样两种选择,一种是进行全押(all-in),另一种是选择弃牌(fold)。
要是小盲注玩家完成全押这样的操作,那么大盲注玩家便能够进行跟注或者选择弃牌 。
如下所示的决策树,我们能够将规则予以可视化。游戏起始于E,此时SB存在全押或者弃牌这两种选择。要是他选择弃牌,那么我们便会转移至状态A,游戏随之结束。倘若他选择全押,我们就会转移至状态D德信竞技,BB务必要在跟注以及弃牌之间做出抉择。要是有一个玩家选择弃牌,另一个玩家便会获取盲注;要是两个玩家都选择全押,那就会发放5张公共牌,并且金额依照扑克的正常规则来进行分配。
这个游戏存在著名的解决方案,它的网址是(http://www.dandbpoker.com/preflop-charts),除此之外呢,还有别的方法,像是虚拟对局啦,其网址为(https://www.youtube.com/watch?v=MVMfDswjJE0),以及直接优化,相关网址在这里(http://willtipton.com/coding/poker/2016/03/06/shove-fold-with-tensorflow.html)。这里,我们将使用强化学习估算解决方案。
这里有
种不重复的两张手牌组合数,所以,我们能够给所有纸牌排序,并且从0到1325进行编号。只要前后编号保持一致,那么具体的顺序便无关紧要了。以下函数暗中定义了这样一种排序,并且创建了从纸牌编号到相关决策信息的映射:纸牌的排序(牌面顺序/rank)以及同花性(牌面花色/suitedness)。
需要留意的是,输出那些处于元组里的首个元素(代码之中的 r2),一直都会排序在较前的地方,如果存有这种情况的话。举例来说,手牌的编号 57 正好就是 62,我们会有:
将玩家全押的情况考虑在内,他们平均所获取的底池的情况,也就是所谓的“期望利益”,是依据游戏规则来进行决定的。文件pf_eqs.dat,其链接是http://willtipton.com/static/pf_eqs.dat,它包含一个numpy矩阵pfeqs,pfeqs的链接是http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.savetxt.html,这里的pfeqs指的是,当对手持有手牌j的时候,持有手牌i所具有的期望利益。
自然,偶尔两人起始手牌之中会存在一张牌是一样的情形,于这种状况下,它们的期望没办法被同时进行计算,此时去获取他们的期望利益也是不合适的。文件pf_confl.dat(http://willtipton.com/static/pf_confl.dat)涵盖另一个1326×1326矩阵,其中每一个元素是0或者1。一个0意味着两位玩家的起始手牌不相同,一个1意味着起始手牌相同。
比如说,鉴于手牌当中56这个数是62,57这个数是62,58这个数同样是62,所以我们便得到了如下情况:
为什么结果不正好是 0.5 呢?
强化学习
接下来步入RL教程,RL问题存在三个关键构成部分,分别是状态,动作,奖励,它们组合在一起呈现如下:
1。 我们处于某‘状态’(即我们观察到的世界的状态)。
2。 我们使用这个信息来采取某‘动作’。
3。 我们会得到某种‘奖励’。
4。 重复以上过程。
没完没了地反复进行上述流程:留意状态,实施行动,获取奖励,留意新状态,施行另一行动,收获别一番奖励等。RL问题不过是探寻怎样挑选行动的办法来获取尽可能多的奖励。事实表明这是个极为普遍的框架。我们能够借由这一方式考察诸多问题,解决这些问题也存在诸多各异的手段。一般来讲,解决办法关联随机游走,也就是四处徘徊,于各异状态挑选多样行为,牢记哪些组合可获取何种奖励,接着试着借助这些信息在往后做出更优选择。
RL怎样被运用到德扑游戏当中呢,在任意一个决策点处,有关状态,玩家清楚自身的2张底牌以及自身所处的位置,随后他能够施行行动,要么选择弃牌,要么选择GII,对于SB而言GII意味着全押,对于BB而言GII意味着跟注,接着获得奖励,此奖励是玩家所赢取的钱数,在最后的手牌里会运用玩家的总筹码大小,举例来看,要是初始筹码大小为S等于10,SB全押而BB弃牌,那么玩家所获得的奖励分别是11及9 。
对两个玩家提交的随机手牌,我们边同步进行处理,边让他们针对如何玩牌去产生决策,随后观察每次结束之际他们最终所获取到货币数量,通过模拟手牌组合的方式来找到游戏策略,再依据这些信息去学习(估计)Q函数Q(S,A),其中Q的参数是状态S以及动作A,输出值是于该种状态里采取该动作时所得到的最终奖励数值,一旦拥有Q(或者它的某种估计),策略选择便特别容易了,即能够去评估每一个策略,进而看出哪一个更具优势 。
所以,我们这儿的工作是对Q进行估计,我们会用Q^(发“Q hat”的音)来指代这个估计。初始化的时候,我们会随机猜测一些Q^。紧接着,我们会模拟一些手牌,两名玩家依据Q^做出决定。每一次手牌之后,我们会调整估计值Q^,去反映玩家在特定状态下采取特定动作后所获得的实际值。最终,我们应当得到一个不错的Q^估计,这便是确定玩家策略所需的全部内容。
我们要留意这里关键的一点,那就是,不论处于何种状态,都得采取所有的动作,并且每个状态与动作的组合都必须至少尝试一回,通过此般方式,才能够恰如其分地估算出最终每个有可能出现的值。所以呢,我们会促使玩家于一小段时间ε之内随机地去施行行动,运用他们依据(自身当前所估计的)最佳策略。首先,要十分主动地探索选择所具备的可能性,频繁地进行随机选取。随着时间不断向前推移,我们会更多地借助所获取到的知识。换句话讲,ε会随着时间的推进而逐渐缩小。达成这一目标存在着诸多办法,好比:
“动作价值函数(action-value function)”被称作Q,因为从任何状态采取任何特定动作的值由它给出,它在大多数RL方法里有重要作用,Q^怎样表示,如何评估,是否在每次手牌之后更新?
特征:Q^ 的输入
首先,Q^的输入是状态和动作,把这个信息传递给Q函数,作为位置, SB情况下为1,BB情况下为0,还有手牌编码,范围是0到1325,以及动作,GII情况下为1,弃牌情况下为0。不过,我们将会看到,要是我们做更多的工作,就会得到更好的结果。在这里,我们用7个数字的向量描述状态和动作:
由函数phi返回的向量φ会成为Q函数的输入,此向量被称作特征向量,其各元素均为特征(φ发音为‘fee’)。我们将会看到,我们所挑选的特征能够在结果质量方面引发极大差异。在挑选特征这一行为(被称为‘特征工程’)过程中,我们运用了与问题相关领域的知识。它如同科学一般具有艺术性。在此处,我们会把判断哪些属于相关信息(在这种情形下)的知识通过以下几种方式进行编码。让我们瞧瞧。
为了达到便利的目的,第一个元素一直都是1。思考紧接着的四个元素。这些是用来表示玩家被发到的手牌的。我们已经从对手牌进行编码的形式,转变为了rank1、rank2以及isSuited。这三个变量从技术层级而言得出了与手上那张用以比赛的牌的编码一样的信息(不考虑特定的组合情况),然而该模型会更出色地运用这种格式所呈现的信息。除了原本就设定好的排序之外,我们还纳入了(|rank1 – rank2|)^0.25。我们恰好了解到connectedness是德州扑克的关键属性,正和它的名称相契合。此外,当所有特征在量纲方面保持一致时,该模型所呈现出的学习效果将会更为出色。在此处,所有的特征大致处于0与1这个范围之间,而这是我们借助把rank除以numRanks从而获得的。
最后,要是 not 是 GII(也就是动作属于弃牌的情形下),实际上我们会把这一些数字设定成 0 。我们清楚,当玩家进行弃牌操作时,特定的持有手牌对于结果而言不存在任何影响(将小概率的卡牌移除效果排除在外),因而我们在这种状况下把无关的信息予以删除。
当下思考最后那两个元素,第一个径直编码玩家所处的位置,然而第二个却同时依赖于isSB以及isGII,何以如此呢,稍后我们会展现这个“交叉项”的必要性。
关于 Q^ 的线性模型
我们会学习一个用于估计的线性函数,该函数对应的是Q^函数,这表明我们要真正去学习一个参数向量,此参数向量一般叫做θ,其长度是7,且与特征向量一致,之后,我们要针对特定的φ来对Q^进行估计 。
此地,下标 i 用以指代向量的特定元素,且将参数列表写成 (φ;θ),这其中表示 Q^ 的值是依赖于 φ 和 θ 的,然而我们能够把它认为成是 φ 的函数,此时 θ 是固定的值,代码是很简单的:
纵使这个函数被广泛运用,然而这个算法并无突出之处,致使它身为这个问题的最优之选。这仅是其中一种方式:把某些学习参数跟某些特征相融合来获取输出,且完全由我们去定义一个θ向量,让它生成我们期望的输出。可是啊,正确挑选θ会为我们出色地估量在具备特定手牌时采取特定行动的价值 。
模拟扑克游戏
接下来,我们要着手处理手牌方面的事务了。这一过程会在后续的几个部分里落地实施,然而当下我们得先去架构三个关键的概念。这三个概念和RL问题的三个关键构成部分存在关联。它们分别是:状态、动作以及奖励。首先来说状态,在每一次进行手牌操作的时候,我们会借助随机发牌的形式,去为每一位玩家的状态完成初始化操作。
再者,实施行动。每一位玩家会运用现有的型号(被 theta 所呈现)以及已知的手牌与身份(是 SB)去挑选行动。于下述函数内,我们估算 GII 以及弃牌/FOLD(qGII 与 qFOLD)的数值。接着抉择当下的最优者(1 减 ε),不然随机选取行动。返回所施行的行动,以及对应的价值估量与特征向量,这两者我们后续会用到。
第三点,一旦情况是我们清楚知晓每个玩家当下所拥有的手牌以及其做出的动作,那我们便会去模拟剩余的手牌以此来获取玩家的奖励。要是存在任何一个玩家选择弃牌,那么我们能够马上返回正确的奖励值。不然的话,我们会参考玩家的状态以及奖励期望(权益),在恰当的时间段随机挑选出一个赢家。
在玩家将所有筹码都押上的情形下,我们运用小手段避开了模拟。不同于借助5张公共牌切实模拟游戏并对玩家的手牌进行评估来晓得谁获胜,我们如今依据预先算好的概率随机挑选出一个赢家。这在数学层面是等同的(琐碎的证明予以忽略),这仅仅是一种更便利且更具计算效率的方式。
更关键的是,我们开展学习的进程未曾借助这些equity,或者有关游戏规则的讯息。就像我们即刻将会目睹的这般,哪怕是全然模拟,学习进程也并无差异,甚至智能体还会跟外部黑盒的扑克游戏体系展开交互进而或许遵循不一样的规则!那么,学习进程到底是怎样推进的呢?
学习:更新 Q^
一回手牌结束过后,我们得去更新 theta。针对每一名玩家,我们已然知晓其状态以及所采取的动作。我们也有动作对应的估计价值,还有从游戏当中获取的实际奖励。从某种层面来讲,实际获得的奖励是“正确解”,要是动作的估计价值跟这个不一样,那我们的模型就存在错误。我们要更新 theta,从而让 Q^(φ;θ)更靠近正确的答案。
先设定,有一个特定状态,它属于一个玩家 ,以 φ‘ 来表示此状态 ,而R是这个玩家所获取到的实际奖励 。再令L等于特定算式 ,即L =(R – Q^(φ;θ))^2 。这个L被称作损失函数 。关键在于 ,L越小 ,那么R就越趋近于Q^(φ;θ) ,要是L等于0 ,那就意味着Q^恰好等同于R 。换个说法来讲 ,我们期望去微调参数 θ ,从而让L变得更小 。(需留意 ,存在诸多可能的损失函数 ,它们呈现出这样的特性 ,即随着Q^越来越靠近R ,L会越来越小 。这里所采用的损失函数仅仅是一种常见的选择) 。
所以“更新Q”意味着令θ产生改变进而让L变得更小。能达成这一目的的方法并非仅有一种,其中一种简便方法当属随机梯度下降,也就是所谓的“stochastic gradient descent”。简单概括来讲,它用于更新θ的规则是:
我们要挑选‘超参数’α,它名为学习率,能把控每次更新的幅度。倘若α过小,学习速度就会迟缓,然而要是它过大,学习过程或许无法收敛。把L代入到这个更新规则里,再进行几行微积分计算,最后我们得到。
提供更新参数准则的是最后一行,我们会依据这个来编写代码,要注意这里的θ以及φ都是长度为7的向量,这里更新参数的准则在分别上适用于每个的元素,。
整合
最后,该整合所有内容了。重复以下步骤:
1。 随机发给每个玩家手牌。
2。 令玩家各自选择一个动作。
3。 得到结果。
4。 使用观测到的(状态,动作,结果)元组更新模型。
有着这样一种蒙特卡罗算法,下面的函数mc将其实现了,参数theta对应学习模型的,被返回了。
特别注意,上节推导出的参数更新规则在代码中得到了实现。
结果
解释模型
本例中,固定 S=10。
我们获取到了数字,然而,它们具备意义吗?事实上,存在几种方式能够协助我们进行判断,并且借助它们获取一些关于模型的解释 。
起始阶段,先行考虑某些特定的情形。当SB执行弃牌动作(就是FOLD动作)时,究竟它的估计数值是多少呢?能够轻易得出,毕竟处于这种状况下phi相对比较简易。实际上,除开第1个(恒定为1)以及第6个(对应着isSB)而言,其他的所有的元素均为0,phi等于。
1,0,0,0,0,1,0
所以,我们的线性模型的Q^,仅仅等同于加总其,theta的第1个 和第6个 元素 。
现在,我们清楚了,依据游戏的规则,SB所做出的选择弃牌这一行为的价值是9.5 ,所以,极其 cool,其中模型与真实状况是万分接近的!这算得上是一种很棒的逻辑判断,并且还用例子阐述了怎样去预估我们模型有可能出现的误差值的大小 。
存在另一种情形,即BB实施弃牌行为。仅phi的首个元素呈现为非零状态,随后我们察觉出一个估计数值,。
即便并不明晰确切的答案该是怎样的,只是晓得它必定应当处于9(要是SB始终是GII的情况下去估量)以及10.5(要是SB一直都选择弃牌的情况下而言)之间。实际上呢,这个数值相较于10.5,更加靠近9,这和SB更加偏向于GII而并非是其他态势是相契合的。
存在一个用于思考各个θ输入的更为普遍的方法 ,每个元素θ_i会致使Q^出现增加 ,这是由于与之对应的特征φ_i会增加1 ,比如 ,在拥有恰当的手牌并同时施行GII策略之际 ,θ的第5个元素也会增加1 ,所以说 ,拥有适合手牌的估计奖励值为0.22571655 ,这是一个较小的正向奖励 ,看起来甚是合理 。
对应于玩家排名较高之手牌的,θ的第2个元素是6.16764962,这和一个特征相对应。这个特征这样,如果是isGII的话,就是rank2除以numRanks,不然的话就是0,它代表的是玩家排名较高手牌时的GII策略。这里,因为是rank2除以numRanks,所以,特征每增加1就大约相当于2和ace之间的差。用一个额外的6BB再加上1个ace,而不是用2的情况下居然可以取得胜利,这样看起来好像是挺合理的呢 。(但是,为什么你会觉得有第二张更高的手牌显然是负的?)
去核查与第6个特征所对应着的θ的元素,若处于isSB的情况那便为1,不然就是0,要是所有其余的特征都相等,那么在SB里的附加值明显就是-0.15230302。我们恐怕能够将这解读成位置方面的劣势,鉴于不得不率先去采取行动而产生的小惩罚。
然而,其他的所有方面并不必然就是一样的。要是SB去执行GII这种策略,那么最后一个具有明显呈现的特征也不是为零这种情况。所以,-0.15230302就是SB进行弃牌操作时所拥有的附加价值。当开展执行GII这个行为之际,我们去归纳总结最后这一个特征所产生的作用效果,发觉奖励是-0.15230302加上0.14547532最终等于-0.0068277。很明显,当SB采用更为突进激进的策略之时,所处位置的劣势情况就会变少!
在本问题范畴这儿我们能看到,选择有意义的特征对有效解释结果有帮助。颇为有趣的是,有一种玩德扑游戏的老规则叫作SAGE。在锦标赛现场这个规则较易被记住。其原则是为你的手搭建“能力指数”,这是照顺子、同花以及对子来构建规则的,之后用它判定是否GII。它们的特征组合跟我们的特征组合相比较会怎样呢?它们的结果又是如何呢?
最终,为何选取isSB以及isGII去判定最后一项特征,而不单单是isGII呢?思索如下:(BB,FOLD)的估算值仅是θ的首个元素,因而此首个元素要可随意变动,进而获取正确的(BB,FOLD)数值;那么,第6 个元素是处于SB里的额外贡献之体现,它得能够随意变动,以此获取正确的(SB,FOLD)。
一旦咱们自弃牌转移至GII,元素2至5变成非零情形,且依据玩家被调整成特定数值,可这些决策同样适用于SB以及BB。此模型要给SB全押拿出一些有别于BB全押的决策。
假设,我们会有的最终特征是,若isGII成立那么就是1,要是不成立那就是0。这并非由玩家决定,所以,SB和BB的估计值之间,唯一存在的差异,将会是在于isSB项。这个数字,必须把执行弃牌时SB和BB之间的差异考虑在内,还要把执行GII时SB和BB之间的差异考虑在内。模型必须在这两个差异中间挑选出一个数字,最终有可能会造成一些不太理想的折中情况。相反,我们所需要的是,若isGII以及isSB均成立则为1,要是不成立那就为0。如此一来,这个模型能够去分辨SB GII跟BB GII的增量数值 。
留意,此模型依旧没办法捕捉诸多细微的详情。举例来说,鉴于模型全然内置的函数形式,我们所见到的GII的估计值的差别在两种特定手牌组合情形下,像A2 和K2,对于SB和BB而言是全然一样的。不问θ的值怎样,我们的模型都绝无可能进行预测。
有这样一种模型,其偏差值(bias)很高。它不具备灵活性,且存在一个具备强大影响力的内置“观点”,该“观点”用于决定结果呈现出何种样子。这便是特征工程极为重要的原因所在。要是我们未曾尝试为算法提供经过精心设计的特征,那么算法或许就缺乏表征一个优质解决方案的能力。
能够给模型增添更多的特征,像是其他交叉项,借此获得偏差较小的模型,然而这有可能会引发缺点。这迅猛地就失却了可解释性,并且也或许会遭遇更多的技术问题,像过拟合这种情况。(当然了,在多数运用当中这并非是首要问题,准确性相较于可解释性更为重要,而且存在应付过拟合的方法)。
可视化策略
我们要评估该模型,以此来找到完整的策略,目的是了解在每个玩家的1326种手牌组合里面,究竟是GII更好,还是弃牌更好,是这样的情况:
看起来,针对SB而言,大概55%的手牌抉择是进行全押,然而针对于BB来讲,大概49%的时段会选择跟注。
末梢,咱能够制造些许SVG,用以于Jupyter环境里描绘GII范畴,。
拿不定主意如何抉择呢在此处存在着诸多符合我们所期望的具有定性特征之处亦即较大的手牌状况良好拥有对子情形良好同花优于非同花SB相较于BB打法更为宽松等可是处于边界线状态的手牌其作出打法选择的方式有的时候会和真实存在的平衡策略相应的打法有所差异 。
结语
文章对 RL 技术进行介绍,此文章为我们提供了一些合理策略用于德扑游戏,该学习过程不依赖任何结构,也不依赖游戏规则,而是让智能体自行游戏,观察结果,依据此做出更好决定,另一方面,重要特征工程要学习好模型需一些领域专业知识。
最后,来介绍一番背景。好多的合适问题,都能够阐述成 RL 问题 ,而且,也有着好多不一样的方法用来去解决它们。这里的解决方案,或许会具备下面这些特征咯:属于无模型的情况,有着基于价值的特性,是蒙特卡罗类型的,处于在策略之类别的,采取的是无折现型手法,并且还运用了线性函数逼近器哟 。


