簡單的統計學:如何用Python計算撲克概率

2020-12-10 deephub

介紹

在本文中,我們展示了如何在Python中表示基本的撲克元素,例如「手」和「組合」,以及如何計算撲克賠率,即在無限額德州撲克中獲勝/平局/失敗的可能性。

我們根據《拉斯維加斯威尼斯之夜》中的真實故事提供實用的分析。

我們將使用poker包來表示手牌,連擊和範圍。 我已經擴展了來自Kevin Tseng的撲克賠率計算器,因此它除了能夠計算單個手牌之外,還可以基於範圍(可能的手牌)來計算撲克概率。

from poker import Rangefrom poker.hand import Comboimport holdem_calcimport holdem_functionsimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom IPython.core.display import display, HTMLhero_odds = []hero_range_odds = []

翻牌圈

我的手牌為K和J(KJ),我使用來自poker.hand的Combo類構造我的手牌。

# my hand = King of spades and Jack of clubshero_hand = Combo('KsJc')print(hero_hand)

我記不清翻牌前發生的事情以及我的位置。 但是,我確實記得翻牌前有加注,而翻牌後只剩下兩名選手:我和對方。

我們現在要注意。 翻牌圈出現梅花Q,紅桃10和梅花J。 是的,我翻到了順子!

讓我們假設沒有對方撲克的先驗知識來計算翻牌後的賠率,即在翻牌後,我們將計算出我的牌勝過隨機的一對牌的可能性。

flop = ["Qc", "Th", "9s"] # the flopboard = flop # the board equals the flopvillan_hand = None # no prior knowledge about the villanexact_calculation = True # calculates exactly by simulating the set of all possible handsverbose = True # returns odds of making a certain poker hand, e.g., quads, set, straightnum_sims = 1 # ignored by exact_calculation = Trueread_from_file = None # we are not reading hands from fileodds = holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = True)

Holdemcalc中的函數calculateodds_villan可以計算出特定的德州撲克贏手的概率。 通過運行蒙特卡洛方法可以估算出該概率,也可以通過模擬所有可能的情況來準確地計算出該概率,快速計算翻牌後的確切賠率。因此在這裡我們不需要蒙特卡洛近似值。 這是我們的賠率:

odds[0]{'tie': 0.04138424018164999, 'win': 0.9308440557284221, 'lose': 0.027771704089927955}

此時,我感覺還不錯。 在隨機的情況下,我只有2.77%的機會輸,獲勝的機會超過93%。 這很樂觀。

考慮到翻牌前有加注,而只有我和對方在翻牌後才離開,所以對方有一些手牌,對吧? 我們稱這種可能的手為範圍。 這是我們根據幾個因素(包括對方的舉止,位置,下注大小等)做出的推論。該推論導致我們假設對方可能擁有一組手牌。 在這一點上,我認為對方有:

一對7或更好A /10或更好K/J或更好我們可以使用「類別範圍」來表示該範圍,如下所示:

villan_range = Range('77+, AT+, KJ+')display(HTML(villan_range.to_html()))print("#combo combinations:" + str(len(villan_range.combos)))

這使對方手牌組合從總共51 * 52–1 = 2651個可能減少到144種可能。 現在假設對方手牌的範圍來計算我的賠率。

items = [holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = False) for villan_hand in villan_range.combos]odds = {}[odds.update({odd_type: np.mean([res[0][odd_type] for res in items if res])}) for odd_type in ["tie", "win", "lose"]]

{'tie': 0.11423324150596878, 'win': 0.8030711151923272, 'lose': 0.08269564330170391}

在假定的範圍內,我的獲勝機率從93%下降至80%。 但是,我仍然很可能損失8.2%。 在這一點上,我很明確。 但是我應該繼續嗎? 我絕對希望對方繼續比賽並且不棄牌。 但是他在翻牌後有個好牌的可能性有多大? 讓我們看看如果我們繼續玩到最後,他伸手的機率是多少。

for hand_ranking in holdem_functions.hand_rankings:print(hand_ranking +": " + str(np.mean([res[1][1][hand_ranking] for res in items if res])))

High Card: 0.06978879706152433 Pair: 0.3662891541679421 Two Pair: 0.23085399449035812 Three of a Kind: 0.09733700642791548 Straight: 0.18498112437506367 Flush: 0.0040608101214161816 Full House: 0.04205693296602388 Four of a Kind: 0.004560759106213652 Straight Flush: 2.0406081012141617e-05 Royal Flush: 5.101520253035404e-05

如果我們繼續玩,對方很有可能做出一對(36%)或兩對(23%)。 他極有可能直接命中(18%)甚至打出盤(9.7%)或滿堂(4%)。 由於對方很有可能擁有合理的手牌,因此我決定下高注,大約底池的2/3。

轉牌

到轉牌了,是方片2(2)。 基本上,這是一張空白牌,也就是說,它對我們的遊戲沒有太大影響。

turn= ["2d"]board = flop + turnvillan_hand = Noneodds = holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = True)hero_odds.append(odds[0]['win'])print(odds[0])

{'tie': 0.0233201581027668, 'win': 0.9677206851119895, 'lose': 0.008959156785243741}

假設對方的牌是隨機的,那麼我現在有96%的獲勝機率。

但是,考慮到我假定的對方手牌範圍,我的獲勝機率現在從翻牌時的80%上升到86%。 我再次下注,對方跟注,河牌來了。

items = [holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = False) for villan_hand in villan_range.combos]odds = {}[odds.update({odd_type: np.mean([res[0][odd_type] for res in items if res])}) for odd_type in ["tie", "win", "lose"]]

{'tie': 0.10123966942148759, 'win': 0.8615702479338843, 'lose': 0.0371900826446281}

河牌

是梅花K(K)。 這使對方更容易勝利。 所以這對我來說是個壞消息。

river = ["Kc"]board = flop + turn + river verbose = Truevillan_hand = Noneodds = holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = True)hero_odds.append(odds[0]['win'])print(odds[0])

{'tie': 0.11818181818181818, 'win': 0.8696969696969697, 'lose': 0.012121212121212121}

現在,我對隨機牌的獲勝機率從96%降至約87%。 但我仍然只以1.2%的極低概率輸掉。 好吧,那條壞的河牌不是那麼糟吧?

好吧,還有另外一個因素。 對方在翻牌圈和河牌圈都跟我有大賭注。 他可能比我想像的要好...對嗎? 然後,我應該調整我的假定範圍。

現在,我認為對方不再擁有77或88的一對,否則,鑑於我的高賭注,他不會跟下去。 我認為他可能有一對9或更好的一對,才能與99、10或QQ配對。 他可能還會有JJ從而導致平局。 或KK和AA,直到轉牌時都是頭對。 我決定保持10和K或更好的牌,因為有所謂的隱含賠率。 隱含賠率是對您打出的一筆錢可以從投注中贏取多少錢的估計。 因此,對方可能會等待中獎(他可能剛剛中了?)。 因此,我將對方的更新範圍定義如下:

villan_range = Range('99+, AT+, KJ+') display(HTML(villan_range.to_html()))print("#combo combinations:" + str(len(villan_range.combos)))

現在,對方的連擊數從144降低到了132。讓我們計算更新後的賠率。

items = [holdem_calc.calculate_odds_villan(board, exact_calculation, num_sims, read_from_file , hero_hand, villan_hand, verbose, print_elapsed_time = False) for villan_hand in villan_range.combos]odds = {}[odds.update({odd_type: np.mean([res[0][odd_type] for res in items if res])}) for odd_type in ["tie", "win", "lose"]]

{'tie': 0.12, 'win': 0.72, 'lose': 0.16}

現在,我有72%的機會獲勝(從86%下降的),而我在轉牌時的失利機率從3.7%增加到16%。 我決定慎重一下,對方則全押,下注大約70%的彩池。

基本的河牌戰略可以告訴您以下內容:

用你最小的牌作為河牌利用您最強的資產押注以中等強度的攤牌值檢查手牌,以期達到攤牌for hand_ranking in holdem_functions.hand_rankings: print(hand_ranking +": " + str(np.mean([res[1][1][hand_ranking] for res in items if res])))

High Card: 0.0 Pair: 0.5066666666666667 Two Pair: 0.08 Three of a Kind: 0.13333333333333333 Straight: 0.28 Flush: 0.0 Full House: 0.0 Four of a Kind: 0.0 Straight Flush: 0.0 Royal Flush: 0.0

從賠率直方圖中,我們可以將對方的可能手牌分為3種類型:

虛張聲勢:他拿著{好牌,成對}的機率為60.66%中強度牌:他以{0.8}的機率拿著{Two Pair}價值下註:他以41.33%的機率持有{三種牌}對方的全押是有道理的,他持有好牌的概率太低而無法檢查。 所以在這裡我在想他要麼因為虛弱而虛張聲勢,要麼他發瘋了,這是一個有價值的選擇。 如果您的持牌量最差,那麼會虛張聲勢;如果您的牌很強,則進行價值下注的基本策略有時被稱為兩極分化下注。 那就是對方在這裡所做的。

回顧每種類型的概率(虛張聲勢,中等強度的手牌,價值下注),我基本上應該至少有60.66%的勝率,這是一個保守的衡量標準,因為對方可能會押注三分之一。 但是我應該跟進嗎?

這是另一個稱為底池賠率的概念。 底池賠率是指相對於底池大小進行下注的價格。 總而言之,如果我贏得底池的概率大於底池限注價格和底池大小之間的比率,我應該跟注。 讓我們做一些數學運算:

贏取機會≥60.66%(保守估計)底池價格= 0.7 *底池大小預測底池大小=(1 + 0.7 + 0.7)*底池大小底池賠率=底池價格/預測底池大小= 29%我獲勝的機會至少是底池賠率的兩倍。 因此,我繼續跟進。 結果呢? 對方轉過牌。 桌子一度安靜,卻凝視著桌子上的Ace Jack。

討論和結論

在本文中,我展示了如何表示基本的撲克元素(例如手牌和組合),以及如何在講述威尼斯人夜晚的故事的同時,假設Python中的隨機手牌和範圍來計算撲克賠率。

我們展示了撲克有多麼令人興奮(概率上很有趣)。 在下面,我展示了我的獲勝賠率是如何從翻牌到轉牌,然後是河牌的改變過程,假設對方的隨機牌以及推斷範圍。

我們觀察到,即使最終結果不利於我,我還是贏得這一單挑局的主要人選。 這就是為什麼撲克玩家說

您應該專注於做出決定,而不關注所取得的結果。

當然,本文中的所有分析都假設了一些範圍和基本的撲克策略,這些策略和基本的撲克策略構成了我在玩遊戲時的思維模型,並在本文中以Python實現。 我不是職業撲克玩家,還有很多方法。 我相信我犯了一些錯誤,例如,低估了對方在翻牌前加注時持有A和J的可能。

我很好奇,其他人將如何使用此處使用的Python框架來分析手牌。

作者:Thársis Souza, PhD

deephub翻譯組:孟翔傑

相關焦點

  • 分析《德州撲克》獲勝的概率的計算 快樂之都
    《德州撲克》 概率計算所謂撲克的概率,簡單說,就是等來某種獲勝牌型的可能性(成牌概率),與底池提供籌碼(底池概率)之間的比較,如果底池籌碼足夠多,高於成牌可能,就玩下去,反之就棄牌。《德州撲克》底池概率(Pot Odds) 底池概率(Pot Odds)是已有的底池籌碼與你當前要下……
  • 德州撲克中如何計算翻前發到特定起手牌的概率
    撲克數學是德州撲克非常重要的一個方面,但它很簡單,不需要你具備高深的數學知識。我們將嘗試在本文中用淺顯的語言為你解釋如何計算翻前發到特定起手牌的概率。計算翻前發到特定底牌的概率非常簡單。每個牌手在牌局開始時將發到兩張起手牌。
  • 德州撲克概率表(完整版)
    這篇文章討論你應該知道的有關概率的所有重要的和有趣的內容。撲克中的概率. 概率是指某個事件會發生的確定程度。傳統的定義是: "一個事件的概率是特定事件發生的數量和所有可能事件發生數量的比率,且每個單位事件發生的可能性均相等,這使得它們的可能性是相同的。" 因此,投硬幣翻中頭的概率是1:2或50%。
  • 德州撲克講堂:如何將概率運用在行動下註上
    原標題:德州撲克講堂:如何將概率運用在行動下註上   概率,第五期內容介紹了德州撲克的經典速算法則——42法則,及玩家在翻牌圈將抽牌X4、在轉牌圈將抽牌X2便可大略算出勝率。本期將會結合前五期介紹的概率相關內容講解如何將概率運用在行動下註上面。
  • 簡單易懂的概率計算方法
    計算單一隨機事件的概率1.定義事件和結果。概率是在一系列可能結果中一個或多個事件發生的可能性。因此,假設我們希望計算出把一個六面骰子擲出三的可能性。"擲出三"是一個事件,而我們知道六面骰子可以被擲出六個數字中的任何一個,因此其結果數為六。
  • 專業大神教你德州撲克的概率表
    理解基本的概率將為你玩德扑打下更堅實的基礎,這篇文章討論你應該知道的有關概率的所有重要的和有趣的內容。充分了解德撲的規則才能更好的進行比賽。德撲究竟怎麼玩呢?概率是指某個事件會發生的確定程度,傳統的定義是:「一個事件的概率是特定事件發生的數量和所有可能事件發生數量的比率,且每個單位事件發生的可能性均相等,這使得它們的可能性是相同的。」因此,投硬幣翻中頭的概率是1:2或50%。對於撲克玩家來說,隨機學是研究概率中最有趣的部分,隨機性關係到以頻率為基礎的可能性。
  • 天天德州撲克算法 天天德州撲克算牌須知
    原標題:天天德州撲克算法 天天德州撲克算牌須知   本文將告訴你,高手是這樣煉成的,首先要學會《天天德州》撲克計算法   撲克計算法主要是學習撲克的概率,簡單說,就是等來某種獲勝牌型的可能性(成牌概率),與底池提供籌碼(底池概率)之間的比較,如果底池籌碼足夠多,高於成牌可能,就玩下去,反之就棄牌。
  • 如何利用excel工作軟體計算統計學相關數據
    這篇文章主要介紹用Excel軟體計算統計學數據的方法步驟,就不過多介紹每個統計學概念的具體意義了,如果大家感興趣,後續我會慢慢整理一些快速掌握統計學的方法
  • 圖解統計學:簡單易懂的基礎概率&描述性統計
    hyn | 作者知乎專欄 | 來源https://zhuanlan.zhihu.com/p/40756359 從小偏文科的我,聽到數學相關的知識就頭疼,更是毫無統計學基礎,之前用 Excel做零售分析時也從沒覺得統計學和數據分析有什麼必要關聯。
  • 概率控?談《天天德州》經典成牌概率
    《天天德州》華麗的外表之下,是樸實的德州撲克遊戲。這項傳統撲克遊戲在大數據概念橫行的今天,已經成了各種談論統計學與概率論書籍的常客——誰讓咱就是52張撲克抽5張那麼簡單的規則呢?事實上,牌桌統計學和概率分析從很早以前就開始了,目前計算成牌概率的理論也有好幾種,精細的方法更是從2人局一路計算到10人局,從高牌一路殺到皇家同花順。別以為概率只是書呆子的寶貝,雖然實際的對局中成牌的概率是隨著翻牌、轉牌、河牌的依次翻開,幾十上百倍的在增加,但了解一下經典的成牌概率理論,知道自己手中捏著多大的勝算,對贏牌很有幫助。
  • 數學統計學教材推介 | 數論/統計/概率/微積分
    數學統計學研究提供Springer高質量,前沿的研究橫跨數學統計學的研究領域,特別是代數、分析、應用程式、計算科學與工程、動力系統與微分方程、幾何和拓撲結構
  • Python X 蒙特卡洛方法
    蒙特卡洛方法是一種在統計學十分常用的一種隨機模擬方法, 簡單來說即使用隨機數來解決統計計算問題.
  • 德州撲克:AI打牌也能完勝人類了
    今天就從理性的角度講講,AI是如何打敗人類的。幾年前也是輝煌過的~~~德州撲克怎麼玩?舉個慄子,比如,小明是一個普通中國家庭長大的小孩,在他的一生中,面臨著很多個選擇,如何才能在未來走向人生巔峰呢?如果可以列舉出他未來所有的可能性,把每一步的選擇拆解成「子未來」,那麼就可以計算出成功勝算最大的選擇了。
  • ICML論文|阿爾法狗CTO講座: AI如何用新型強化學習玩轉圍棋撲克遊戲
    雖然限制德州拿住撲克(LHE)——一種真實世界規模的撲克遊戲——已經可以用目前的計算資源解決(Bowling 等人,2015),大部分其他撲克和真實世界遊戲如果不經過抽象化便無法觸及。我們的方法不依賴例如抽象化或者其他任何的預先知識。NFSP 代理利用深度強化學習來直接從其與遊戲互動的經驗中學習。當應用在德州撲克上的時候,NFSP 實現了一種納什均衡,而普通的強化學習方法出現了偏離。
  • 統計學入門級:常見概率分布+python繪製分布圖
    設在一次試驗中,事件A發生的概率為p(0<p<1),則在n重伯努利試驗中,事件A恰好發生 k 次的概率為: 其中表示從n個元素中抽取k個元素的組合,計算公式為: 因為連續型隨機變量可以取某一區間或整個實數軸上的任意一個值,所以通常用一個函數f(x)來表示連續型隨機變量,而f(x)就稱為概率密度函數。
  • 統計學知識大梳理(終極篇)
    概率與概率分布稍微關注過統計學的人,可能會這麼一個疑問。為什麼大學裡會有這樣兩門課,《概率論與數理統計》,《統計學》,它們有什麼區別?不確定性事件唯一的規律就是概率,獨立隨機事件我們沒辦法預測或控制它在某個時刻一定會發生,但卻可以用概率來描述它發生的可能性。以概率論作為理論基礎,為我們提供了認識不確定世界的方法。
  • Python科學計算入門書籍推薦
    話說回來,這近些日子,隨著機器學習的熱潮,python也算是程序界的蒂花之秀了,幾乎到處都能看到它的聲影。算下來,我也有「幾乎4年」的python開發時間了,期間還使用python來參加全國研究生數學建模比賽並連續兩年拿到了國二。都說python入門簡單,網上也有很多學習資源。但是大多數都比較亂,沒有一個明確的順序和方向。
  • 統計學知識詳解,數據分析也可以很簡單
    這本書將為你提供足夠的統計學領域知識,這樣你就不會迷失,與此同時,這本書也會教你使用統計學分析所需要的工具。基於上述原因,本書將重點講解統計學的基礎知識和假設檢驗,並簡單地介紹其他的統計學方法。我明白本書中介紹的大多數統計學檢驗也可以使用統計學建模的方法來完成。但是在大多數情況下,統計學建模並不是生命科學領域的期刊所使用的方法論。高級的統計分析超出了本書的範圍,並且坦率地說,也超出了我對統計學的了解。
  • 讀書學德州小綠皮之撲克中的數學!
    最重要和最難的部分就是計算底池賠率和隱含賠率。而這些數學原理只要通過簡單的加減乘除就可以算出來,很少會用到高深的數學計算公式。下面的章節會引導你使用數學原理讓你變成一個更好德州撲克玩家。我儘可能用最簡單直接的語言表述這裡面的數學原理。如果你感到困擾,放鬆一下,拿出筆和紙,自己演算一下例子。
  • 【入門】數據分析必備——統計學入門基礎知識
    Python、爬蟲、數據分析One old watch, like brief python成功的關鍵在於相信自己有成功的能力。但是,統計學的知識包括了圖形信息化、數據的集中趨勢、概率計算、排列組合、連續型概率分布、離散型概率分布、假設檢驗、相關和回歸等知識,對於具體的知識點,本文就不一一介紹了,感興趣的同學請參考《深入淺出統計學》、《統計學:從數據到結論》等專業書籍。定義:使用特定的數字或圖表來體現數據的集中程度和離散程度。