├── .gitignore
├── Poker Hand History Review.ipynb
├── Poker Probability and Statistics Part 1.ipynb
├── Poker Probability and Statistics Teaser.ipynb
├── Poker Probability and Statistics-Part 2 Final Draft.ipynb
├── Poker Probability and Statistics-Part 2.ipynb
├── Poker Segmentation.ipynb
├── README.md
└── Report25_vsPlayerFinal.csv
/.gitignore:
--------------------------------------------------------------------------------
1 | # History files
2 | .Rhistory
3 | .Rapp.history
4 |
5 | # Session Data files
6 | .RData
7 |
8 | # Example code in package build process
9 | *-Ex.R
10 |
11 | # Output files from R CMD build
12 | /*.tar.gz
13 |
14 | # Output files from R CMD check
15 | /*.Rcheck/
16 |
17 | # RStudio files
18 | .Rproj.user/
19 |
20 | # produced vignettes
21 | vignettes/*.html
22 | vignettes/*.pdf
23 |
24 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
25 | .httr-oauth
26 |
27 | # knitr and R markdown default cache directories
28 | /*_cache/
29 | /cache/
30 |
31 | # Temporary files created by R markdown
32 | *.utf8.md
33 | *.knit.md
34 | .Rproj.user
35 |
36 | # Python
37 | *.exe
38 | *.ipynb_checkpoints
39 | *.idea
40 |
--------------------------------------------------------------------------------
/Poker Hand History Review.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "In the business world, Data Science is used to make predictions and optimize decisions by creating machine learning models. In online poker, the decision that needs to be made is whether to bet, call, or fold, but you aren’t allowed to use software to make that decision for you. At most online poker sites, that is where the line is drawn in the rules. This means that the model that must be trained is your brain, and the training is done away from the table with an endless stream of equity calculations. Anytime I ran into a situation while playing that confused me, I would mark the hand for review later. After my poker playing session was done, I'd go back through the hands that I'd marked for review and break them down mathamatically so I'd have a better idea of what to do in each situation the next time it arose.\n",
8 | "\n",
9 | "Here is an example:\n",
10 | "\n",
11 | "- When reviewing poker hands, it is common to refer to our opponent as the \"Villian\" and ourselves as the \"Hero.\"\n",
12 | "- Hero has: \n",
13 | "- Hero bet 0.85 (Hero has 20.95 remaining);\n",
14 | "- Opponent (Villian) raises to 2.50 (Villian has 30.35 remaining);\n",
15 | " - In poker termanology, this is called a 3bet. The small blind and big blind make the first bet, and I raised them which was the second bet.\n",
16 | "- There is currently 3.70 Total in the Pot;\n",
17 | "\n",
18 | "\n",
19 | "Calling is not a good option for reasons that are beyond the scope of this blog post. We must decide between raising with the plan of going ‘All-In’ or folding. Folding costs nothing so we will analyze the expected value of going all in. In this situation, I’d make a small raise to induce my opponent to ‘All-in’ bluff, but we need to do the calculation as if I’m going ‘All-in’ since that is the plan, so;\n",
20 | "\n",
21 | "- Hero risks 20.95 if All-in and loses;\n",
22 | "- Hero wins 23 if All-in and wins;\n",
23 | "- Hero wins 3.70 if Villian folds.\n"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 36,
29 | "metadata": {
30 | "collapsed": true
31 | },
32 | "outputs": [],
33 | "source": [
34 | "LoseAllIn = -20.95\n",
35 | "WinAllIn = 23\n",
36 | "WinVillianFolds = 3.7"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "Poker is a game of deductive reasoning based on incomplete information. Here is the information you have on this opponent:\n",
44 | "\n",
45 | "- The Villian is in the Button position which is the first position to the right of the small and big blinds. Overall, from this position, villian 3bets 7.4% (27 trials);\n",
46 | "- Hero is in the Cut-Off position, which is the first position to the right of the Button. Overall, vs. the Cut-Off, villian 3bets 12.5% (16 trials);\n",
47 | "- When Villian is in the Button vs. a pre-flop raise from the Cut-Off, villian 3bets 25% (4 trials);\n",
48 | "- When Villian 3bets pre-flop and faces a raise, he folds 50% of the time (2 trials)."
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "Based on the above statistics, I’m going to make the following assumptions which are educated guesses;\n",
56 | "\n",
57 | "- Villian raises to 2.50 with about (~) 13-15% of the range of possible starting hands;\n",
58 | "- Villian folds to a re-raise ~ 25% of the time and goes ‘All-in’ ~75% of the time;\n",
59 | "- Villian re-raises ‘All-In’ with a ~10% range, which looks like this: \n"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "\n",
67 | "- The hands highlighted in yellow represent the Villian's range, which consists of 128 of the 1326 possible combinations of starting hands (9.7%);\n",
68 | "- If you’re wondering why A5s and A2s are in the range, those represent Villian’s bluff hands.\n",
69 | "\n",
70 | "Now that I have Villian’s range, I can plug the Hero's hand (10h10s) and the Villian’s range into an [equity calculator](http://www.acepokersolutions.com/Poker-equity-calculator/). The equity calculator simulates 10h10s vs. Villian’s range thousands of times and determines that the Hero wins ~53.77% of the time. Now it’s a simple calculation. You need to build a function that represents the following equation:\n"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "- $ifVillianFolds = (WinVillianFolds * EstimatedFoldPercent)$\n",
78 | "- $ifVillianAllin = ((WinAllIn * Equity) + (LoseAllIn * (1 - Equity))) * (1 - EstimatedFoldPercent)$\n",
79 | "- $AllinExpectedValue = ifVillianFolds + ifVillianAllin$\n",
80 | "\n",
81 | "Now you can create variables for `EstFoldPercent` and `Equity`, and then create your `AllinExpectedValue` function."
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": 37,
87 | "metadata": {
88 | "collapsed": true
89 | },
90 | "outputs": [],
91 | "source": [
92 | "EstFoldPercent = .25\n",
93 | "Equity = .538"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": 38,
99 | "metadata": {
100 | "collapsed": false
101 | },
102 | "outputs": [],
103 | "source": [
104 | "def AllinExpectedValue(LoseAllIn, WinAllIn, WinVillianFolds, EstFoldPercent, Equity):\n",
105 | " ifVillianFolds = (WinVillianFolds * EstFoldPercent)\n",
106 | " ifVillianAllin = ((WinAllIn * Equity) + (LoseAllIn * (1 - Equity))) * (1 - EstFoldPercent)\n",
107 | " AllinExpectedValue = ifVillianFolds + ifVillianAllin\n",
108 | " if AllinExpectedValue > 0:\n",
109 | " return AllinExpectedValue, 'Raise!'\n",
110 | " else:\n",
111 | " return AllinExpectedValue, 'Fold!'\n",
112 | " "
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": 39,
118 | "metadata": {
119 | "collapsed": false
120 | },
121 | "outputs": [
122 | {
123 | "data": {
124 | "text/plain": [
125 | "(2.9463250000000016, 'Raise!')"
126 | ]
127 | },
128 | "execution_count": 39,
129 | "metadata": {},
130 | "output_type": "execute_result"
131 | }
132 | ],
133 | "source": [
134 | "AllinExpectedValue(LoseAllIn, WinAllIn, WinVillianFolds, EstFoldPercent, Equity)"
135 | ]
136 | }
137 | ],
138 | "metadata": {
139 | "anaconda-cloud": {},
140 | "kernelspec": {
141 | "display_name": "Python [default]",
142 | "language": "python",
143 | "name": "python3"
144 | },
145 | "language_info": {
146 | "codemirror_mode": {
147 | "name": "ipython",
148 | "version": 3
149 | },
150 | "file_extension": ".py",
151 | "mimetype": "text/x-python",
152 | "name": "python",
153 | "nbconvert_exporter": "python",
154 | "pygments_lexer": "ipython3",
155 | "version": "3.5.2"
156 | }
157 | },
158 | "nbformat": 4,
159 | "nbformat_minor": 1
160 | }
161 |
--------------------------------------------------------------------------------
/Poker Probability and Statistics Part 1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Probability and Statistics: Python Tutorial - Part 1\n",
8 | "\n",
9 | "Data Scientists create machine learning models to make predictions and optimize decisions. In online poker, the options are whether to bet, call, or fold. You aren't allowed to use software to make those decisions though. That's where most online poker sites draw the line in the rules. Since you can't train a machine learning model, you must train your brain. This requires an endless stream of equity calculations away from the poker table, which use many different probability and statistics concepts. \n",
10 | "\n",
11 | "In this tutorial, you'll learn some of these concepts using a deck of cards and generic poker situations. More specifically, you'll cover the following topics:\n",
12 | "\n",
13 | "- Probability Theory: An Introduction\n",
14 | " - Key Concepts\n",
15 | " - Calculating Probability\n",
16 | "- Probability with Combinations and Permutations\n",
17 | "- Independent versus Dependent Events\n",
18 | "- Multiple Events\n",
19 | " - Mutually Exclusive Events\n",
20 | " - Non-Mutually Exclusive Events\n",
21 | " - Intersection of Independent Events\n",
22 | " - Intersection of Dependent Events\n",
23 | "- Expected Value \n",
24 | "\n",
25 | "If you're interested in tackling statistics with Python, consider DataCamp's [Statistical Thinking in Python](https://www.datacamp.com/courses/statistical-thinking-in-python-part-1) course. \n",
26 | "\n",
27 | "## Personal Motivation \n",
28 | "\n",
29 | "For several years, beginning in 2010 I made a living playing online poker professionally. Data Science was a natural progression for me as it requires a similar skill-set as earning a profit from online poker. I wrote a blog about [what data science has in common with poker](https://medium.springboard.com/how-i-used-professional-poker-to-become-a-data-scientist-e49b75dfe8e3), and I mentioned that each time a poker hand is played at an online poker site, a hand history is generated. These hand histories explain everything that each player did during that hand. I used software called [Hold’em Manager](https://holdemmanager.com/?a_aid=sharpdata) (think Tableau for poker) to take advantage of this data. Hold'em Manager downloads each of these hand histories in real-time to a PostgreSQL database so you can keep track of your opponent’s tendencies."
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "\n",
37 | "## Probability Theory: An Introduction\n",
38 | "\n",
39 | "Before you get your hands dirty, it's time to consider what probability theory is and why it's important to learn about it when you're getting into data science. Additionally, you'll learn some key concepts that will be handy to consider throughout the tutorial and you'll learn how to calculate the probability of single events.\n",
40 | "\n",
41 | "You'll often wonder in real-life situations what the probabilities are of some event occurring, such as winning the lottery, the victory of your soccer team or a discount on your favorite pair of shoes. \"What are the chances...\" is an expression you probably use very often. Determining the chances of an event occurring is called \"probability\". \n",
42 | "\n",
43 | "This type of probability is different from the mathematical way of looking at probability, which you can find in probability theory, a branch of mathematics. And in mathematics, you have two broad categories of interpretations on \"probability\" is - the \"physical\" and \"evidential\" probabilities. \n",
44 | "\n",
45 | "The former are also called objective or frequency probabilities and are associated with random physical systems such as flipping coins, roulette wheels, or rolling dice. In such systems, a given type of event tends to occur at a persistent rate, or \"relative frequency\", in a long run of trials. \n",
46 | "\n",
47 | "The latter is also called Bayesian probability, which can be assigned to any statement whatsoever, even when no random process is involved, as a way to represent its subjective plausibility, or the degree to which the statement is supported by the available evidence. On most accounts, evidential probabilities are considered to be degrees of belief, defined in terms of dispositions to gamble at certain odds. \n",
48 | "\n",
49 | "**Note** that probability theory is mainly concerned with predicting the likelihood of future events, while statistics analyzes the frequency of past events. This also explains why probability theory is also one of the core topics that you should cover if you want to become a data scientist: as you well know, in data science and machine learning, you'll use data from events that have already occurred to predict future events.\n",
50 | "\n",
51 | "So while probability theory is generally considered to be hard to understand intuitively, the concepts are crucial to data science and predictive analytics. \n",
52 | "\n",
53 | "### Key Concepts and Symbols\n",
54 | "\n",
55 | "Some key concepts that you should probably be aware of for this tutorial are mostly concerned with the frequentist perspective on probability, as this tutorial works with a deck of 52 playing cards. \n",
56 | "\n",
57 | "From that perspective, the fundamental ingredient of probability theory is an *experiment* that can be repeated, at least hypothetically, under essentially identical conditions. This experiment may lead to different outcomes on different *trials* or single performances of an experiment. The set of all possible *outcomes* or results of an experiment is then called a \"*sample space*\". An *event* is a well-defined subset of the sample space. \n",
58 | "\n",
59 | "This is all very theoretical. \n",
60 | "\n",
61 | "Let's consider some examples:\n",
62 | "\n",
63 | "- A somewhat cliché example would be flipping a coin. In this case, the experiment is, in fact, the flipping of a coin. You can toss the coin multiple times, and all these trials might have different outcomes. As there are two possible outcomes -heads or tails- the sample space is 2. However, the event \"tossing a coin\" can, for example, consist of one outcome \"Heads\". Similarly, when you toss a coin twice, your event \"the first toss results in a Heads\" might have an outcome \"Heads-Heads\" or \"Heads-Tails\".\n",
64 | "\n",
65 | "\n",
66 | "- Another example that is maybe less straightforward is an experiment where you spin a globe and you stop it by putting your finger on it. You can spin the globe multiple times and all these times might have different outcomes - You can either land your finger on land or on water. That means that the sample space is 2. An event \"my finger is on land\" might have an outcome \"Land - Water\" or \"Land - Land\".\n",
67 | "\n",
68 | "\n",
69 | "- A last example is the experiment where you toss a die. You can toss the die multiple times and all of these throws can have different outcomes: 6 to be exact, since your die has 6 numbers (1,2,3,4,5,6). An event \"The sum of the results of the two toss is equal to 10\" can consist of 10, while the event \"the number is even\" can consist of 2, 4, or 6. \n",
70 | "\n",
71 | "Now that you have an idea of the key concepts that you'll be using throughout this tutorial, it's time to also consider some probability symbols that you will also encounter:\n",
72 | "\n",
73 | "|Symbol |Meaning\n",
74 | "|--------|----\n",
75 | "|$$\\cup$$|And \n",
76 | "|$$\\cap$$|Or \n",
77 | "|||Given\n",
78 | "\n",
79 | "\n",
80 | "### Calculating Probability For Single Events\n",
81 | "\n",
82 | "Now that you're completely up to date, you can start to determine the probability of a single event happenings, such as a coin landing on tails. To calculate this probability, you divide the number of possible event outcomes by the sample space. \n",
83 | "\n",
84 | "This means that you have to consider first how many possible ways there are for the coin to land on tails, and the number of possible outcomes. The former is 1, as you have only one possible way to get tails. The latter is 2, as you will either get heads or tails when you flip the coin.\n",
85 | "\n",
86 | "To summarize, the calculation of the probability of an event A will look something like this:"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "$$P(A) = \\frac{Event \\ outcomes \\ favorable \\ to \\ A}{Sample \\ space}$$"
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": [
100 | "In the case of the coin flipping, the probability of the coin landing on tails is 1/2 or 0.5. \n",
101 | "\n",
102 | "**Note** how the probability is always between 0 and 1, where 0 indicates that it's not very probable that the event will happen, where 1 indicates that it's probable that the event will happen. \n",
103 | "\n",
104 | "Now let's consider a second example in which you'll calculate the probability of an event. \n",
105 | "\n",
106 | "
\n",
107 | "\n",
108 | "There are 52 cards In a standard deck of cards and of those 52 cards, 4 are Aces. If you follow the example of the coin flipping from above to know the probability of drawing an Ace, you'll divide the number of possible event outcomes (4), by the sample space (52):"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "$$P(A) = \\frac{4}{52}$$\n",
116 | "\n",
117 | "**Note** how $A$ represents the event of \"drawing an Ace\".\n",
118 | "\n",
119 | "Now, determine the probability of drawing an Ace with the help of Python:"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": 1,
125 | "metadata": {},
126 | "outputs": [
127 | {
128 | "name": "stdout",
129 | "output_type": "stream",
130 | "text": [
131 | "0.08\n"
132 | ]
133 | }
134 | ],
135 | "source": [
136 | "# Sample Space\n",
137 | "cards = 52\n",
138 | "\n",
139 | "# Outcomes\n",
140 | "aces = 4\n",
141 | "\n",
142 | "# Divide possible outcomes by the sample set\n",
143 | "ace_probability = aces / cards\n",
144 | "\n",
145 | "# Print probability rounded to two decimal places\n",
146 | "print(round(ace_probability, 2))"
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "The probability of drawing an Ace from a standard deck is 0.08. To determine probability in percentage form, simply multiply by 100."
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": 2,
159 | "metadata": {},
160 | "outputs": [
161 | {
162 | "name": "stdout",
163 | "output_type": "stream",
164 | "text": [
165 | "8.0%\n"
166 | ]
167 | }
168 | ],
169 | "source": [
170 | "# Ace Probability Percent Code\n",
171 | "ace_probability_percent = ace_probability * 100\n",
172 | "\n",
173 | "# Print probability percent rounded to one decimal place\n",
174 | "print(str(round(ace_probability_percent, 0)) + '%')"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "The probability of drawing an Ace as a percent is 8%. \n",
182 | "\n",
183 | "Now that you have seen two examples where you calculated probabilities, it's easy to assume that you might build out your probability calculations to determine, for example, the probability of drawing a card that is a Heart, a face card (such as Jacks, Queens, or Kings), or a combination of both, such as a Queen of Hearts. \n",
184 | "\n",
185 | "In such cases, you might want to create a User-Defined Function (UDF) `event_probability()` to which you pass the `event_outcomes` and the `sample_space` to find the probability of an event in percentage form, since you'll be reusing a lot of the code: "
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": 3,
191 | "metadata": {},
192 | "outputs": [
193 | {
194 | "name": "stdout",
195 | "output_type": "stream",
196 | "text": [
197 | "25.0%\n",
198 | "23.1%\n",
199 | "1.9%\n"
200 | ]
201 | }
202 | ],
203 | "source": [
204 | "# Create function that returns probability percent rounded to one decimal place\n",
205 | "def event_probability(event_outcomes, sample_space):\n",
206 | " probability = (event_outcomes / sample_space) * 100\n",
207 | " return round(probability, 1)\n",
208 | "\n",
209 | "# Sample Space\n",
210 | "cards = 52\n",
211 | "\n",
212 | "# Determine the probability of drawing a heart\n",
213 | "hearts = 13\n",
214 | "heart_probability = event_probability(hearts, cards)\n",
215 | "\n",
216 | "# Determine the probability of drawing a face card\n",
217 | "face_cards = 12\n",
218 | "face_card_probability = event_probability(face_cards, cards)\n",
219 | "\n",
220 | "# Determine the probability of drawing the queen of hearts\n",
221 | "queen_of_hearts = 1\n",
222 | "queen_of_hearts_probability = event_probability(queen_of_hearts, cards)\n",
223 | "\n",
224 | "# Print each probability\n",
225 | "print(str(heart_probability) + '%')\n",
226 | "print(str(face_card_probability) + '%')\n",
227 | "print(str(queen_of_hearts_probability) + '%')"
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {},
233 | "source": [
234 | "These results probably don't surprise you: as you expected, the chances of drawing a Queen of Hearts are much smaller than the chances of drawing a regular face card or a Heart.\n",
235 | "\n",
236 | "\n",
237 | "## Probability with Combinations and Permutations\n",
238 | "\n",
239 | "You have seen in the previous section that determining the size of your sample space is key to calculating probabilities. However, this can sometimes prove to be a challenge!\n",
240 | "\n",
241 | "Fortunately, there are ways to make the counting task easier. Two of these ways are permutations and combinations. In this section, you'll see what both of these concepts exactly mean and how you can use them to calculate the size of your sample space! \n",
242 | "\n",
243 | "### Permutations\n",
244 | "\n",
245 | "Permutations are the number of ways a subset of a specified size can be arranged from a given set, generally without replacement. An example of this would be a 4 digit PIN with no repeated digits. The probability of having no repeated digits can be calculated by executing the following calculation:\n",
246 | "\n",
247 | "$$10 \\times 9 \\times 8 \\times 7$$.\n",
248 | "\n",
249 | "You have 10 numbers to choose from, but as you're working without replacement, one option always falls away as you pick a number for the 4-digit pin. This means that in picking the first number for your pin, you'll have 10 numbers to choose from (0 to 9), but for the second number of your pin, you'll only have 9 options to choose from, etc. \n",
250 | "\n",
251 | "On a higher level, you see that the previous paragraph actually considers two things: (1) the numbers to choose from, and (2) the numbers that you actually choose. In the example above, 10 is the number of digits that you can choose from, as you consider all numbers between 0 and 9. However, the actual number of things that you choose is 4, since you have a 4-digit pin. \n",
252 | "\n",
253 | "When calculating the permutations, this means that you consider the full set of the numbers to choose from, which is in reality $$10 \\times 9 \\times 8 \\times 7 \\times 6 \\times 5 \\times 4 \\times 3 \\times 2 \\times 1$$ and you divide the result of this calculation by the difference in the numbers to choose from (10) and the numbers that you actually choose (4). Since you're considering probabilities, this means that this difference will be $$6 \\times 5 \\times 4 \\times 3 \\times 2 \\times 1$$. \n",
254 | "\n",
255 | "**Note** that you can also write the above as \n",
256 | "\n",
257 | "$$10P4 = \\frac{10!}{(10 - 4)!}$$\n",
258 | "\n",
259 | "You'll notice that there is an \"10!\" and \"6!\" or \"10 factorial\" and \"6 factorial\" in the equation, which is used to indicate that all the consecutive positive integers from 1 up to and including 10 or 6 are to be multiplied together. \n",
260 | "\n",
261 | "The result of this calculation is 5040 permutations. **Note** how this is exactly the same as the calculation that you made above, when you multiplied 10, 9, 8 and 7.\n",
262 | "\n",
263 | "Generalizing the calculations above, this means that the formula to calculate permutations is the following:\n",
264 | "\n",
265 | "$$nPk = \\frac{n!}{(n - k)!}$$\n",
266 | "\n",
267 | "Let's practice this with an example!\n",
268 | "\n",
269 | "To find the number of permutations of pocket Aces, from which you only pick 2, you'll consider the full set of aces to choose from (4) and you also consider the number of aces that you actually choose (2):\n",
270 | "\n",
271 | "$$4P2 = \\frac{4!}{(4 - 2)!}$$\n",
272 | "\n",
273 | "### Combinations\n",
274 | "\n",
275 | "You have seen that when you're working with permutations, the order matters. With combinations, however, this isn't the case: the order doesn't matter. Combinations refers to the number of ways a subset of a specified size can be drawn from a given set. \n",
276 | "\n",
277 | "An example here is the following situation where you have your deck of cards, which consists of 52 cards. Three cards are going to be taken out of the deck. How many different ways can you choose these three cards?\n",
278 | "\n",
279 | "In fact, this should be $$52 \\times 51 \\times 50$$, which is actually the same as the permutations formula that you have just used! However, with combinations, you don't take the order into account. This means that if you want to figure out how many combinations you actually have, you just create all the permutations and divide by all the redundancies or $$3 \\times 2 \\times 1$$. \n",
280 | "\n",
281 | "This means that your calculation of the combinations will look like this:\n",
282 | "\n",
283 | "$$52C3 = \\frac{\\frac {52!}{(52-3)!}}{3!}$$\n",
284 | "\n",
285 | "This calculation can be generalized to the following formula:\n",
286 | "\n",
287 | "$$nCk = \\frac{nPk}{k!}$$\n",
288 | "\n",
289 | "Where you clearly see that the numerator is exactly the same formula as the permutations formula that you have just seen, while the denominator is the factorial of the number of cards that you will actually choose. \n",
290 | "\n",
291 | "Consider another example with Aces. There are four Aces in a deck of cards, and these are all the different combinations of pocket Aces;\n",
292 | "\n",
293 | "1. Ace Hearts / Ace Diamonds\n",
294 | "2. Ace Hearts / Ace Clubs\n",
295 | "3. Ace Hearts / Ace Spades\n",
296 | "4. Ace Diamonds / Ace Clubs\n",
297 | "5. Ace Diamonds / Ace Spades\n",
298 | "6. Ace Clubs / Ace Spades\n",
299 | "\n",
300 | "There are six combinations of pocket Aces. To find the number of combinations, you first must find the number of permutations:"
301 | ]
302 | },
303 | {
304 | "cell_type": "code",
305 | "execution_count": 4,
306 | "metadata": {},
307 | "outputs": [
308 | {
309 | "name": "stdout",
310 | "output_type": "stream",
311 | "text": [
312 | "12.0\n"
313 | ]
314 | }
315 | ],
316 | "source": [
317 | "# Permutations Code\n",
318 | "import math\n",
319 | "n = 4\n",
320 | "k = 2\n",
321 | "\n",
322 | "# Determine permutations and print result\n",
323 | "Permutations = math.factorial(n) / math.factorial(k)\n",
324 | "print(Permutations)"
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {},
330 | "source": [
331 | "To determine the number of combinations, simply divide the number of permutations by the factorial of the size of the subset. Try finding the number of starting hand combinations that can be dealt in Texas Hold’em.\n",
332 | "\n",
333 | "$$52C2 = \\frac{52P2}{2!}$$"
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": 5,
339 | "metadata": {},
340 | "outputs": [
341 | {
342 | "name": "stdout",
343 | "output_type": "stream",
344 | "text": [
345 | "1326.0\n"
346 | ]
347 | }
348 | ],
349 | "source": [
350 | "# Combinations Code\n",
351 | "n = 52\n",
352 | "k = 2\n",
353 | "\n",
354 | "# Determine Permutations\n",
355 | "Permutations = math.factorial(n) / math.factorial(n - k)\n",
356 | "\n",
357 | "# Determine Combinations and print result\n",
358 | "Combinations = Permutations / math.factorial(k)\n",
359 | "print(Combinations)"
360 | ]
361 | },
362 | {
363 | "cell_type": "markdown",
364 | "metadata": {},
365 | "source": [
366 | "\n",
367 | "## Independent versus Dependent Events\n",
368 | "\n",
369 | "You have read in the introduction that an event is a well-defined subset of the sample space. Events can be classified into two categories: dependent or independent.\n",
370 | "\n",
371 | "Independent events are events that don't impact the probability of the other event(s). Two events A and B are independent if knowing whether event A occurred gives no information about whether event B occurred. \n",
372 | "\n",
373 | "This is true when you, for example, draw an Ace from the deck, replace the card, shuffle the deck, and then drawing another card. The probability of drawing an Ace the first draw is the same as the second. \n",
374 | "\n",
375 | "Dependent events, then, are events that have an impact on the probability of the other event(s). \n",
376 | "\n",
377 | "For example, you draw a card from the deck and then draw a second card from the deck without replacing the first card. In this case, the probability of drawing an Ace the fist draw is not the same as the probability of drawing an Ace on the second draw. After the first card is drawn, the sample space has reduced by 1, from 52 to 51. Depending on what the card was on the first draw, the number of event outcomes may have also changed. If the card was an Ace, there are now only 3 Aces remaining for the second draw.\n",
378 | "\n",
379 | "Let's consider these definitions in formal terms now. Events A and B (which have nonzero probability) are independent if one of the following equivalent statements holds:\n",
380 | "$$P (A ∩ B) = P(A)P(B)$$\n",
381 | "$$P (A|B) = P(A)$$\n",
382 | "$$P (B|A) = P(B)$$\n",
383 | "\n",
384 | "Or, in other words, events A and B are independent if:\n",
385 | "
\n",
386 | "- The probability of events A and B to occur equals the product of the probabilities of each event occurring.
\n",
387 | "
This is for example the case when you put your finger on a spinning globe: the chances of your finger landing on land has a probability of $0.7$ because about 70% of the earth is made out of land. This makes the chances of landing three times on land is $0.7 \\times 0.7 \\times 0.7$.
\n",
388 | "\n",
389 | "- the probability of event A to occur if an event B has already occurred is equal to the probability of an event A to occur.
\n",
390 | "
This is also true for the globe example that you read about earlier: the chances of landing twice on land and once on water $0.7 \\times 0.7 \\times 0.3$. The probabilities for landing on water or land don't change each time you spin the globe, even if you have done it before.
\n",
391 | "\n",
392 | "- The probability of an event B to occur if an event A has already occurred is the same as the probability of an event B to occur.
\n",
393 | "
This is also true for the globe example that you read about earlier: the chances of landing twice on water and once on land $0.3 \\times 0.3 \\times 0.7$. Once again, the individual probabilities for landing on water or land don't change each time you spin the globe, regardless of whether you have already done that action before or not.
\n",
394 | "\n",
395 | "Let's consider the following example, where you already know the probability of drawing an Ace on the first draw. Now you need to determine the probability of drawing an Ace on the second draw, if the first card drawn was either a King or an Ace:"
396 | ]
397 | },
398 | {
399 | "cell_type": "code",
400 | "execution_count": 6,
401 | "metadata": {},
402 | "outputs": [
403 | {
404 | "name": "stdout",
405 | "output_type": "stream",
406 | "text": [
407 | "7.8\n",
408 | "5.9\n"
409 | ]
410 | }
411 | ],
412 | "source": [
413 | "# Sample Space\n",
414 | "cards = 52\n",
415 | "cards_drawn = 1 \n",
416 | "cards = cards - cards_drawn \n",
417 | "\n",
418 | "# Determine the probability of drawing an Ace after drawing a King on the first draw\n",
419 | "aces = 4\n",
420 | "ace_probability1 = event_probability(aces, cards)\n",
421 | "\n",
422 | "# Determine the probability of drawing an Ace after drawing an Ace on the first draw\n",
423 | "aces_drawn = 1\n",
424 | "aces = aces - aces_drawn\n",
425 | "ace_probability2 = event_probability(aces, cards)\n",
426 | "\n",
427 | "# Print each probability\n",
428 | "print(ace_probability1)\n",
429 | "print(ace_probability2)"
430 | ]
431 | },
432 | {
433 | "cell_type": "markdown",
434 | "metadata": {},
435 | "source": [
436 | "There are a few situations common to poker which are relevant to the concept of dependent events. \n",
437 | "\n",
438 | "But before you get started, a little background info is in order. The game is Texas Hold’em. Played with a standard 52 card deck, Texas Hold’em is the most popular of all the poker variations. Each player is dealt two cards to start the hand and will make the best five-card hand possible by using their two cards combined with the five community cards that are dealt throughout the hand. Cards are dealt in four rounds:\n",
439 | "\n",
440 | "- Pre-Flop: Each player is dealt two cards, known as \"hole cards\"\n",
441 | "- Flop: Three community cards are dealt\n",
442 | "- Turn: One community card is dealt\n",
443 | "- River: Final community card is dealt\n",
444 | "\n",
445 | "#### Dependent Events: Flush Draw\n",
446 | "\n",
447 | "**Your Hand**\n",
448 | "\n",
449 | "
\n",
450 | "\n",
451 | "\n",
452 | "**Community Cards**\n",
453 | "\n",
454 | "
\n",
455 | "\n",
456 | "\n",
457 | "Your on the Turn and you have four cards to an Ace high Flush. A Flush is a strong poker hand where all five cards are the same suit. What's the probability that the last community card, known as the River Card, is a Diamond?"
458 | ]
459 | },
460 | {
461 | "cell_type": "code",
462 | "execution_count": 7,
463 | "metadata": {},
464 | "outputs": [
465 | {
466 | "name": "stdout",
467 | "output_type": "stream",
468 | "text": [
469 | "19.6\n"
470 | ]
471 | }
472 | ],
473 | "source": [
474 | "# Sample Space\n",
475 | "cards = 52\n",
476 | "hole_cards = 2\n",
477 | "turn_community_cards = 4\n",
478 | "cards = cards - (hole_cards + turn_community_cards)\n",
479 | "\n",
480 | "# Outcomes\n",
481 | "diamonds = 13\n",
482 | "diamonds_drawn = 4\n",
483 | "# In poker, cards that complete a draw are known as \"outs\"\n",
484 | "outs = diamonds - diamonds_drawn\n",
485 | "\n",
486 | "#Determine river flush probability\n",
487 | "river_flush_probability = event_probability(outs, cards)\n",
488 | "print(river_flush_probability)"
489 | ]
490 | },
491 | {
492 | "cell_type": "markdown",
493 | "metadata": {},
494 | "source": [
495 | "There is roughly a 20% chance of hitting your Flush draw on the River. Here’s another one:\n",
496 | "\n",
497 | "#### Dependent Events: Open Ended Straight Draw\n",
498 | "\n",
499 | "**Your Hand**\n",
500 | "\n",
501 | "
\n",
502 | "\n",
503 | "**Community Cards**\n",
504 | "\n",
505 | "
\n",
506 | "\n",
507 | "Your on the Turn and you have an open ended Straight draw. A Straight is another strong hand where there are five cards in sequential order. The Straight draw is open ended because any Eight ( 8, 9, 10, Jack, Queen) or any King (9, 10, Jack, Queen, King) will complete the straight. \n",
508 | "\n",
509 | "What's the probability that the River card completes the Straight?"
510 | ]
511 | },
512 | {
513 | "cell_type": "code",
514 | "execution_count": 8,
515 | "metadata": {},
516 | "outputs": [
517 | {
518 | "name": "stdout",
519 | "output_type": "stream",
520 | "text": [
521 | "17.4\n"
522 | ]
523 | }
524 | ],
525 | "source": [
526 | "# Sample Space\n",
527 | "cards = 52\n",
528 | "hole_cards = 2\n",
529 | "turn_community_cards = 4\n",
530 | "cards = cards - (hole_cards + turn_community_cards)\n",
531 | "\n",
532 | "# Outcomes\n",
533 | "eights = 4\n",
534 | "kings = 4\n",
535 | "outs = eights + kings\n",
536 | "\n",
537 | "# Determine river straight probability\n",
538 | "river_straight_probability = event_probability(outs, cards)\n",
539 | "print(river_straight_probability)"
540 | ]
541 | },
542 | {
543 | "cell_type": "markdown",
544 | "metadata": {},
545 | "source": [
546 | "There is roughly a 17% chance of hitting your Straight draw on the River.\n",
547 | "\n",
548 | "\n",
549 | "## Multiple Events\n",
550 | "\n",
551 | "Up until now, you considered only one event when you were calculating the probabilities, but what when you are dealing with multiple events? \n",
552 | "\n",
553 | "An example of multiple events is the question \"what is the probability of eating three oatmeal cookies followed by a chocolate chip cookie when you eat four cookies out of a cookie jar filled with these two types of cookies?\". The assumption in this example is that you always put back a cookie after you ate one. \n",
554 | "\n",
555 | "To calculate the probability for multiple events, you basically determine the number of events (4 in this case, since you eat 4 cookies), you then determine the probability for each event occurring separately and you multiply all of these probabilities to get your final answer. In the example that was described above, this would be $$0.5 \\times 0.5 \\times 0.5 \\times 0.5$$ or 0.0625. \n",
556 | "\n",
557 | "$$P(Event A \\cap Event B)=P(Event A) \\times P(Event A)$$ \n",
558 | "\n",
559 | "**Note** that in this case, you calculate the probabilities of eating an oatmeal cookie AND another oatmeal cookie AND a third oatmeal, AND a last chocolate chip cookie. When you're considering events that all have to happen, you multiply the probabilities.\n",
560 | "\n",
561 | "For your deck of playing cards, you could ask yourself the question \"What is the probability of getting three Hearts when choosing without replacement?\". When you sample or choose without replacement, it means that you choose a card but do not put it back, so that your final selection cannot include that same card. Note that this also means that your events aren't independent! In this case, your probability calculation will be the following: $$13/52 \\times 12/51 \\times 11/50$$. \n",
562 | "\n",
563 | "### Mutually Exclusive Events\n",
564 | "\n",
565 | "When you're working with multiple events, you might also have events that are mutually exclusive or disjoint: they cannot both occur. In such cases, you might want to calculate the probability (or the union) of any of multiple mutually exclusive events occurring. In such cases, you don't multiply probabilities, but you simply add together the probability of each event occurring:\n",
566 | "\n",
567 | "$$P(Event A \\cup Event B) = P(Event A) + P(Event B)$$\n",
568 | "\n",
569 | "It's key here to understand that the \"OR\" component is very important: drawing a heart OR drawing a club are two mutually exclusive events. A heart is a heart and a club is a club. To determine the probability of drawing a heart or drawing a club, add the probability of drawing a heart to the probability of drawing a club.\n",
570 | "\n",
571 | "$$P(Heart \\cup Club) = (\\frac{13}{52}) \\times (\\frac{13}{52})$$\n",
572 | "\n",
573 | "Now it's time for you to determine the probability of the following mutually exclusive events;\n",
574 | "\n",
575 | "1. Drawing a heart or drawing a club;\n",
576 | "2. Drawing an ace, a king or a queen."
577 | ]
578 | },
579 | {
580 | "cell_type": "code",
581 | "execution_count": 9,
582 | "metadata": {},
583 | "outputs": [
584 | {
585 | "name": "stdout",
586 | "output_type": "stream",
587 | "text": [
588 | "50.0\n",
589 | "23.1\n"
590 | ]
591 | }
592 | ],
593 | "source": [
594 | "# Sample Space\n",
595 | "cards = 52\n",
596 | "\n",
597 | "# Calculate the probability of drawing a heart or a club\n",
598 | "hearts = 13\n",
599 | "clubs = 13\n",
600 | "heart_or_club = event_probability(hearts, cards) + event_probability(clubs, cards)\n",
601 | "\n",
602 | "# Calculate the probability of drawing an ace, king, or a queen\n",
603 | "aces = 4\n",
604 | "kings = 4\n",
605 | "queens = 4\n",
606 | "ace_king_or_queen = event_probability(aces, cards) + event_probability(kings, cards) + event_probability(queens, cards)\n",
607 | "\n",
608 | "print(heart_or_club)\n",
609 | "print(ace_king_or_queen)"
610 | ]
611 | },
612 | {
613 | "cell_type": "markdown",
614 | "metadata": {},
615 | "source": [
616 | "### Non-Mutually Exclusive Events\n",
617 | "\n",
618 | "You can imagine that not all events are mutually exclusive: Drawing a heart or drawing an ace are two non-mutually exclusive events. The ace of hearts is both an ace and a heart. When events are not mutually exclusive, you must correct for the overlap.\n",
619 | "\n",
620 | "$$P(Event A \\cup Event B) = P(Event A) + P(Event B) - P(EventA \\cup EventB)$$\n",
621 | "\n",
622 | "To calculate the probability of drawing a heart or an ace, add the probability of drawing a heart to the probability of drawing an ace and then subtract the probability of drawing the ace of hearts.\n",
623 | "\n",
624 | "$$P(Heart \\cup Ace) = (\\frac{13}{52}) + (\\frac{4}{52}) - (\\frac{1}{52})$$\n",
625 | "\n",
626 | "Calculate the probability of the following non mutually exclusive events;\n",
627 | "\n",
628 | "1. Drawing a heart or an ace;\n",
629 | "2. Drawing a red card or drawing a face card."
630 | ]
631 | },
632 | {
633 | "cell_type": "code",
634 | "execution_count": 10,
635 | "metadata": {},
636 | "outputs": [
637 | {
638 | "name": "stdout",
639 | "output_type": "stream",
640 | "text": [
641 | "30.8\n",
642 | "61.6\n"
643 | ]
644 | }
645 | ],
646 | "source": [
647 | "# Sample Space\n",
648 | "cards = 52\n",
649 | "\n",
650 | "# Calculate the probability of drawing a heart or an ace\n",
651 | "hearts = 13\n",
652 | "aces = 4\n",
653 | "ace_of_hearts = 1\n",
654 | "heart_or_ace = event_probability(hearts, cards) + event_probability(aces, cards) - event_probability(ace_of_hearts, cards)\n",
655 | "\n",
656 | "# Calculate the probability of drawing a red card or a face card\n",
657 | "red_cards = 26\n",
658 | "face_cards = 12\n",
659 | "red_face_cards = 6\n",
660 | "red_or_face_cards = event_probability(red_cards, cards) + event_probability(face_cards, cards) - event_probability(red_face_cards, cards)\n",
661 | "\n",
662 | "print(round(heart_or_ace, 1))\n",
663 | "print(round(red_or_face_cards, 1))"
664 | ]
665 | },
666 | {
667 | "cell_type": "markdown",
668 | "metadata": {},
669 | "source": [
670 | "### Intersection of Independent Events\n",
671 | "\n",
672 | "The probability of the intersection of two independent events is determined by multiplying the probabilities of each event occurring.\n",
673 | "\n",
674 | "$$P(Event A \\cap Event B) = P(Event A) \\times P(Event B)$$\n",
675 | "\n",
676 | "If you want to know the probability of drawing an Ace from a deck of cards, replacing it, reshuffling the deck, and drawing another Ace, you multiply the probability of drawing and Ace times the probability of drawing an Ace.\n",
677 | "\n",
678 | "$$P(Ace \\cap Ace) = (\\frac{4}{52}) \\times (\\frac{4}{52})$$"
679 | ]
680 | },
681 | {
682 | "cell_type": "code",
683 | "execution_count": 11,
684 | "metadata": {},
685 | "outputs": [
686 | {
687 | "name": "stdout",
688 | "output_type": "stream",
689 | "text": [
690 | "0.6\n"
691 | ]
692 | }
693 | ],
694 | "source": [
695 | "# Sample Space\n",
696 | "cards = 52\n",
697 | "\n",
698 | "# Outcomes\n",
699 | "aces = 4\n",
700 | "\n",
701 | "# Probability of one ace\n",
702 | "ace_probability = aces / cards\n",
703 | "\n",
704 | "# Probability of two consecutive independant aces \n",
705 | "two_aces_probability = ace_probability * ace_probability\n",
706 | "\n",
707 | "# Two Ace Probability Percent Code\n",
708 | "two_ace_probability_percent = two_aces_probability * 100\n",
709 | "print(round(two_ace_probability_percent, 1))"
710 | ]
711 | },
712 | {
713 | "cell_type": "markdown",
714 | "metadata": {},
715 | "source": [
716 | "The probability of drawing two Aces in a row, independently, is 0.592%. What if the second event is dependant?\n",
717 | "\n",
718 | "### Intersection of Dependent Events\n",
719 | "\n",
720 | "The probability of the intersection of two non independent events (Event A & Event B given A) is determined by multiplying the probability of Event A occurring times the probability of Event B given A. \n",
721 | "\n",
722 | "$$P(Event A \\cap Event B | A) = P(Event A) \\times P(Event B | A)$$\n",
723 | "\n",
724 | "The best starting hand you can have in Texas Hold’em is pocket Aces. What is the probability of being dealt two Aces?\n",
725 | "\n",
726 | "$$P(Ace \\cap Ace | Ace) = (\\frac{4}{52}) \\times (\\frac{3}{51})$$\n"
727 | ]
728 | },
729 | {
730 | "cell_type": "code",
731 | "execution_count": 12,
732 | "metadata": {},
733 | "outputs": [
734 | {
735 | "name": "stdout",
736 | "output_type": "stream",
737 | "text": [
738 | "0.4524886877828055\n"
739 | ]
740 | }
741 | ],
742 | "source": [
743 | "# Sample Space first draw\n",
744 | "cards = 52\n",
745 | "\n",
746 | "# Outcomes first draw\n",
747 | "aces = 4\n",
748 | "\n",
749 | "# Probability of ace on first draw\n",
750 | "first_ace_probability = aces / cards\n",
751 | "\n",
752 | "# Sample Space second draw\n",
753 | "cards = cards - 1\n",
754 | "\n",
755 | "# Outcomes second draw\n",
756 | "aces = aces - 1\n",
757 | "\n",
758 | "# Probability of ace on second draw after ace on first\n",
759 | "second_ace_probability = aces / cards\n",
760 | "\n",
761 | "# Probability of two consecutive aces (dependent)\n",
762 | "both_aces_probability = first_ace_probability * second_ace_probability * 100\n",
763 | "print(both_aces_probability)"
764 | ]
765 | },
766 | {
767 | "cell_type": "markdown",
768 | "metadata": {},
769 | "source": [
770 | "The probability of drawing two dependent Aces in a row is 0.452%. Let's take a look at a couple situations where this comes into play at the poker table.\n",
771 | "\n",
772 | "#### Intersection of Dependent Events: Flop Flush Draw\n",
773 | "\n",
774 | "**Your Hand**\n",
775 | "\n",
776 | "
\n",
777 | "\n",
778 | "**Community Cards**\n",
779 | "\n",
780 | "
\n",
781 | "\n",
782 | "\n",
783 | "This is a similar situation as the Flush draw above, except this time you're on the flop and have two more community cards to come instead of just one. How can you determine the probability of getting a Flush by the River? First you need to determine all the different possible scenarios;\n",
784 | "\n",
785 | "- A) Turn Diamond, River Non Diamond (Made Flush)\n",
786 | "- B) Turn Non Diamond, River Diamond (Made Flush)\n",
787 | "- C) Turn Diamond, River Diamond (Made Flush)\n",
788 | "- D) Turn Non Diamond, River Non Diamond (No Flush)\n",
789 | "\n",
790 | "Those are the only four possibilities, and each of those scenarios are mutually exclusive. This means that if you add the probabilities of each of those scenarios occurring, the total will be 1. In other words, one of those four scenarios is definitely going to occur. You want to know the probability of scenario A, B, or C occurring. The simplest approach to figure this out is to determine the probability of scenario D, and subtract that from 1."
791 | ]
792 | },
793 | {
794 | "cell_type": "code",
795 | "execution_count": 13,
796 | "metadata": {},
797 | "outputs": [
798 | {
799 | "name": "stdout",
800 | "output_type": "stream",
801 | "text": [
802 | "38.4\n"
803 | ]
804 | }
805 | ],
806 | "source": [
807 | "# Sample Space on turn\n",
808 | "cards = 52\n",
809 | "hole_cards = 2\n",
810 | "flop_community_cards = 3\n",
811 | "cards = cards - (hole_cards + flop_community_cards)\n",
812 | "\n",
813 | "# Outcomes\n",
814 | "diamonds = 13\n",
815 | "diamonds_drawn = 4\n",
816 | "non_diamonds_drawn = 1\n",
817 | "outs = diamonds - diamonds_drawn\n",
818 | "turn_non_diamonds = cards - outs - non_diamonds_drawn \n",
819 | "\n",
820 | "# Probability of not getting a diamond on the turn\n",
821 | "no_diamond_turn_probability = turn_non_diamonds / cards\n",
822 | "\n",
823 | "# Sample Space on river\n",
824 | "turn_community_card = 1\n",
825 | "cards = cards - turn_community_card\n",
826 | "\n",
827 | "# Outcomes on river\n",
828 | "river_non_diamonds = turn_non_diamonds - turn_community_card\n",
829 | "\n",
830 | "# Probability of not getting a diamond on the river\n",
831 | "no_diamond_river_probability = river_non_diamonds / cards\n",
832 | "\n",
833 | "# Probability of not getting a flush\n",
834 | "no_flush_probability = no_diamond_turn_probability * no_diamond_river_probability\n",
835 | "\n",
836 | "# Probability of getting a flush\n",
837 | "flush_probability = 1 - no_flush_probability\n",
838 | "flush_probability_percent = flush_probability * 100\n",
839 | "\n",
840 | "# Print probability percent rounded to one decimal place\n",
841 | "print(round(flush_probability_percent, 1))"
842 | ]
843 | },
844 | {
845 | "cell_type": "markdown",
846 | "metadata": {},
847 | "source": [
848 | "Now let's change the hand slightly:\n",
849 | "\n",
850 | "**Your Hand**\n",
851 | "\n",
852 | "
\n",
853 | "\n",
854 | "**Community Cards**\n",
855 | "\n",
856 | "
\n",
857 | "\n",
858 | "This is a similar situation as the last one, except for one big difference. You still have a flush draw, but this time you don’t have the Ace. If a Diamond falls on the turn and the river, there is a good chance someone will have a better flush draw. Determine the probability of a Diamond falling on the Turn or the River, but not both. You already have the probability of not hitting a flush. \n",
859 | "\n",
860 | "Now find the probability of a diamond falling on the turn and river, add that to the probability of not hitting a flush, and subtract from 1."
861 | ]
862 | },
863 | {
864 | "cell_type": "code",
865 | "execution_count": 14,
866 | "metadata": {},
867 | "outputs": [
868 | {
869 | "name": "stdout",
870 | "output_type": "stream",
871 | "text": [
872 | "35.1\n"
873 | ]
874 | }
875 | ],
876 | "source": [
877 | "# Sample Space on turn\n",
878 | "cards = 52\n",
879 | "hole_cards = 2\n",
880 | "flop_community_cards = 3\n",
881 | "cards = cards - (hole_cards + flop_community_cards)\n",
882 | "\n",
883 | "# Outcomes on turn\n",
884 | "diamonds = 13\n",
885 | "diamonds_drawn = 4\n",
886 | "outs = diamonds - diamonds_drawn\n",
887 | "\n",
888 | "# Probability of diamond on turn\n",
889 | "diamond_turn_probability = outs / cards\n",
890 | "\n",
891 | "# Sample Space on river\n",
892 | "turn_diamonds = 1\n",
893 | "cards = cards - turn_diamonds\n",
894 | "\n",
895 | "# Outcomes on river\n",
896 | "river_diamonds = outs - turn_diamonds\n",
897 | "\n",
898 | "# Probability of diamond on river\n",
899 | "diamond_river_probability = river_diamonds / cards\n",
900 | "\n",
901 | "# Probability of getting a diamond on the turn and river\n",
902 | "two_diamonds_probability = diamond_turn_probability * diamond_river_probability\n",
903 | "\n",
904 | "# Determine the probability of getting only one diamond by the river\n",
905 | "one_diamond_probability = 1 - (no_flush_probability + two_diamonds_probability)\n",
906 | "one_diamond_probability_percent = one_diamond_probability * 100\n",
907 | "\n",
908 | "# Print probability percent rounded to one decimal place\n",
909 | "print(round(one_diamond_probability_percent, 1))"
910 | ]
911 | },
912 | {
913 | "cell_type": "markdown",
914 | "metadata": {},
915 | "source": [
916 | "\n",
917 | "## Expected Value\n",
918 | "\n",
919 | "When playing a game such as poker, you're fairly concerned with questions such as \"how much do I gain - or lose - on average, if I repeatedly play this game?\". You can imagine that this is no different for poker, especially when you're a professional poker player! \n",
920 | "\n",
921 | "Now, if the possible outcomes of the game and their associated probabilities can be described by a random variable, then you can answer the above question by computing its **expected value**, which is equal to a weighted average of the outcomes where each outcome is weighted by its probability.\n",
922 | "\n",
923 | "Or, in other words, you simply multiply the Total Value times the probability of winning to get your Expected Value:\n",
924 | "\n",
925 | "$$Expected Value = Total Value \\times Probability$$\n",
926 | "\n",
927 | "What is the expected value if there is \\$100 (Total Value) in the pot, and your probability of winning the pot is 0.75?\n",
928 | "\n",
929 | "$$Expected Value = \\$100 \\times 0.75$$"
930 | ]
931 | },
932 | {
933 | "cell_type": "code",
934 | "execution_count": 15,
935 | "metadata": {},
936 | "outputs": [
937 | {
938 | "name": "stdout",
939 | "output_type": "stream",
940 | "text": [
941 | "75.0\n"
942 | ]
943 | }
944 | ],
945 | "source": [
946 | "# Initialize `pot` and `probability` variables\n",
947 | "pot = 100\n",
948 | "probability = 0.75\n",
949 | "\n",
950 | "# Determine expected value\n",
951 | "expected_value = pot * probability\n",
952 | "print(expected_value)"
953 | ]
954 | },
955 | {
956 | "cell_type": "markdown",
957 | "metadata": {},
958 | "source": [
959 | "You're expected value is \\$75. Expected value is an important concept in poker. Let’s go back to the first flush example to see how to use expected values to your advantage.\n",
960 | "\n",
961 | "##### Your Hand\n",
962 | "\n",
963 | "
\n",
964 | "\n",
965 | "\n",
966 | "##### Opponents Hand\n",
967 | "\n",
968 | "
\n",
969 | "\n",
970 | "##### Community Cards\n",
971 | "\n",
972 | "
\n",
973 | "\n",
974 | "- Total Pot = \\$60\n",
975 | "\n",
976 | "- Opponents Bet = \\$20\n",
977 | "\n",
978 | "Your opponent has decided to be helpful and show you his cards, and has a set of 2s. To win the hand on the River, you must hit any Diamond except a Jack or 2. The Jack or 2 of Diamonds would give your opponent a better hand, a full house and four of a kind respectively. You have to call \\$20 to stay in the hand, and if you win the hand you win \\$60. If your expected value is greater than \\$20 you should call the bet, and if not you should fold. \n",
979 | "\n",
980 | "Figure out if you should call the bet: "
981 | ]
982 | },
983 | {
984 | "cell_type": "code",
985 | "execution_count": 16,
986 | "metadata": {},
987 | "outputs": [
988 | {
989 | "name": "stdout",
990 | "output_type": "stream",
991 | "text": [
992 | "9.55 Fold\n"
993 | ]
994 | }
995 | ],
996 | "source": [
997 | "# Sample Space\n",
998 | "cards = 52\n",
999 | "hole_cards = 2\n",
1000 | "# Your opponent provided you information... use it!\n",
1001 | "opponents_hole_cards = 2 \n",
1002 | "\n",
1003 | "turn_community_cards = 4\n",
1004 | "cards = cards - (hole_cards + opponents_hole_cards + turn_community_cards)\n",
1005 | "\n",
1006 | "# Outcomes\n",
1007 | "diamonds = 13\n",
1008 | "diamonds_drawn = 4\n",
1009 | "\n",
1010 | "# You can't count the two diamonds that won't help you win\n",
1011 | "diamond_non_outs = 2 \n",
1012 | "\n",
1013 | "outs = diamonds - diamonds_drawn - diamond_non_outs\n",
1014 | "\n",
1015 | "# Determine win probability\n",
1016 | "win_probability = outs / cards\n",
1017 | "\n",
1018 | "# Determine expected value\n",
1019 | "pot = 60\n",
1020 | "ev = pot * win_probability\n",
1021 | "\n",
1022 | "# Print ev and appropriate decision\n",
1023 | "call_amount = 20\n",
1024 | "if ev >= 20:\n",
1025 | " print(round(ev, 2), 'Call')\n",
1026 | "else:\n",
1027 | " print(round(ev, 2), 'Fold')"
1028 | ]
1029 | },
1030 | {
1031 | "cell_type": "markdown",
1032 | "metadata": {},
1033 | "source": [
1034 | "Your expected value is only \\$9.55, which is less than the \\$20 you would need to risk to get that reward, so you must fold. Determining Expected Value is critical to understand at the poker table and Part 2 will dig much deeper into the concept.\n",
1035 | "\n",
1036 | "## Conclusion\n",
1037 | "\n",
1038 | "Congrats, you have made it to the end of this tutorial on probability theory with Python! This concludes Part 1 of the tutorial. You learned about several core probability concepts including Independent/Dependent events, Permutations/Combinations, Multiple events, Expected Values, and how to calculate each of them. \n",
1039 | "\n",
1040 | "In Part 2, you will apply these concepts to actual poker hands that I played during my career.\n",
1041 | "\n",
1042 | "\\*One card is dealt face down, known as the Burn card, before the Flop, Turn, and River. Since the card is dealt face down, and no player knows what it is, it does not count as a trial."
1043 | ]
1044 | }
1045 | ],
1046 | "metadata": {
1047 | "anaconda-cloud": {},
1048 | "kernelspec": {
1049 | "display_name": "Python 3",
1050 | "language": "python",
1051 | "name": "python3"
1052 | },
1053 | "language_info": {
1054 | "codemirror_mode": {
1055 | "name": "ipython",
1056 | "version": 3
1057 | },
1058 | "file_extension": ".py",
1059 | "mimetype": "text/x-python",
1060 | "name": "python",
1061 | "nbconvert_exporter": "python",
1062 | "pygments_lexer": "ipython3",
1063 | "version": "3.6.0"
1064 | }
1065 | },
1066 | "nbformat": 4,
1067 | "nbformat_minor": 1
1068 | }
1069 |
--------------------------------------------------------------------------------
/Poker Probability and Statistics Teaser.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Poker Probability and Statistics\n",
8 | "\n",
9 | "For several years, beginning in 2010 I made a living playing online poker professionally. Data Science was a natural progression for me as it requires a similar skill-set as earning a profit at online poker. I wrote a blog about [what data analysis has in common with poker](https://medium.springboard.com/how-i-used-professional-poker-to-become-a-data-scientist-e49b75dfe8e3), and I mentioned that each time a poker hand is played at an online poker site, a hand history is generated that explains everything that each player did during the hand. I used software called [Hold’em Manager](https://holdemmanager.com/?a_aid=sharpdata) (think Tableau for poker), which downloads each of these hand histories in real time to a PostgreSQL database so you can keep track of your opponent’s tendencies. \n",
10 | "\n",
11 | "Before we get started, a little background info is in order. The game is No Limit Texas Hold’em, and if you’ve never played or are unfamiliar with poker terminology you can [click here](https://www.pokernews.com/poker-rules/texas-holdem.htm) for a concise but detailed explanation. In the business world, Data Science is used to make predictions and optimize decisions by creating machine learning models. In online poker, the decision that needs to be made is whether to bet, call, or fold, but you aren’t allowed to use software to make that decision for you. At most online poker sites, that is where the line is drawn in the rules. This means that the model that must be trained is your brain, and the training is done away from the table with an endless stream of equity calculations. \n",
12 | "\n",
13 | "Anytime I ran into a situation while playing that confused me, I would mark the hand for review later. After my poker playing session was done, I'd go back through the hands that I'd marked for review and break them down mathematically so I'd have a better idea of what to do in each situation the next time it arose. I picked out five hands from my poker career. Using the statistics on my opponents that I had available at the time, I’ll explain my thought process. Then you can analyze the hand using Python to determine which of your options offers the highest expected value.\n",
14 | "\n",
15 | "**Note**: *When reviewing poker hands, it is common to refer to our opponent as the \"Villain\" and ourselves as the \"Hero.\"*"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "## Hand 1 Overview:\n",
23 | "\n",
24 | "\n",
25 | "\n",
26 | "- Hero bet 0.85 (Hero has 20.95 remaining);\n",
27 | "- Opponent (Villain) raises to 2.50 (Villain has 30.35 remaining);\n",
28 | " - In poker terminology, this is called a 3bet. The small blind and big blind make the first bet, and the Hero raised them which was the second bet.\n",
29 | "- There is currently 3.70 Total in the Pot.\n",
30 | "\n",
31 | "Calling is not a good option for reasons that are beyond the scope of this blog post. The Hero must decide between raising with the plan of going All-In (Betting all remaining chips) or folding. Folding costs nothing so you will analyze the expected value of going all in. In this situation, I’d make a small raise to induce my opponent to All-in bluff, but we need to do the calculation as if I’m going All-in since that is the plan, so;\n",
32 | "\n",
33 | "- Hero risks 20.95 if All-in and loses;\n",
34 | " - Going ‘All-in’ means to put all your money in the pot. The Hero has 20.95 remaining, so going All-in risks 20.95.\n",
35 | "- Hero wins 23 if All-in and wins;\n",
36 | " - There is currently 3.70 in the pot. Hero bet 0.85 and the Villain raised to 2.50. Hero must add 1.65 of remaining 20.95 to match Villain’s raise, leaving Hero with 19.30. This means the Hero can win an additional 19.30 on top of the 3.70 already in the pot for a total of 23.00.\n",
37 | "- Hero wins 3.70 if Villain folds."
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 1,
43 | "metadata": {
44 | "collapsed": true
45 | },
46 | "outputs": [],
47 | "source": [
48 | "Hand1_AllIn_Loses = -20.95\n",
49 | "Hand1_AllIn_Winnings = 23\n",
50 | "Hand1_Fold_Winnings = 3.7"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "### Hand 1 Relevant Statistics:"
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "metadata": {},
63 | "source": [
64 | "Poker is a game of deductive reasoning based on incomplete information. Here is the information you have on this opponent:\n",
65 | "\n",
66 | " \n",
67 | "\n",
68 | "1. The Villian is in the Button position which is the first position to the right of the small and big blinds. Overall, from this position, villian 3bets 7.4% (27 trials);\n",
69 | "2. Hero is in the Cut-Off position, which is the first position to the right of the Button. Overall, vs. the Cut-Off, villian 3bets 12.5% (16 trials);\n",
70 | "3. When Villian is in the Button vs. a pre-flop raise from the Cut-Off, villian 3bets 25% (4 trials);\n",
71 | "4. When Villian 3bets pre-flop and faces a raise, he folds 50% of the time (2 trials)."
72 | ]
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "### Hand 1 Assumptions:"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "Based on the above statistics, I’m going to make the following assumptions which are educated guesses;\n",
86 | "\n",
87 | "- Villian raises to 2.50 with about (~) 13-15% of the range of possible starting hands;\n",
88 | "- Villian folds to a re-raise ~ 25% of the time and goes ‘All-in’ ~75% of the time;\n",
89 | "- Villian re-raises ‘All-In’ with a ~10% range, which looks like this: \n"
90 | ]
91 | },
92 | {
93 | "cell_type": "markdown",
94 | "metadata": {},
95 | "source": [
96 | "\n",
97 | "- The hands highlighted in yellow represent the Villian's range, which consists of 128 of the 1326 possible combinations of starting hands (9.7%);\n",
98 | "- If you’re wondering why A5s and A2s are in the range, those represent Villian’s bluff hands.\n",
99 | "\n"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "metadata": {},
105 | "source": [
106 | "### Hand 1 Analysis:"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "Now that I have Villian’s range, I can plug the Hero's hand (10h10s) and the Villian’s range into an [equity calculator](http://www.acepokersolutions.com/Poker-equity-calculator/). The equity calculator simulates 10h10s vs. Villian’s range thousands of times and determines that the Hero wins ~53.77% of the time. \n",
114 | "\n",
115 | "Now you can create variables for `Fold_Percent` and `Equity`"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": 2,
121 | "metadata": {
122 | "collapsed": true
123 | },
124 | "outputs": [],
125 | "source": [
126 | "Hand1_Fold_Percent = .25\n",
127 | "Hand1_Equity = .538"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "Now it’s a simple calculation. You need to build a function that represents the following equation:\n",
135 | "\n",
136 | "- $FoldEV = (FoldPercent * FoldWinnings)$\n",
137 | "\n",
138 | "- $AllinEV = (1 - FoldPercent) * ((AllInWinnings * Equity) + (AllInLoses * (1 - Equity)))$\n",
139 | "\n",
140 | "- $AllinExpectedValue = FoldEV + AllinEV$\n",
141 | "\n",
142 | "\n",
143 | "## To be continued...\n",
144 | "\n",
145 | "**When complete, this post will be published to [DataCamp's Blog](https://www.datacamp.com/community/blog) and will include interactive code. In the meantime, [click here](https://www.datacamp.com/community/tutorials/python-statistics-data-science) for 40+ resources for learning about statistics with Python.**"
146 | ]
147 | }
148 | ],
149 | "metadata": {
150 | "anaconda-cloud": {},
151 | "kernelspec": {
152 | "display_name": "Python [default]",
153 | "language": "python",
154 | "name": "python3"
155 | },
156 | "language_info": {
157 | "codemirror_mode": {
158 | "name": "ipython",
159 | "version": 3
160 | },
161 | "file_extension": ".py",
162 | "mimetype": "text/x-python",
163 | "name": "python",
164 | "nbconvert_exporter": "python",
165 | "pygments_lexer": "ipython3",
166 | "version": "3.5.2"
167 | }
168 | },
169 | "nbformat": 4,
170 | "nbformat_minor": 1
171 | }
172 |
--------------------------------------------------------------------------------
/Poker Probability and Statistics-Part 2 Final Draft.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Part 2: Poker Probability and Statistics Case Studies\n",
8 | "\n",
9 | "In Part I of this tutorial, you learned about several concepts including Independent/Dependent events, Permutations/Combinations, Multiple events, Expected Values, and how to calculate each of them. Now you will apply those concepts to actual poker hands that I played during my career. Along the way, you’ll learn much more about the concept of Expected Value and how to use it for making optimal decisions.\n",
10 | "\n",
11 | "- An Introduction to No Limit Texas Hold’em\n",
12 | "- Poker Probability Case Studies: Tools\n",
13 | "- Expected Value: A Closer Look\n",
14 | "- Case Study 1 \n",
15 | "- Case Study 2\n",
16 | "- Case Study 3\n",
17 | "- Conclusion\n",
18 | "\n",
19 | "\n",
20 | "\n",
21 | "## An Introduction to No Limit Texas Hold’em \n",
22 | "\n",
23 | "Before you get started, a little background info is in order. The game that will be covered in the case studies of this article is No Limit Texas Hold’em. Played with a standard 52 card deck, Texas Hold’em is the most popular of all the poker variations. Each player tries to make the best five-card hand possible by combining their two cards with the five community cards dealt throughout the hand. \n",
24 | "\n",
25 | "The player to the left of the dealer button starts the action and play moves clockwise around the table. The betting is typically started when the player to the left of the dealer button posts a small blind, and the next player to the left posts a big blind. Betting action takes place on multiple streets: preflop, flop, turn, and the river. \n",
26 | "Here are a few terms you should understand:\n",
27 | "\n",
28 | "\n",
29 | "- **Button** - The Button is a circular disk that gets passed around the table clockwise after each hand. In a home game, the person who has the Button deals the hand dealing the first card to the player on their left. At a casino, the Button identifies who is supposed to be the dealer, but the actual dealer is provided by the casino.\n",
30 | "- **The Blinds** - The Blinds are forced bets by the two players to the left of the Button. They are called “Blinds” because the two players have to bet blind, in that they have to bet before they get to see their cards. \n",
31 | "- **Streets** - Each round that cards are dealt is referred to as a street. \n",
32 | "- **Pre-Flop** - This is the first betting round. Each player is dealt two cards, and the blinds start the betting action. No community cards have been dealt yet.\n",
33 | "- **Flop** - This is the second betting round. In this round, three community cards are dealt face up in the middle of the table, followed by a round of betting.\n",
34 | "- **Turn** - In this round, only one community card is dealt, followed by the third round of betting.\n",
35 | "- **The River** - The final community card is dealt, followed by the last round of betting.\n",
36 | "- **Showdown** - After the River is dealt and all betting action has taken place, any remaining players Show their cards to see who has the best hand.\n",
37 | "- **Check** - If it’s a player's turn to act, and no previous bets have been made during that round of betting, the player can Check which means to choose not to bet, and allow the next player to take their turn.\n",
38 | "- *Bet or Raise* - Betting or Raising means to increase the size of the wager during a betting round. The first player to put money in the pot each round is making a Bet. If another player increases the size of the bet that round, they are making a Raise.\n",
39 | "- **Call** - If it’s a player’s turn to act and a bet has already been made during that round, the player can match the previous bet which is known as Calling the bet.\n",
40 | "- **Fold** -If it’s a player’s turn to act and a bet has already been made during that round, the player can give up and Fold their hand. This player is no longer involved in the hand and losses any money they have put in the pot.\n",
41 | "\n",
42 | "\n",
43 | "If you’ve never played or are unfamiliar with poker terminology you can [click here](https://www.pokernews.com/poker-rules/texas-holdem.htm) for a concise but detailed explanation. \n"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "## Poker Probability Case Studies: Tools\n",
51 | "\n",
52 | "Anytime I ran into a situation while playing that confused me, I would mark the hand for review later. After my poker playing session was done, I'd go back through the hands that I'd marked for review. I'd break them down mathematically so I'd have a better idea of what to do in similar situations in the future. \n",
53 | "\n",
54 | "The hands used in this tutorial were downloaded and stored in a PostgreSQL database by [Hold’em Manager](https://holdemmanager.com/?a_aid=sharpdata), software mentioned in Part I. Hold’em Manager calculates statistics from these hand histories for every opponent you play against. The data updates and displays in real time as you play.\n",
55 | "\n",
56 | "I picked out three hands from my poker career. You'll use statistics on my opponents that I had available at the time, deductive reasoning, and a tool called an [equity calculator](http://www.acepokersolutions.com/poker-calculator/), to make assumptions about the probability of winning the hand for each viable option.\n",
57 | "\n",
58 | "**Note:** an equity calculator is used to determine the probability of winning a hand based on a situation that you indicate. You enter your cards, the community cards (if any), and the range of hands you assume your opponent is holding. The calculator provides a probability of winning the hand if the remaining cards are dealt. \n"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {},
64 | "source": [
65 | "## Expected Value: A Closer Look\n",
66 | "\n",
67 | "Before getting into the analysis for the first hand, you need a better understanding of Expected Value. [In Part I](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#ev), you learned how to calculate your expected value for winning a \\$100 dollar pot with a 75% chance of winning. There were only two possibilities:\n",
68 | "- Win \\$100 \n",
69 | "- Win \\$0\n",
70 | "\n",
71 | "With the help of the formula ExpectedValue=TotalValue×Probability, you calculated that the Expected Value would be \\$100 * .75 or \\$75.\n",
72 | "\n",
73 | "However, many times you will not have such a straightforward calculation and you will have more than two possible outcomes. To determine expected value, you must find the weighted average of each possible outcome, where each possible outcome is weighted by its respective probability of occuring.\n",
74 | "\n",
75 | "That’s why the equation above would be better represented like this:\n",
76 | "\n",
77 | "$$Expected Value = (100 * .75) + (0 * .25)$$\n",
78 | "$$Expected Value = \\$75$$\n",
79 | "\n",
80 | "And what if there were a third possible outcome for the above situation?\n",
81 | "\n",
82 | "Take a look at the following situation, where you have a 50 percent chance of winning \\$100, 25% chances of winning \\$25 and another 25% chances of winning absolutely nothing:\n",
83 | "- Win \\$100 (50%)\n",
84 | "- Win \\$25 (25%)\n",
85 | "- Win \\$0 (25%)\n",
86 | "\n",
87 | "Then, the calculation of your Expected Value will be as follows:\n",
88 | "\n",
89 | "$$Expected Value = (100 * .50) + (25 * .25) + (0 * .25)$$\n",
90 | "$$Expected Value = \\$56.25$$\n",
91 | "\n",
92 | "Now it’s time to apply what you’ve learned to a few scenarios I ran into at the poker table.\n"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "Case Study 1: Pocket 10s vs. Pre Flop Raise
\n",
100 | "\n",
101 | "\n",
102 | "**Note:** When reviewing poker hands, it is common to refer to your opponent as the Villain and the player being reviewed is referred to as the Hero. The player you will be reviewing is ‘GamingFoSho’ which was my username at the poker sites that I played at.\n",
103 | "\n",
104 | "### Hand 1 Overview:\n",
105 | "\n",
106 | "\n",
107 | "\n",
108 | "Hero (GamingFoSho) has a pair of 10s and bet \\$0.85. He has \\$20.95 remaining. The Opponent or Villain raises to \\$2.50 and has \\$30.35 remaining.\n",
109 | "\n",
110 | "In poker terminology, this is called a 3bet. The small blind and big blind make the first bet, and Hero raised them which was the second bet. There is currently \\$3.70 total in the Pot. Calling is not a good option for reasons that are beyond the scope of this blog post to fully explain. \n",
111 | "\n",
112 | "**Note:** Generally speaking, playing poker passively is not profitable and playing poker aggressively is profitable. Calling is passive and betting or raising is aggressive. There are other factors related to poker strategy such as player position that indicate calling is a bad option, but would require significant explanation.\n",
113 | "\n",
114 | "Hero must decide between raising with the plan of going All-In and betting all remaining chips or folding. Folding costs nothing so you will analyze the expected value of going all in. In this situation, I’d make a small raise to induce Villain to All-in bluff, but the calculation must be done as if I’m going All-in since that is the plan.\n",
115 | "\n",
116 | "Hero risks \\$20.95 if All-in and loses. Going ‘All-in’ means to put all your money in the pot. Hero has \\$20.95 remaining, so going All-in risks \\$20.95. Hero wins \\$23 if All-in and wins. There is currently \\$3.70 in the pot. Hero bet \\$0.85 and Villain raised to \\$2.50. Hero must add \\$1.65 of remaining \\$20.95 to match Villain’s raise, leaving Hero with \\$19.30. This means Hero can win an additional \\$19.30 on top of the \\$3.70 already in the pot for a total of \\$23.00. Since there is currently \\$3.70 total in the pot, Hero wins \\$3.70 if Villain folds.\n"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 1,
122 | "metadata": {
123 | "collapsed": true
124 | },
125 | "outputs": [],
126 | "source": [
127 | "Hand1_AllIn_Loses = -20.95\n",
128 | "Hand1_AllIn_Winnings = 23\n",
129 | "Hand1_Fold_Winnings = 3.7"
130 | ]
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "### Hand 1 Relevant Statistics:"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "Poker is a game of deductive reasoning based on incomplete information. In Hold’em Manager, I can review hands I’ve played in the past and see the statistics I had at the time the hand was played. Below are screenshots of some of the statistics that I had on this opponent at the time this hand was played. \n",
144 | "\n",
145 | "The numbers represent a specific situation, such as betting preflop from the Button. Most of the time there are two numbers listed. The number on the left indicates the percentage of trials Villain made a specific move in a specific situation. The number in parenthesis on the right indicates the number of trials up to 99 trials. If there is no number in parenthesis, the number of trials is 100 or more. \n",
146 | "\n",
147 | "I had played 392 hands versus this opponent and I’ve highlighted the stats that are relevant to this hand:\n",
148 | "\n",
149 | "\n",
150 | " \n",
151 | "\n",
152 | "1. Villain is in the Button position which is the first position to the right of the small and big blinds. Overall, from this position, Villain 3bets 7.4% (27 trials);\n",
153 | "2. Hero is in the Cut-Off position, which is the first position to the right of the Button. Overall, vs. the Cut-Off, Villain 3bets 12.5% (16 trials);\n",
154 | "3. When Villain is in the Button vs. a pre-flop raise from the Cut-Off, Villain 3bets 25% (4 trials);\n",
155 | "4. When Villain 3bets pre-flop and faces a raise, he folds 50% of the time (2 trials).\n",
156 | "\n",
157 | "**Note:** How did I decide these 4 points were important? Hero was in the Cut-Off position and Villain 3bet from the Button. I want statistics that show what Villain has done in previous hands in similar situations. How often does Villain 3Bet from the Button position or vs. a player in the Cut-Off position? How often does Villain fold a 3Bet to a raise? The stats I selected above were the ones that best answered those questions.\n",
158 | "\n"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "### Hand 1 Assumptions:"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "Based on the above statistics, I’m going to make the following assumptions which are educated guesses;\n",
173 | "\n",
174 | "1. Villain raises to 2.50 with about (~) 13-15% of the range of possible starting hands;\n",
175 | "2. Villain folds to a re-raise ~ 25% of the time and goes ‘All-in’ ~75% of the time;\n",
176 | "3. Villain re-raises ‘All-In’ with a ~10% range, which is represented in the image below.\n",
177 | "4. The hands highlighted in yellow represent Villain’s assumed range, which consists of 128 combinations (9.7% of the sample size). \n",
178 | "5. If you’re wondering why A5s and A2s are in the range, those represent Villain’s bluff hands.\n",
179 | "\n",
180 | "**Note:** The image below represents the sample size of all possible starting hand combinations in Texas Hold’em, \n",
181 | "which in [Part I you found was 1326 combinations.](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#combinations)\n",
182 | "\n",
183 | "\n",
184 | "\n",
185 | "\n",
186 | "AA = Ace Ace, KK = King King, etc.\n",
187 | "AKo = Ace King offsuit, ATo = Ace Ten offsuit, etc.\n",
188 | "AKs = Ace King suited, ATs = Ace Ten suited, J8s = Jack Eight suited, etc.\n",
189 | "\n",
190 | "\n"
191 | ]
192 | },
193 | {
194 | "cell_type": "markdown",
195 | "metadata": {},
196 | "source": [
197 | "### Hand 1 Analysis:"
198 | ]
199 | },
200 | {
201 | "cell_type": "markdown",
202 | "metadata": {},
203 | "source": [
204 | "Now that you have Villain’s range, you need to determine the probability that Hero's hand will win vs. Villain’s assumed range if both go all in. You can plug Hero's hand (10h10s) and Villain’s range into an equity calculator to determine the probability Hero will win. The [equity calculator](http://www.acepokersolutions.com/Poker-equity-calculator/) simulates 10h10s vs. Villain’s assumed range thousands of times and determines that Hero wins about 53.77% of the time. \n",
205 | "\n",
206 | "Now you can create variables for `EstFoldPercent` and `Equity`, and then create your `AllinExpectedValue()` function.\n",
207 | "\n"
208 | ]
209 | },
210 | {
211 | "cell_type": "code",
212 | "execution_count": 2,
213 | "metadata": {
214 | "collapsed": true
215 | },
216 | "outputs": [],
217 | "source": [
218 | "Hand1_Fold_Percent = .25\n",
219 | "Hand1_Equity = .538"
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {},
225 | "source": [
226 | "Now it’s a simple calculation. You need to build a function that represents the following equation:\n",
227 | "\n",
228 | "- $FoldEV = (FoldPercent * FoldWinnings)$\n",
229 | "\n",
230 | "- $AllinEV = (1 - FoldPercent) * ((AllInWinnings * Equity) + (AllInLoses * (1 - Equity)))$\n",
231 | "\n",
232 | "- $AllinExpectedValue = FoldEV + AllinEV$"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": 3,
238 | "metadata": {
239 | "collapsed": true
240 | },
241 | "outputs": [],
242 | "source": [
243 | "def AllinExpectedValue(AllIn_Loses, AllIn_Winnings, Fold_Winnings, Fold_Percent, Equity):\n",
244 | " FoldEV = (Fold_Percent * Fold_Winnings)\n",
245 | " AllinEV = (1 - Fold_Percent) * ((AllIn_Winnings * Equity) + (AllIn_Loses * (1 - Equity)))\n",
246 | " AllinExpectedValue = FoldEV + AllinEV\n",
247 | " if AllinExpectedValue > 0:\n",
248 | " return 'Raise!', AllinExpectedValue\n",
249 | " else:\n",
250 | " return 'Fold!', AllinExpectedValue"
251 | ]
252 | },
253 | {
254 | "cell_type": "markdown",
255 | "metadata": {},
256 | "source": [
257 | "Now plug the Hand 1 variables into the `AllinExpectedValue` function and print your results."
258 | ]
259 | },
260 | {
261 | "cell_type": "code",
262 | "execution_count": 4,
263 | "metadata": {},
264 | "outputs": [
265 | {
266 | "name": "stdout",
267 | "output_type": "stream",
268 | "text": [
269 | "Raise!\n",
270 | "2.9463250000000016\n"
271 | ]
272 | }
273 | ],
274 | "source": [
275 | "Hand1_Decision, Hand1_EV = AllinExpectedValue(Hand1_AllIn_Loses, Hand1_AllIn_Winnings, Hand1_Fold_Winnings, Hand1_Fold_Percent, Hand1_Equity)\n",
276 | "print(Hand1_Decision)\n",
277 | "print(Hand1_EV)"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "### Hand 1 Results\n",
285 | "\n",
286 | "\n",
287 | "\n",
288 | "**Hero wins the hand with a set (three of a kind) of Tens beating a pair of Kings.**"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "Case Study 2: Pocket 8s Vs. Pre flop Raise
\n",
296 | "\n",
297 | "### Hand 2 Overview:\n",
298 | "\n",
299 | "\n",
300 | "\n",
301 | "In this situation, Hero (GamingFoSho) bet \\$1.10 and has \\$28.58 remaining. Villain, on the other hand, raises to \\$3.80 and has \\$10.66 remaining. There is currently \\$5.40 in the pot. This is a similar situation as the last hand. Again, calling is not a good option. Folding costs nothing, so you need to determine if raising All-in has a positive expected value. \n",
302 | "\n",
303 | "If Hero goes All-in, he Risks \\$13.36 since Villain has \\$10.66 remaining, and has raised \\$2.70. Hero wins \\$16.06 if All-in and wins the hand (Villain has \\$10.66 remaining, and there is currently \\$5.40 in pot) and wins \\$5.40 if All-in and Villain folds.\n"
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": 5,
309 | "metadata": {
310 | "collapsed": true
311 | },
312 | "outputs": [],
313 | "source": [
314 | "Hand2_AllIn_Loses = -13.36\n",
315 | "Hand2_AllIn_Winnings = 16.06\n",
316 | "Hand2_Fold_Winnings = 5.40"
317 | ]
318 | },
319 | {
320 | "cell_type": "markdown",
321 | "metadata": {},
322 | "source": [
323 | "### Hand 2 Relevant Statistics:\n",
324 | "\n",
325 | "\n",
326 | "\n",
327 | "\n",
328 | "\n",
329 | "1. Villain is in the Small-Blind position. From this position, Villain 3bets 7.2% (100+ trials);\n",
330 | "2. Hero is in the Cut-Off position, and vs. the Cut-Off, Villain 3bets 7.9% (89 trails);\n",
331 | "3. Villain folds to a 4bet 25% (8 trials);\n",
332 | "4. Villain 3bets 4% overall (100+ trails), but vs. Hero only 1% (98 trials). This is a huge red flag, and indicates Villain has a very strong hand;\n",
333 | "5. Villain 3bets out of position vs. the Cut-Off 9.8% (51 trials). Out of position means Villain will be first to act in the later betting rounds, and Hero will be second to act.\n",
334 | "6. Villain folds to a 4bet when out of position 0% (5 trials). Another huge red flag.\n"
335 | ]
336 | },
337 | {
338 | "cell_type": "markdown",
339 | "metadata": {},
340 | "source": [
341 | "### Hand 2 Assumptions:\n",
342 | "\n",
343 | "Based on the above statistics, I’m going to make the following assumptions;\n",
344 | "\n",
345 | "1. In comparison to most opponents, Villain 3bets ~8-10% of the time, but appears to 3bet 4 times as often vs. opponents other than Hero. This puts Villain’s range at ~3%. \n",
346 | "2. Villain has yet to fold to a 4bet in this situation, so at most Villain is folding 10% of the time. \n",
347 | "3. Villain calls with a ~2.7% range, which is represented in the image below.\n",
348 | "4. The hands in yellow represent Villain’s assumed range, which consists of 34 of the 1326 possible combinations of starting hands (2.6%).\n",
349 | "\n",
350 | "\n",
351 | "\n",
352 | "\n"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {},
358 | "source": [
359 | "### Hand 2 Analysis:"
360 | ]
361 | },
362 | {
363 | "cell_type": "markdown",
364 | "metadata": {},
365 | "source": [
366 | "Once again, I’ll use an equity calculator to determine the Hero’s equity. In this case, the Hero’s hand has 35.84% equity vs. the Villain’s range.\n",
367 | "\n",
368 | "Now you can create variables for `EstFoldPercent` and `Equity`. \n"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": 6,
374 | "metadata": {
375 | "collapsed": true
376 | },
377 | "outputs": [],
378 | "source": [
379 | "Hand2_Fold_Percent = .10\n",
380 | "Hand2_Equity = .3584"
381 | ]
382 | },
383 | {
384 | "cell_type": "markdown",
385 | "metadata": {},
386 | "source": [
387 | "Now plug the variables for this hand into the `AllinExpectedValue` function, and print the results."
388 | ]
389 | },
390 | {
391 | "cell_type": "code",
392 | "execution_count": 7,
393 | "metadata": {},
394 | "outputs": [
395 | {
396 | "name": "stdout",
397 | "output_type": "stream",
398 | "text": [
399 | "Fold!\n",
400 | "-1.994284799999999\n"
401 | ]
402 | }
403 | ],
404 | "source": [
405 | "Hand2_Decision, Hand2_EV = AllinExpectedValue(Hand2_AllIn_Loses, Hand2_AllIn_Winnings, Hand2_Fold_Winnings, Hand2_Fold_Percent, Hand2_Equity)\n",
406 | "print(Hand2_Decision)\n",
407 | "print(Hand2_EV)"
408 | ]
409 | },
410 | {
411 | "cell_type": "markdown",
412 | "metadata": {},
413 | "source": [
414 | "### Hand 2 Results:\n",
415 | "\n",
416 | "\n",
417 | "\n",
418 | "**The Hero wins the hand with a set of eights vs. two pairs, Aces and Kings. This was a lucky result from a decision that would lose money in the long run. The optimal play here is to fold.**"
419 | ]
420 | },
421 | {
422 | "cell_type": "markdown",
423 | "metadata": {},
424 | "source": [
425 | "Case Study 3: Flop Check Raise Semi Bluff
\n",
426 | "\n",
427 | "## Hand 3 Overview:\n",
428 | "\n",
429 | "\n",
430 | "\n",
431 | "This hand is on the flop and Hero (GamingFoSho) is first to act and checks. He has \\$25.08. Villain bets \\$1.06 and has \\$25.37 remaining. There is currently \\$2.66 in the pot.\n",
432 | "\n",
433 | "Once again, calling is not a good option, and folding costs nothing. Hero must decide if raising in this situation, known as a Semi-Bluff, has a positive expected value. A Semi-Bluff is when you raise with a drawing hand, in this case a flush draw. \n",
434 | "Hero does not have a made hand, as he is currently only holding an Ace high, but has four Hearts and only needs one more for a flush which is a strong hand. Much like the first hand, the best line of play when raising is to raise small and give Villain the opportunity to bluff. If Hero were to just go all in, Villain would most likely fold a hand like King of Hearts/Jack of Hearts.\n",
435 | "\n",
436 | "Hero risks \\$25.08 if All-in. Hero wins \\$26.68 if All-in and wins hand. Villain bet \\$1.06, so Hero must match that amount from the remaining \\$25.08, leaving Hero with \\$24.02. This means Hero can win an additional \\$24.02 on top of the \\$2.66 currently in the pot for a total of \\$26.68. Hero wins \\$2.66 if Villain folds.\n",
437 | "\n"
438 | ]
439 | },
440 | {
441 | "cell_type": "code",
442 | "execution_count": 8,
443 | "metadata": {
444 | "collapsed": true
445 | },
446 | "outputs": [],
447 | "source": [
448 | "Hand3_AllIn_Loses = -25.08\n",
449 | "Hand3_AllIn_Winnings = 26.68\n",
450 | "Hand3_Fold_Winnings = 2.66"
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {},
456 | "source": [
457 | "### Hand 3 Relevant Statistics:\n",
458 | "\n",
459 | "\n",
460 | "\n",
461 | "\n",
462 | "\n",
463 | "\n",
464 | "1. Preflop, Villain raised and from Middle Position Villain raises 9% (100+ trails);\n",
465 | "2. On the flop Hero checks, and Villain (who raised preflop) bets again. This is called a continuation bet (Cbet). Villain Cbets 100% (12 trials);\n",
466 | "3. Hero is Check-Raising Villain and when facing a Check-Raise, Villain folds 67% (3 trials);\n",
467 | "\n"
468 | ]
469 | },
470 | {
471 | "cell_type": "markdown",
472 | "metadata": {},
473 | "source": [
474 | "### Hand 3 Assumptions:\n",
475 | "\n",
476 | "- Opponents preflop range is ~9-10%, which looks like this:\n",
477 | "\n",
478 | "\n",
479 | "\n",
480 | "- The hands highlighted in yellow represent Villain’s range, which consists of 128 of the 1326 possible combinations of starting hands (9.7%);\n",
481 | "- After Cbeting 100% of the time, Villain folds ~67% of the time to Hero’s Check-Raise, leaving ~35-45 combinations in Villains range. Villains range looks like this:\n",
482 | "\n",
483 | "\n",
484 | "\n",
485 | "\n",
486 | "- This range consists of 35 combinations, and make up the strongest hands from Villain's pre-flop range. \n",
487 | "- Some of the hands are different shades of yellow. There are a couple reasons for this;\n",
488 | "\n",
489 | " 1. Card removal - Pocket Aces (AA) normally has six combinations (Diamonds/Clubs, Hearts/Clubs, Spades/Clubs, Hearts/Diamonds, Spades/Diamonds, Spades/Hearts), but the Hero has the Ace of Hearts. The Villain could only have three combinations of Pocket Aces (Diamonds/Clubs, Spades/Clubs, Spades/Diamonds).\n",
490 | " 2. Flush Draws - There are four combinations of King/Jack suited (Diamonds, Hearts, Spades, and Clubs), but the Villain would only go All-in with one of those combos (Hearts).\n"
491 | ]
492 | },
493 | {
494 | "cell_type": "markdown",
495 | "metadata": {},
496 | "source": [
497 | "### Hand 3 Analysis:\n",
498 | "\n",
499 | "Once again, I plug Hero’s hand and Villain’s range into the equity calculator, this time also entering the 3 flop cards. The equity calculator indicates that Hero wins in this situation 43.58%.\n",
500 | "\n",
501 | "Now you can create your variables for `EstFoldPercent` and `Equity`.\n",
502 | "\n"
503 | ]
504 | },
505 | {
506 | "cell_type": "code",
507 | "execution_count": 9,
508 | "metadata": {
509 | "collapsed": true
510 | },
511 | "outputs": [],
512 | "source": [
513 | "Hand3_Fold_Percent = .67\n",
514 | "Hand3_Equity = .4358"
515 | ]
516 | },
517 | {
518 | "cell_type": "markdown",
519 | "metadata": {},
520 | "source": [
521 | "Now plug the Hand 3 variables into the `AllinExpectedValue` function and print the results."
522 | ]
523 | },
524 | {
525 | "cell_type": "code",
526 | "execution_count": 10,
527 | "metadata": {},
528 | "outputs": [
529 | {
530 | "name": "stdout",
531 | "output_type": "stream",
532 | "text": [
533 | "Raise!\n",
534 | "0.9496126400000008\n"
535 | ]
536 | }
537 | ],
538 | "source": [
539 | "Hand3_Decision, Hand3_EV = AllinExpectedValue(Hand3_AllIn_Loses, Hand3_AllIn_Winnings, Hand3_Fold_Winnings, Hand3_Fold_Percent, Hand3_Equity)\n",
540 | "print(Hand3_Decision)\n",
541 | "print(Hand3_EV)"
542 | ]
543 | },
544 | {
545 | "cell_type": "markdown",
546 | "metadata": {},
547 | "source": [
548 | "### Hand 3 Results:\n",
549 | "\n",
550 | "\n",
551 | "\n",
552 | "**The Hero wins with and Ace high flush, beating the Villains pair of Tens.**"
553 | ]
554 | },
555 | {
556 | "cell_type": "markdown",
557 | "metadata": {},
558 | "source": [
559 | "## Conclusion\n",
560 | " "
561 | ]
562 | },
563 | {
564 | "cell_type": "markdown",
565 | "metadata": {
566 | "collapsed": true
567 | },
568 | "source": [
569 | "Congrats, you’ve now completed this tutorial on probability theory with Python! After learning about core probability concepts including [Independent/Dependent events](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#independent), [Permutations/Combinations](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#combinations), [Multiple events](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#events), [Expected Values](https://www.datacamp.com/community/tutorials/statistics-python-tutorial-probability-1#ev), and how to calculate each of them in Part 1, you applied those concepts to real life poker situations in Part 2. \n",
570 | "\n",
571 | "You gained a much deeper understanding of Expected Value and used the concept to make optimal decisions at the poker table. The concept is an extremely useful one to keep in mind when making any business or financial decision, so next time you face such a decision, try to quantify your options in terms of Expected Value.\n"
572 | ]
573 | }
574 | ],
575 | "metadata": {
576 | "anaconda-cloud": {},
577 | "kernelspec": {
578 | "display_name": "Python 3",
579 | "language": "python",
580 | "name": "python3"
581 | },
582 | "language_info": {
583 | "codemirror_mode": {
584 | "name": "ipython",
585 | "version": 3
586 | },
587 | "file_extension": ".py",
588 | "mimetype": "text/x-python",
589 | "name": "python",
590 | "nbconvert_exporter": "python",
591 | "pygments_lexer": "ipython3",
592 | "version": "3.6.1"
593 | }
594 | },
595 | "nbformat": 4,
596 | "nbformat_minor": 1
597 | }
598 |
--------------------------------------------------------------------------------
/Poker Probability and Statistics-Part 2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Poker Probability and Statistics\n",
8 | "\n",
9 | " \n",
10 | "\n",
11 | "Anytime I ran into a situation while playing that confused me, I would mark the hand for review later. After my poker playing session was done, I'd go back through the hands that I'd marked for review and break them down mathematically so I'd have a better idea of what to do in each situation the next time it arose. I picked out five hands from my poker career. Using the statistics on my opponents that I had available at the time, I’ll explain my thought process. Then you can analyze the hand using Python to determine which of your options offers the highest expected value.\n",
12 | "\n",
13 | "## What is No Limit Texas Hold'em About? \n",
14 | "\n",
15 | "Before we get started, a little background info is in order. The game is No Limit Texas Hold’em. Played with a standard 52 card deck, Texas Hold’em is the most popular of all the poker variations. Each player is dealt two cards to start the hand. Each player will make the best five-card hand possible by using their two cards combined with the five community cards that are dealt throughout the hand. The player to the left of the dealer button starts the action and play moves clockwise around the table. The betting is typically started when the player to the left of the dealer button posts a small blind, and the next player to the left posts a big blind. Betting action takes place on multiple streets: preflop, flop, turn, and the river. Here are a few terms you should understand;\n",
16 | "\n",
17 | "- Button - The Button is a circular disk that gets passed around the table clockwise after each hand. In a home game, the person who has the Button deals the hand dealing the first card to the player on their left. At a casino, the Button identifies who is supposed to be the dealer, but the actual dealer is provided by the casino.\n",
18 | "- The Blinds - The Blinds are forced bets by the two players to the left of the Button. They are called “Blinds” because the two players have to bet blind, in that they have to bet before they get to see their cards. \n",
19 | "- Streets - Each round that cards are dealt is referred to as a street. \n",
20 | "- Pre-Flop - This is the first betting round. Each player is dealt two cards, and the blinds start the betting action. No community cards have been dealt yet.\n",
21 | "- Flop - This is the second betting round. In this round, three community cards are dealt face up in the middle of the table, followed by a round of betting.\n",
22 | "- Turn - In this round, only one community card is dealt, followed by the third round of betting.\n",
23 | "- The River - The final community card is dealt, followed by the last round of betting.\n",
24 | "- Showdown - After the River is dealt and all betting action has taken place, any remaining players Show their cards to see who has the best hand.\n",
25 | "- Check - If it’s a player's turn to act, and no previous bets have been made during that round of betting, the player can Check which means to choose not to bet, and allow the next player to take their turn.\n",
26 | "- Bet or Raise - Betting or Raising means to increase the size of the wager during a betting round. The first player to put money in the pot each round is making a Bet. If another player increases the size of the bet that round, they are making a Raise.\n",
27 | "- Call - If it’s a player’s turn to act and a bet has already been made during that round, the player can match the previous bet which is known as Calling the bet.\n",
28 | "- Fold - If it’s a player’s turn to act and a bet has already been made during that round, the player can give up and Fold their hand. This player is no longer involved in the hand and losses any money they have put in the pot.\n",
29 | "\n",
30 | "If you’ve never played or are unfamiliar with poker terminology you can click [here](https://www.pokernews.com/poker-rules/texas-holdem.htm) for a concise but detailed explanation. \n",
31 | "\n",
32 | "**Note**: *When you reviewing poker hands, you refer to your opponent as the \"Villain\" and yourself as the \"Hero.\"*"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "## Hand 1 Overview:\n",
40 | "\n",
41 | " \n",
42 | "\n",
43 | "\n",
44 | "\n",
45 | "In this situation, you see the following:\n",
46 | "- Hero bet \\$0.85, so he has \\$20.95 left;\n",
47 | "- Opponent - also called the \"Villain\"- raises to \\$2.50. This means that the Villain has \\$30.35 remaining;
\n",
48 | "*In poker terminology, this is called a 3bet. The small blind and big blind make the first bet, and the Hero raised them which was the second bet.*\n",
49 | "- There is currently \\$3.70 Total in the Pot.\n",
50 | "\n",
51 | " \n",
52 | "\n",
53 | "Calling is not a good option for reasons that are beyond the scope of this blog post. The Hero must decide between raising with the plan of going All-In, or, in other words, betting all remaining chips, or folding. Folding costs nothing so you will analyze the Expected Value (EV) of going all in. \n",
54 | "\n",
55 | "In this situation, you could make a small raise to induce my opponent to all-in bluff, but you need to do the calculation as if you're going All-in since that is the plan, so:\n",
56 | "\n",
57 | "- Hero risks \\$20.95 if All-in and loses;
\n",
58 | "*Going ‘All-in’ means to put all your money in the pot. The Hero has \\$20.95 remaining, so going All-in risks all the cash he has left.**\n",
59 | "\n",
60 | "- Hero wins \\$23 if All-in and wins;
\n",
61 | "*There is currently \\$3.70 in the pot. Hero bet \\$0.85 and the Villain raised to \\$2.50. Hero must add \\$1.65 of remaining \\$20.95 to match Villain’s raise, leaving Hero with \\$19.30. This means the Hero can win an additional \\$19.30 on top of the \\$3.70 already in the pot for a total of \\$23.00.*\n",
62 | "\n",
63 | "- Hero wins \\$3.70 if Villain folds."
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": 1,
69 | "metadata": {
70 | "collapsed": true
71 | },
72 | "outputs": [],
73 | "source": [
74 | "Hand1_AllIn_Loses = -20.95\n",
75 | "Hand1_AllIn_Winnings = 23\n",
76 | "Hand1_Fold_Winnings = 3.7"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "### Hand 1 Relevant Statistics:"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "Poker is a game of deductive reasoning based on incomplete information. Here is the information you have on this opponent:\n",
91 | "\n",
92 | " \n",
93 | "\n",
94 | "1. The Villian is in the Button position which is the first position to the right of the small and big blinds. Overall, from this position, villian 3bets 7.4% (27 trials);\n",
95 | "2. Hero is in the Cut-Off position, which is the first position to the right of the Button. Overall, vs. the Cut-Off, villian 3bets 12.5% (16 trials);\n",
96 | "3. When Villian is in the Button vs. a pre-flop raise from the Cut-Off, villian 3bets 25% (4 trials);\n",
97 | "4. When Villian 3bets pre-flop and faces a raise, he folds 50% of the time (2 trials)."
98 | ]
99 | },
100 | {
101 | "cell_type": "markdown",
102 | "metadata": {},
103 | "source": [
104 | "### Hand 1 Assumptions:"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "Based on the above statistics, I’m going to make the following assumptions which are educated guesses;\n",
112 | "\n",
113 | "- Villian raises to 2.50 with about (~) 13-15% of the range of possible starting hands;\n",
114 | "- Villian folds to a re-raise ~ 25% of the time and goes ‘All-in’ ~75% of the time;\n",
115 | "- Villian re-raises ‘All-In’ with a ~10% range, which looks like this: \n"
116 | ]
117 | },
118 | {
119 | "cell_type": "markdown",
120 | "metadata": {},
121 | "source": [
122 | "\n",
123 | "- The hands highlighted in yellow represent the Villian's range, which consists of 128 of the 1326 possible combinations of starting hands (9.7%);\n",
124 | "- If you’re wondering why A5s and A2s are in the range, those represent Villian’s bluff hands.\n",
125 | "\n"
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {},
131 | "source": [
132 | "### Hand 1 Analysis:"
133 | ]
134 | },
135 | {
136 | "cell_type": "markdown",
137 | "metadata": {},
138 | "source": [
139 | "Now that I have Villian’s range, I can plug the Hero's hand (10h10s) and the Villian’s range into an [equity calculator](http://www.acepokersolutions.com/Poker-equity-calculator/). The equity calculator simulates 10h10s vs. Villian’s range thousands of times and determines that the Hero wins ~53.77% of the time. \n",
140 | "\n",
141 | "Now you can create variables for `Fold_Percent` and `Equity`"
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": 2,
147 | "metadata": {
148 | "collapsed": true
149 | },
150 | "outputs": [],
151 | "source": [
152 | "Hand1_Fold_Percent = .25\n",
153 | "Hand1_Equity = .538"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "Now it’s a simple calculation. You need to build a function that represents the following equation:\n",
161 | "\n",
162 | "- $FoldEV = (FoldPercent * FoldWinnings)$\n",
163 | "\n",
164 | "- $AllinEV = (1 - FoldPercent) * ((AllInWinnings * Equity) + (AllInLoses * (1 - Equity)))$\n",
165 | "\n",
166 | "- $AllinExpectedValue = FoldEV + AllinEV$"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": 3,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "def AllinExpectedValue(AllIn_Loses, AllIn_Winnings, Fold_Winnings, Fold_Percent, Equity):\n",
176 | " FoldEV = (Fold_Percent * Fold_Winnings)\n",
177 | " AllinEV = (1 - Fold_Percent) * ((AllIn_Winnings * Equity) + (AllIn_Loses * (1 - Equity)))\n",
178 | " AllinExpectedValue = FoldEV + AllinEV\n",
179 | " if AllinExpectedValue > 0:\n",
180 | " return 'Raise!', AllinExpectedValue\n",
181 | " else:\n",
182 | " return 'Fold!', AllinExpectedValue"
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "metadata": {},
188 | "source": [
189 | "Now plug the Hand 1 variables into the `AllinExpectedValue` function and print your results."
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": 4,
195 | "metadata": {},
196 | "outputs": [
197 | {
198 | "name": "stdout",
199 | "output_type": "stream",
200 | "text": [
201 | "Raise!\n",
202 | "2.9463250000000016\n"
203 | ]
204 | }
205 | ],
206 | "source": [
207 | "Hand1_Decision, Hand1_EV = AllinExpectedValue(Hand1_AllIn_Loses, Hand1_AllIn_Winnings, Hand1_Fold_Winnings, Hand1_Fold_Percent, Hand1_Equity)\n",
208 | "print(Hand1_Decision)\n",
209 | "print(Hand1_EV)"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "### Hand 1 Results\n",
217 | "\n",
218 | "\n",
219 | "\n",
220 | "**Hero wins the hand with a set (three of a kind) of Tens beating a pair of Kings.**"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {},
226 | "source": [
227 | "## Hand 2 Overview:\n",
228 | "\n",
229 | "\n",
230 | "\n",
231 | "- Hero bet 1.10 and has 28.58 remaining.\n",
232 | "- Villain raises to 3.80 and has 10.66 remaining.\n",
233 | "- There is currently 5.40 in the pot.\n",
234 | "\n",
235 | "This is a similar situation as the last hand. Again, calling is not a good option. Folding costs nothing, so we need to determine if raising All-in has a positive expected value.\n",
236 | "\n",
237 | "- Hero Risks 13.36 if All-in;\n",
238 | "\t- Villain has 10.66 remaining, and has raised 2.70;\n",
239 | "- Hero wins 16.06 if All-in and wins hand;\n",
240 | "\t- Villain has 10.66 remaining, and there is currently 5.40 in pot;\n",
241 | "- Hero wins 5.40 if All-in and Villain folds."
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 5,
247 | "metadata": {
248 | "collapsed": true
249 | },
250 | "outputs": [],
251 | "source": [
252 | "Hand2_AllIn_Loses = -13.36\n",
253 | "Hand2_AllIn_Winnings = 16.06\n",
254 | "Hand2_Fold_Winnings = 5.40"
255 | ]
256 | },
257 | {
258 | "cell_type": "markdown",
259 | "metadata": {},
260 | "source": [
261 | "### Hand 2 Relevant Statistics:\n",
262 | "\n",
263 | "\n",
264 | "\n",
265 | "\n",
266 | "\n",
267 | "1. The Villain is in the Small-Blind position. From this position, Villain 3bets 7.2% (100+ trials);\n",
268 | "\t- 100+ trials = If there is no indication of the number of trials next to the relevant statistic;\n",
269 | "2. The Hero is in the Cut-Off position, and vs. the Cut-Off, Villain 3bets 7.9% (89 trails);\n",
270 | "3. The Villain folds to a 4bet 25% (8 trials);\n",
271 | "4. The Villain 3bets 4% overall (100+ trails), but vs. the Hero only 1% (98 trials);\n",
272 | "\t- This is a huge red flag, and indicates the Villain has a very strong hand;\n",
273 | "5. The Villain 3bets out of position vs. the Cut-Off 9.8% (51 trials);\n",
274 | "\t- Out of position means the Villain will be first to act in the later betting rounds, and Hero will be second to act.\n",
275 | "6. The Villain folds to a 4bet when out of position 0% (5 trials);\n",
276 | "\t- Another huge red flag."
277 | ]
278 | },
279 | {
280 | "cell_type": "markdown",
281 | "metadata": {},
282 | "source": [
283 | "### Hand 2 Assumptions:\n",
284 | "\n",
285 | "Based on the above statistics, I’m going to make the following assumptions;\n",
286 | "\n",
287 | "- Vs. most opponents, the Villain 3bets ~8-10% of the time, but appears to 3bet 4 times as often vs. other opponents than the Hero. This puts the Villain’s range at ~3%.\n",
288 | "- The Villain has yet to fold to a 4bet in this situation, so at most the Villain is folding 10% of the time.\n",
289 | "- The Villain calls with a ~2.7% rang, which looks like this: \n",
290 | "\n",
291 | "\n",
292 | "\n",
293 | "- The hands in yellow represent the Villain’s assumed range, which consists of 34 of the 1326 possible combinations of starting hands (2.6%)."
294 | ]
295 | },
296 | {
297 | "cell_type": "markdown",
298 | "metadata": {},
299 | "source": [
300 | "### Hand 2 Analysis:"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "Once again, I’ll use an equity calculator to determine the Hero’s equity. In this case, the Hero’s hand has 35.84% equity vs. the Villain’s range.\n",
308 | "\n",
309 | "Now you can create variables for `EstFoldPercent` and `Equity`. \n"
310 | ]
311 | },
312 | {
313 | "cell_type": "code",
314 | "execution_count": 6,
315 | "metadata": {
316 | "collapsed": true
317 | },
318 | "outputs": [],
319 | "source": [
320 | "Hand2_Fold_Percent = .10\n",
321 | "Hand2_Equity = .3584"
322 | ]
323 | },
324 | {
325 | "cell_type": "markdown",
326 | "metadata": {},
327 | "source": [
328 | "Now plug the variables for this hand into the `AllinExpectedValue` function, and print the results."
329 | ]
330 | },
331 | {
332 | "cell_type": "code",
333 | "execution_count": 7,
334 | "metadata": {},
335 | "outputs": [
336 | {
337 | "name": "stdout",
338 | "output_type": "stream",
339 | "text": [
340 | "Fold!\n",
341 | "-1.994284799999999\n"
342 | ]
343 | }
344 | ],
345 | "source": [
346 | "Hand2_Decision, Hand2_EV = AllinExpectedValue(Hand2_AllIn_Loses, Hand2_AllIn_Winnings, Hand2_Fold_Winnings, Hand2_Fold_Percent, Hand2_Equity)\n",
347 | "print(Hand2_Decision)\n",
348 | "print(Hand2_EV)"
349 | ]
350 | },
351 | {
352 | "cell_type": "markdown",
353 | "metadata": {},
354 | "source": [
355 | "### Hand 2 Results:\n",
356 | "\n",
357 | "\n",
358 | "\n",
359 | "**The Hero wins the hand with a set of eights vs. two pairs, Aces and Kings. This was a lucky result from a decision that would lose money in the long run. The correct play here is to fold.**"
360 | ]
361 | },
362 | {
363 | "cell_type": "markdown",
364 | "metadata": {},
365 | "source": [
366 | "## Hand 3 Overview:\n",
367 | "\n",
368 | "\n",
369 | "\n",
370 | "- This hand is on the flop, and the Hero is first to act and checks (Hero has 25.08);\n",
371 | "- The Villain bets 1.06 (Villain has 25.37 remaining);\n",
372 | "- There is currently 2.66 in the pot.\n",
373 | "\n",
374 | "Once again, calling is not a good option, and folding costs nothing. The Hero must decide if raising in this situation, known as a Semi-Bluff, has a positive expected value. A Semi-Bluff is when you raise with a drawing hand, in this case a flush draw. The Hero does not have a made hand, currently only holding an Ace high, but has four Hearts and only needs one more for a flush which is a strong hand. Similarly, to the first hand, the best line of play when raising is to raise small and give the Villain the opportunity to bluff himself. If the Hero were to just go all in, the Villain would most likely fold a hand like King of Hearts/Jack of Hearts. \n",
375 | "\n",
376 | "- Hero risks 25.08 if All-in;\n",
377 | "- Hero wins 26.68 if All-in and wins hand;\n",
378 | "\t- The Villain bet 1.06, so the Hero must match that amount from the remaining 25.08, leaving the Hero with 24.02. This means the Hero can win an additional 24.02 on top of the 2.66 currently in the pot for a total of 26.68;\n",
379 | "- Hero wins 2.66 if Villain folds.\n"
380 | ]
381 | },
382 | {
383 | "cell_type": "code",
384 | "execution_count": 8,
385 | "metadata": {
386 | "collapsed": true
387 | },
388 | "outputs": [],
389 | "source": [
390 | "Hand3_AllIn_Loses = -25.08\n",
391 | "Hand3_AllIn_Winnings = 26.68\n",
392 | "Hand3_Fold_Winnings = 2.66"
393 | ]
394 | },
395 | {
396 | "cell_type": "markdown",
397 | "metadata": {},
398 | "source": [
399 | "### Hand 3 Relevant Statistics:\n",
400 | "\n",
401 | "\n",
402 | "\n",
403 | "\n",
404 | "\n",
405 | "\n",
406 | "1. Preflop, the Villain raised and from Middle Position the Villain raises 9% (100+ trails);\n",
407 | "2. On the flop the Hero checks, and the Villain (who raised preflop) bets again. This is called a continuation bet (Cbet). The Villain Cbets 100% (12 trials);\n",
408 | "3. The Hero is Check-Raising the Villain and when facing a Check-Raise, the Villain folds 67% (3 trials);\n"
409 | ]
410 | },
411 | {
412 | "cell_type": "markdown",
413 | "metadata": {},
414 | "source": [
415 | "### Hand 3 Assumptions:\n",
416 | "\n",
417 | "- Opponents preflop range is ~9-10%, which looks like this:\n",
418 | "\n",
419 | "\n",
420 | "\n",
421 | "- The hands highlighted in yellow represent the Villain’s range, which consists of 128 of the 1326 possible combinations of starting hands (9.7%);\n",
422 | "- After Cbeting 100% of the time, the Villain folds ~67% of the time to the Hero’s Check-Raise, leaving ~35-45 combinations in the Villains range. The Villains range looks like this:\n",
423 | "\n",
424 | "\n",
425 | "\n",
426 | "- This range consists of 35 combinations, and make up the strongest hands from the Villain's pre-flop range.\n",
427 | "- Some of the hands are different shades of yellow. There are a couple reasons for this;\n",
428 | " 1. Card removal - Pocket Aces (AA) normally has six combinations (Diamonds/Clubs, Hearts/Clubs, Spades/Clubs, Hearts/Diamonds, Spades/Diamonds, Spades/Hearts), but the Hero has the Ace of Hearts. The Villain could only have three combinations of Pocket Aces (Diamonds/Clubs, Spades/Clubs, Spades/Diamonds).\n",
429 | " 2. Flush Draws - There are four combinations of King/Jack suited (Diamonds, Hearts, Spades, and Clubs), but the Villain would only go All-in with one of those combos (Hearts).\n"
430 | ]
431 | },
432 | {
433 | "cell_type": "markdown",
434 | "metadata": {},
435 | "source": [
436 | "### Hand 3 Analysis:\n",
437 | "\n",
438 | "Once again, I plug the Hero’s hand and the Villain’s range into the equity calculator, this time also entering the 3 flop cards. The equity calculator indicates that the Hero wins in this situation 43.58%.\n",
439 | "\n",
440 | "Now you can create your variables for `EstFoldPercent` and `Equity`.\n"
441 | ]
442 | },
443 | {
444 | "cell_type": "code",
445 | "execution_count": 9,
446 | "metadata": {
447 | "collapsed": true
448 | },
449 | "outputs": [],
450 | "source": [
451 | "Hand3_Fold_Percent = .67\n",
452 | "Hand3_Equity = .4358"
453 | ]
454 | },
455 | {
456 | "cell_type": "markdown",
457 | "metadata": {},
458 | "source": [
459 | "Now plug the Hand 3 variables into the `AllinExpectedValue` function and print the results."
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 10,
465 | "metadata": {},
466 | "outputs": [
467 | {
468 | "name": "stdout",
469 | "output_type": "stream",
470 | "text": [
471 | "Raise!\n",
472 | "0.9496126400000008\n"
473 | ]
474 | }
475 | ],
476 | "source": [
477 | "Hand3_Decision, Hand3_EV = AllinExpectedValue(Hand3_AllIn_Loses, Hand3_AllIn_Winnings, Hand3_Fold_Winnings, Hand3_Fold_Percent, Hand3_Equity)\n",
478 | "print(Hand3_Decision)\n",
479 | "print(Hand3_EV)"
480 | ]
481 | },
482 | {
483 | "cell_type": "markdown",
484 | "metadata": {},
485 | "source": [
486 | "### Hand 3 Results:\n",
487 | "\n",
488 | "\n",
489 | "\n",
490 | "**The Hero wins with and Ace high flush, beating the Villains pair of Tens.**"
491 | ]
492 | },
493 | {
494 | "cell_type": "markdown",
495 | "metadata": {},
496 | "source": [
497 | "## Conclusion\n",
498 | " "
499 | ]
500 | },
501 | {
502 | "cell_type": "code",
503 | "execution_count": null,
504 | "metadata": {
505 | "collapsed": true
506 | },
507 | "outputs": [],
508 | "source": []
509 | }
510 | ],
511 | "metadata": {
512 | "anaconda-cloud": {},
513 | "kernelspec": {
514 | "display_name": "Python 3",
515 | "language": "python",
516 | "name": "python3"
517 | },
518 | "language_info": {
519 | "codemirror_mode": {
520 | "name": "ipython",
521 | "version": 3
522 | },
523 | "file_extension": ".py",
524 | "mimetype": "text/x-python",
525 | "name": "python",
526 | "nbconvert_exporter": "python",
527 | "pygments_lexer": "ipython3",
528 | "version": "3.6.0"
529 | }
530 | },
531 | "nbformat": 4,
532 | "nbformat_minor": 1
533 | }
534 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blog Posts: Data-Science-Poker-Projects
2 |
3 |
4 | ### Overview
5 |
6 | After reading one of my Scikit-Learn tutorials I published on [DataCamp's blog](https://www.datacamp.com/community/authors/daniel-poston), [SpringBoard](https://www.springboard.com/) approached me to write a blog about Data Science and Poker. This repository consists of the files and code related to that blog post along with a soon to be published blog post for DataCamp on Poker Probability and Statistics in Python.
7 |
8 | ## [How I Used Professional Poker to Become a Data Scientist](https://medium.springboard.com/how-i-used-professional-poker-to-become-a-data-scientist-e49b75dfe8e3)
9 |
10 | April 15th, 2011, is referred to as Black Friday in the poker community. It’s the day that the United States Government shut down the top three online poker sites. About 4,000 US citizens played online poker professionally back then, and thus the exodus began. Canada and Costa Rica were popular destinations. I’m from Southern California, so I’m no stranger to Baja California. I decided to set up shop south of the border in a town called Rosarito, Mexico...
11 |
12 | ### Related Files:
13 | - [Poker Segmentation.ipynb](https://github.com/Sharp-Data/Data-Science-Poker-Projects/blob/master/Poker%20Segmentation.ipynb): The post is based on the code in this file. Python code in Jupyter notebook which builds a K Means Model to segment poker opponents.
14 | - Report25_vsPlayerFinal.csv: Actual data from my poker career on my opponents. Consists of statistics on their playing tendencies and their win/loss totals.
15 |
16 |
--------------------------------------------------------------------------------