{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import numpy as np\n", "import pandas as pd\n", "import random\n", "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')\n", "from collections import Counter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Converting state polling average to probability" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The state polling average is the average from multiple polling companies using different margins of error. For example, if a candidate has a polling average of 50% with an assumed margin of error of +/- 4, that means the truth is in the range of 46 to 54. Their opponent has a polling average of 46% with an assumed margin of error of +/- 4, that means the truth is in the range of 42 to 50." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![example7](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex7.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**This means we can have one candidate leading in the polls but ultimately lose the election.\n", "![example8](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex8.png)\n", "It also means we can have the candidate that lead in the polls win larger than expected.**\n", "![example9](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex9.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Polling average alone does not give us the probability of a candidate winning. The candidate in the lead would win 100% of the time." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 100.0% of 10000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "wins = 0 # number of wins x over y\n", "number_of_elections = 10000\n", "for i in range(number_of_elections):\n", " victory = x - y\n", " if victory >= 1:\n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead, we will randomly add the margin of error to a candidate's polling average." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n = 4\n", "random.choice(range((n*-1),(n+1),1))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.58% of 10000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 10000\n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) # random selection of margin or error for candidate x\n", " moe_y = random.choice(range((n*-1),(n+1),1)) # different margin of error for candidate y\n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that a candidate with a 4 point lead only wins 81% of the time. Keep in mind that a tie is not a victory. \n", "What if we run it again? Will the percentage stay the same?" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.44% of 10000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 # number of wins x over y\n", "number_of_elections = 10000\n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) # random selection of margin or error for candidate x\n", " moe_y = random.choice(range((n*-1),(n+1),1)) # different margin of error for candidate y\n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: # cannot be a tie \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is still about 81%. Let's try doubling the number of simulated elections." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.41000000000001% of 20000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 20000 # previously we used 10,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.89% of 20000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 20000 # previously we used 10,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What about 100,000?" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.286% of 100000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 100000 # previously we used 20,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.541% of 100000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 100000 # previously we used 20,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1,000,000?" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.4585% of 1000000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 1000000 # previously we used 100,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x wins: 81.5544% of 1000000 elections\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "wins = 0 \n", "number_of_elections = 1000000 # previously we used 100,000 \n", "for i in range(number_of_elections):\n", " moe_x = random.choice(range((n*-1),(n+1),1)) \n", " moe_y = random.choice(range((n*-1),(n+1),1)) \n", " x1 = x + moe_x\n", " y1 = y + moe_y\n", " victory = x1 - y1\n", " if victory >= 1: \n", " wins += 1\n", "wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", "print('Candidate x wins:', wins_percentage,'of', number_of_elections,'elections')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have the probability stabilizing, but do we need to do Monte Carlo simulations or can we calculate the probability to get an accurate number? Let's look at the range again.\n", "![example7](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex7.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Candidate x can end up winning 46, 47, 48, 49, 50, 51, 52, 53, or 54 votes. \n", "Candidate y can end up winning 42, 43, 44, 45, 46, 47, 48, 49, or 50 votes. \n", "A margin of error of 4 means both candidates have a 1 out of 9 probability (4 below average, average, 4 above). \n", "\n", "Candidate y can only win with 47, 48, 49, or 50 (a 4 out of 9 probability) **but** it is dependent on candidate x. \n", "\n", "For candidate y to win with a 47 (1 out of 9 probability), candidate y must get 46 (1 out of 9 probability). \n", "For candidate y to win with a 48 (2 out of 9 probability), candidate y must get 47 or less (2 out of 9 probability). \n", "For candidate y to win with a 49 (3 out of 9 probability), candidate y must get 48 or less (3 out of 9 probability). \n", "For candidate y to win with a 50 (4 out of 9 probability), candidate y must get 49 or less (4 out of 9 probability). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do the complicated combinatorics or we can do a quick Monte Carlo simulation that gets us pretty close." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def moe(x, y, n):\n", " moe_x = random.choice(range((n*-1),(n+1),1))\n", " moe_y = random.choice(range((n*-1),(n+1),1))\n", " x += moe_x\n", " y += moe_y\n", " return x, y\n", "\n", "def sim(x, y, n, number_of_elections=20000):\n", " x = int(x)\n", " y = int(y)\n", " n = int(n)\n", " wins = 0 \n", " for i in range(number_of_elections):\n", " x1, y1 = moe(x, y, n)\n", " victory = x1 - y1\n", " if victory >= 1:\n", " wins += 1\n", " wins_percentage = str((float(wins) / number_of_elections)*100)+'%'\n", " return wins_percentage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's stick with our previous example of candidate x averaging 50 and candidate y averaging 46 with a margin of error of 4" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'81.06%'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "sim(x,y,n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Margin of Error\n", "\n", "Let's take a quick look how those probabilities change as we increase the margin of error" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Candidate x winning probability with a MoE of 4: 81.69%\n", "Candidate x winning probability with a MoE of 5: 76.885%\n", "Candidate x winning probability with a MoE of 6: 73.76%\n", "Candidate x winning probability with a MoE of 7: 70.38499999999999%\n", "Candidate x winning probability with a MoE of 8: 68.61%\n", "Candidate x winning probability with a MoE of 9: 66.97%\n", "Candidate x winning probability with a MoE of 10: 65.66%\n" ] } ], "source": [ "x = 50\n", "y = 46\n", "n = 4\n", "print('Candidate x winning probability with a MoE of 4:', sim(x,y,n))\n", "n = 5\n", "print('Candidate x winning probability with a MoE of 5:', sim(x,y,n))\n", "n = 6\n", "print('Candidate x winning probability with a MoE of 6:', sim(x,y,n))\n", "n = 7\n", "print('Candidate x winning probability with a MoE of 7:', sim(x,y,n))\n", "n = 8\n", "print('Candidate x winning probability with a MoE of 8:', sim(x,y,n))\n", "n = 9\n", "print('Candidate x winning probability with a MoE of 9:', sim(x,y,n))\n", "n = 10\n", "print('Candidate x winning probability with a MoE of 10:', sim(x,y,n))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are using **unweighted** polling averages. This means that every poll entered into the average is treated like all others. Polling aggregators **claim** they weight individual polls in order to produce correct probabilities. \n", "\n", "It is universally understood that a prediction above 50% is a prediction for that outcome. The strength of that prediction is how far above 50% that probability may be. \n", "\n", "For example, a 99% probability is a more confident prediction than 65%.\n", "\n", "To clarify: \n", "**Prediction is above 50% \n", "Probability is confidence in the prediction**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Applying State Probabilities to the 2016 Election" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv('backtest2016.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We need to decide what margin of error to use. We can take a guess or we can look at the actual results. \n", "Let's create a margin of victory column and see what we have." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "df['spread'] = abs(df['trump_rcp'] - df['clinton_rcp'])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df.plot(x='state',y='spread',kind='bar',figsize=(16,4),\n", " title='Polling Average Spread by State/District',legend=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see from the chart above there are states that are \"safe states\" for candidates. These safe states are states in which one candidate does not overlap the other within the margin of error. In other words, one candidate's *lowest* possible result is above another candidate's *highest* possible result." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![example12](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex12.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's refer to the qualitative experts to find a cutoff for what constitutes a \"safe state.\" For this we will use the Cook Political Report." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StateCook
35MississippiSolid Rep.
40LouisianaSolid Rep.
41MontanaSolid Rep.
42Nebraska (CD 1)*Solid Rep.
43West VirginiaSolid Rep.
44TennesseeSolid Rep.
45North DakotaSolid Rep.
46KansasSolid Rep.
47AlabamaSolid Rep.
48ArkansasSolid Rep.
49NebraskaSolid Rep.
50South DakotaSolid Rep.
51IdahoSolid Rep.
52KentuckySolid Rep.
53OklahomaSolid Rep.
54WyomingSolid Rep.
55Nebraska (CD 3)*Solid Rep.
\n", "
" ], "text/plain": [ " State Cook\n", "35 Mississippi Solid Rep.\n", "40 Louisiana Solid Rep.\n", "41 Montana Solid Rep.\n", "42 Nebraska (CD 1)* Solid Rep.\n", "43 West Virginia Solid Rep.\n", "44 Tennessee Solid Rep.\n", "45 North Dakota Solid Rep.\n", "46 Kansas Solid Rep.\n", "47 Alabama Solid Rep.\n", "48 Arkansas Solid Rep.\n", "49 Nebraska Solid Rep.\n", "50 South Dakota Solid Rep.\n", "51 Idaho Solid Rep.\n", "52 Kentucky Solid Rep.\n", "53 Oklahoma Solid Rep.\n", "54 Wyoming Solid Rep.\n", "55 Nebraska (CD 3)* Solid Rep." ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "qual = pd.read_csv('aggpreds2016.csv')\n", "qual = qual[['State','Cook']]\n", "rep_safe = list(qual[qual['Cook'].str.startswith('Solid R', na=False)]['State'].values)\n", "qual[qual['Cook'].str.startswith('Solid R', na=False)]" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StateCook
0D.C.Solid Dem.
1CaliforniaSolid Dem.
2MarylandSolid Dem.
3HawaiiSolid Dem.
4VermontSolid Dem.
5New YorkSolid Dem.
6Rhode IslandSolid Dem.
7IllinoisSolid Dem.
8WashingtonSolid Dem.
9New JerseySolid Dem.
10ConnecticutSolid Dem.
11Maine (CD 1)*Solid Dem.
12DelawareSolid Dem.
13MassachusettsSolid Dem.
14OregonSolid Dem.
\n", "
" ], "text/plain": [ " State Cook\n", "0 D.C. Solid Dem.\n", "1 California Solid Dem.\n", "2 Maryland Solid Dem.\n", "3 Hawaii Solid Dem.\n", "4 Vermont Solid Dem.\n", "5 New York Solid Dem.\n", "6 Rhode Island Solid Dem.\n", "7 Illinois Solid Dem.\n", "8 Washington Solid Dem.\n", "9 New Jersey Solid Dem.\n", "10 Connecticut Solid Dem.\n", "11 Maine (CD 1)* Solid Dem.\n", "12 Delaware Solid Dem.\n", "13 Massachusetts Solid Dem.\n", "14 Oregon Solid Dem." ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dem_safe = list(qual[qual['Cook'].str.startswith('Solid D', na=False)]['State'].values)\n", "qual[qual['Cook'].str.startswith('Solid D', na=False)]" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "17 Connecticut\n", "22 Texas\n", "26 South Dakota\n", "27 Tennessee\n", "28 Alaska\n", "29 Kansas\n", "33 Washington\n", "34 Rhode Island\n", "35 Delaware\n", "36 Massachusetts\n", "37 New York\n", "38 California\n", "39 District Of Columbia\n", "40 Hawaii\n", "41 Maryland\n", "42 Vermont\n", "43 Louisiana\n", "44 Mississippi\n", "45 Alabama\n", "46 Arkansas\n", "47 Kentucky\n", "48 Idaho\n", "49 Nebraska\n", "50 North Dakota\n", "51 Oklahoma\n", "52 West Virginia\n", "53 Wyoming\n", "Name: state, dtype: object" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spread_states = df[df['spread'] >= 12]['state'].values\n", "df[df['spread'] >= 12]['state']" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Texas\n", "Alaska\n", "District Of Columbia\n" ] } ], "source": [ "for state in spread_states:\n", " if state in rep_safe or state in dem_safe:\n", " pass\n", " else:\n", " print(state)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we use 6 as our margin of error, we can have all the states above 12 land in the \"safe state\" category which will be represented by a probability of 100% for the safe candidate and 0% for the opponent." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "trump_x = df['trump_rcp'].values\n", "clinton_y = df['clinton_rcp'].values\n", "\n", "clinton_x = df['clinton_rcp'].values\n", "trump_y = df['trump_rcp'].values" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "def sim(x, y, n, number_of_elections=20000):\n", " x = int(x)\n", " y = int(y)\n", " n = int(n)\n", " wins = 0 \n", " for i in range(number_of_elections):\n", " x1, y1 = moe(x, y, n)\n", " victory = x1 - y1\n", " if victory >= 1:\n", " wins += 1\n", " wins_percentage = float(wins) / number_of_elections\n", " return wins_percentage" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "trump_rcp_prob = []\n", "for x, y in zip(trump_x, clinton_y):\n", " nwp = sim(x,y,6)\n", " trump_rcp_prob.append(100*nwp)\n", "\n", "clinton_rcp_prob = []\n", "for x, y in zip(clinton_x, trump_y):\n", " nwp = sim(x,y,6)\n", " clinton_rcp_prob.append(100*nwp)\n", " \n", "df['trump_rcp_prob'] = trump_rcp_prob\n", "df['clinton_rcp_prob'] = clinton_rcp_prob" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
stateecclinton_rcptrump_rcpclinton_actualtrump_actualspreadtrump_rcp_probclinton_rcp_prob
0Florida2946.446.647.8049.020.245.40546.535
1Ohio1842.345.843.5651.693.567.45527.085
2Michigan1645.442.047.2747.503.426.58067.155
3Pennsylvania2046.244.347.4648.181.932.55060.570
4New Hampshire443.342.746.9846.610.638.76054.105
\n", "
" ], "text/plain": [ " state ec clinton_rcp trump_rcp clinton_actual trump_actual \\\n", "0 Florida 29 46.4 46.6 47.80 49.02 \n", "1 Ohio 18 42.3 45.8 43.56 51.69 \n", "2 Michigan 16 45.4 42.0 47.27 47.50 \n", "3 Pennsylvania 20 46.2 44.3 47.46 48.18 \n", "4 New Hampshire 4 43.3 42.7 46.98 46.61 \n", "\n", " spread trump_rcp_prob clinton_rcp_prob \n", "0 0.2 45.405 46.535 \n", "1 3.5 67.455 27.085 \n", "2 3.4 26.580 67.155 \n", "3 1.9 32.550 60.570 \n", "4 0.6 38.760 54.105 " ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# The Electoral College" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![example13](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex13.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have probabilities assigned to the states and districts, we can bring in the Electoral College scoring system. \n", "For more detail on how it works, you can read about it [here](https://en.wikipedia.org/wiki/Electoral_college)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Maximum electoral college votes possible: 538\n", "Minimum electoral college votes to win: 270\n" ] } ], "source": [ "print('Maximum electoral college votes possible:', np.sum(df['ec']))\n", "print('Minimum electoral college votes to win:', int((np.sum(df['ec'])/2) + 1) )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see which of the two candidates are in the lead according to our probabilities" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Trump Most Likely Electoral College Results:: 230\n", "\n", "Clinton Most Likely Electoral College Results:: 272\n" ] } ], "source": [ "print('Trump Most Likely Electoral College Results::', np.sum(df['ec'][df['trump_rcp_prob'] >= 50]))\n", "print()\n", "print('Clinton Most Likely Electoral College Results::', np.sum(df['ec'][df['clinton_rcp_prob'] >= 50]))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "538 - (272+230): 36\n" ] } ], "source": [ "print('538 - (272+230):',538 - (272+230) )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Which states are missing?" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
stateec
0Florida29
5Maine CD21
11Nevada6
\n", "
" ], "text/plain": [ " state ec\n", "0 Florida 29\n", "5 Maine CD2 1\n", "11 Nevada 6" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "unc_states = list(df[ (df['trump_rcp_prob'] <= 50) & (df['clinton_rcp_prob'] <= 50) ]['state'].values)\n", "df[ (df['trump_rcp_prob'] <= 50) & (df['clinton_rcp_prob'] <= 50) ][['state','ec']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is another reason why the 2016 Presidential Election was unique. We have two states and a district where neither major candidate had a 50% probability of winning. These are statistically \"tossup states\" since we can assign a probability but not a prediction." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Reusing our Simulation to Create Election Winning Probabilities" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we can simulate the electoral college results, we need to address something unique with our probability assignments. A state awarding its electoral college votes to a candidate should be 100%, yet we have a number of states and districts that do not total 100%.\n", "\n", "Let us determine this probability for each state and make that our uncertainty probability." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "df['unc_prob'] = 100 - (df['trump_rcp_prob'] + df['clinton_rcp_prob'])" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
statetrump_rcp_probclinton_rcp_probunc_prob
5Maine CD245.72545.7658.510
11Nevada45.75046.1858.065
0Florida45.40546.5358.060
7North Carolina53.77038.8107.420
4New Hampshire38.76054.1057.135
3Pennsylvania32.55060.5706.880
2Michigan26.58067.1556.265
14Iowa66.95027.0655.985
1Ohio67.45527.0855.460
10Colorado27.09567.4655.440
12New Mexico16.67577.9455.380
13Arizona73.07521.6355.290
20South Carolina73.42521.4555.120
9Georgia78.89516.7754.330
8Virginia17.08578.6304.285
6Maine16.98078.8704.150
15Wisconsin12.48083.5903.930
16Oregon6.17591.2702.555
30Nebraska CD294.1203.3952.485
19Maine CD13.41594.3352.250
18Minnesota1.78596.2201.995
24Utah96.4001.7151.885
25Montana96.4401.6901.870
21Indiana98.2150.5351.250
23Missouri98.2700.5101.220
32New Jersey0.53598.2951.170
27Tennessee99.4000.0000.600
31Illinois0.00099.4100.590
22Texas99.4850.0000.515
26South Dakota100.0000.0000.000
42Vermont0.000100.0000.000
52West Virginia100.0000.0000.000
51Oklahoma100.0000.0000.000
50North Dakota100.0000.0000.000
49Nebraska100.0000.0000.000
48Idaho100.0000.0000.000
47Kentucky100.0000.0000.000
46Arkansas100.0000.0000.000
45Alabama100.0000.0000.000
44Mississippi100.0000.0000.000
43Louisiana100.0000.0000.000
40Hawaii0.000100.0000.000
41Maryland0.000100.0000.000
28Alaska100.0000.0000.000
39District Of Columbia0.000100.0000.000
38California0.000100.0000.000
37New York0.000100.0000.000
36Massachusetts0.000100.0000.000
35Delaware0.000100.0000.000
34Rhode Island0.000100.0000.000
33Washington0.000100.0000.000
17Connecticut0.000100.0000.000
29Kansas100.0000.0000.000
53Wyoming100.0000.0000.000
\n", "
" ], "text/plain": [ " state trump_rcp_prob clinton_rcp_prob unc_prob\n", "5 Maine CD2 45.725 45.765 8.510\n", "11 Nevada 45.750 46.185 8.065\n", "0 Florida 45.405 46.535 8.060\n", "7 North Carolina 53.770 38.810 7.420\n", "4 New Hampshire 38.760 54.105 7.135\n", "3 Pennsylvania 32.550 60.570 6.880\n", "2 Michigan 26.580 67.155 6.265\n", "14 Iowa 66.950 27.065 5.985\n", "1 Ohio 67.455 27.085 5.460\n", "10 Colorado 27.095 67.465 5.440\n", "12 New Mexico 16.675 77.945 5.380\n", "13 Arizona 73.075 21.635 5.290\n", "20 South Carolina 73.425 21.455 5.120\n", "9 Georgia 78.895 16.775 4.330\n", "8 Virginia 17.085 78.630 4.285\n", "6 Maine 16.980 78.870 4.150\n", "15 Wisconsin 12.480 83.590 3.930\n", "16 Oregon 6.175 91.270 2.555\n", "30 Nebraska CD2 94.120 3.395 2.485\n", "19 Maine CD1 3.415 94.335 2.250\n", "18 Minnesota 1.785 96.220 1.995\n", "24 Utah 96.400 1.715 1.885\n", "25 Montana 96.440 1.690 1.870\n", "21 Indiana 98.215 0.535 1.250\n", "23 Missouri 98.270 0.510 1.220\n", "32 New Jersey 0.535 98.295 1.170\n", "27 Tennessee 99.400 0.000 0.600\n", "31 Illinois 0.000 99.410 0.590\n", "22 Texas 99.485 0.000 0.515\n", "26 South Dakota 100.000 0.000 0.000\n", "42 Vermont 0.000 100.000 0.000\n", "52 West Virginia 100.000 0.000 0.000\n", "51 Oklahoma 100.000 0.000 0.000\n", "50 North Dakota 100.000 0.000 0.000\n", "49 Nebraska 100.000 0.000 0.000\n", "48 Idaho 100.000 0.000 0.000\n", "47 Kentucky 100.000 0.000 0.000\n", "46 Arkansas 100.000 0.000 0.000\n", "45 Alabama 100.000 0.000 0.000\n", "44 Mississippi 100.000 0.000 0.000\n", "43 Louisiana 100.000 0.000 0.000\n", "40 Hawaii 0.000 100.000 0.000\n", "41 Maryland 0.000 100.000 0.000\n", "28 Alaska 100.000 0.000 0.000\n", "39 District Of Columbia 0.000 100.000 0.000\n", "38 California 0.000 100.000 0.000\n", "37 New York 0.000 100.000 0.000\n", "36 Massachusetts 0.000 100.000 0.000\n", "35 Delaware 0.000 100.000 0.000\n", "34 Rhode Island 0.000 100.000 0.000\n", "33 Washington 0.000 100.000 0.000\n", "17 Connecticut 0.000 100.000 0.000\n", "29 Kansas 100.000 0.000 0.000\n", "53 Wyoming 100.000 0.000 0.000" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[['state','trump_rcp_prob','clinton_rcp_prob','unc_prob']].sort_values('unc_prob',ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simulating One Election" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Won Indiana for 11 electoral college votes\n", "Won Texas for 38 electoral college votes\n", "Won Missouri for 10 electoral college votes\n", "Won Utah for 6 electoral college votes\n", "Won Montana for 3 electoral college votes\n", "Won South Dakota for 3 electoral college votes\n", "Won Tennessee for 11 electoral college votes\n", "Won Alaska for 3 electoral college votes\n", "Won Kansas for 6 electoral college votes\n", "Won Nebraska CD2 for 1 electoral college votes\n", "Won Louisiana for 8 electoral college votes\n", "Won Mississippi for 6 electoral college votes\n", "Won Alabama for 9 electoral college votes\n", "Won Arkansas for 6 electoral college votes\n", "Won Kentucky for 8 electoral college votes\n", "Won Idaho for 4 electoral college votes\n", "Won Nebraska for 4 electoral college votes\n", "Won North Dakota for 3 electoral college votes\n", "Won Oklahoma for 7 electoral college votes\n", "Won West Virginia for 5 electoral college votes\n", "Won Wyoming for 3 electoral college votes\n", "\n", "Final Results: 155 electoral college votes\n" ] } ], "source": [ "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand = list(df['trump_rcp_prob'].values)\n", "sim_election = np.random.uniform()*100\n", "ec_total = 0\n", "for x, y, z in zip(cand, states, ec):\n", " if x > sim_election:\n", " print('Won',y,'for',z,'electoral college votes')\n", " ec_total += z\n", "print()\n", "print('Final Results:',ec_total,'electoral college votes')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Making state-by-state outcomes just a bit more realistic\n", "\n", "The challenge that comes with simulations is that if it is statistically possible then it will likely show up in the simulation. Whether to leave the possibility open ultimately becomes a matter of judgement. For this simulation, we will make any state above a 5% probability eligible for a candidate to win in the simulation. This is inline with out \"safe state\" assessments from the qualitative experts." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Won Florida for 29 electoral college votes\n", "Won Ohio for 18 electoral college votes\n", "Won Michigan for 16 electoral college votes\n", "Won Pennsylvania for 20 electoral college votes\n", "Won New Hampshire for 4 electoral college votes\n", "Won Maine CD2 for 1 electoral college votes\n", "Won North Carolina for 15 electoral college votes\n", "Won Georgia for 16 electoral college votes\n", "Won Colorado for 9 electoral college votes\n", "Won Nevada for 6 electoral college votes\n", "Won Arizona for 11 electoral college votes\n", "Won Iowa for 6 electoral college votes\n", "Won South Carolina for 9 electoral college votes\n", "Won Indiana for 11 electoral college votes\n", "Won Texas for 38 electoral college votes\n", "Won Missouri for 10 electoral college votes\n", "Won Utah for 6 electoral college votes\n", "Won Montana for 3 electoral college votes\n", "Won South Dakota for 3 electoral college votes\n", "Won Tennessee for 11 electoral college votes\n", "Won Alaska for 3 electoral college votes\n", "Won Kansas for 6 electoral college votes\n", "Won Nebraska CD2 for 1 electoral college votes\n", "Won Louisiana for 8 electoral college votes\n", "Won Mississippi for 6 electoral college votes\n", "Won Alabama for 9 electoral college votes\n", "Won Arkansas for 6 electoral college votes\n", "Won Kentucky for 8 electoral college votes\n", "Won Idaho for 4 electoral college votes\n", "Won Nebraska for 4 electoral college votes\n", "Won North Dakota for 3 electoral college votes\n", "Won Oklahoma for 7 electoral college votes\n", "Won West Virginia for 5 electoral college votes\n", "Won Wyoming for 3 electoral college votes\n", "\n", "Final Results: 315 electoral college votes\n" ] } ], "source": [ "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand = list(df['trump_rcp_prob'].values)\n", "sim_election = np.random.uniform(low=0.05)*100\n", "ec_total = 0\n", "for x, y, z in zip(cand, states, ec):\n", " if x > sim_election:\n", " print('Won',y,'for',z,'electoral college votes')\n", " ec_total += z\n", "print()\n", "print('Final Results:',ec_total,'electoral college votes')" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Won Michigan for 16 electoral college votes\n", "Won Pennsylvania for 20 electoral college votes\n", "Won New Hampshire for 4 electoral college votes\n", "Won Maine for 2 electoral college votes\n", "Won Virginia for 13 electoral college votes\n", "Won Colorado for 9 electoral college votes\n", "Won New Mexico for 5 electoral college votes\n", "Won Wisconsin for 10 electoral college votes\n", "Won Oregon for 7 electoral college votes\n", "Won Connecticut for 7 electoral college votes\n", "Won Minnesota for 10 electoral college votes\n", "Won Maine CD1 for 1 electoral college votes\n", "Won Illinois for 20 electoral college votes\n", "Won New Jersey for 14 electoral college votes\n", "Won Washington for 12 electoral college votes\n", "Won Rhode Island for 4 electoral college votes\n", "Won Delaware for 3 electoral college votes\n", "Won Massachusetts for 11 electoral college votes\n", "Won New York for 29 electoral college votes\n", "Won California for 55 electoral college votes\n", "Won District Of Columbia for 3 electoral college votes\n", "Won Hawaii for 4 electoral college votes\n", "Won Maryland for 10 electoral college votes\n", "Won Vermont for 3 electoral college votes\n", "\n", "Final Results: 272 electoral college votes\n" ] } ], "source": [ "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand = list(df['clinton_rcp_prob'].values)\n", "sim_election = np.random.uniform(low=0.05)*100\n", "ec_total = 0\n", "for x, y, z in zip(cand, states, ec):\n", " if x > sim_election:\n", " print('Won',y,'for',z,'electoral college votes')\n", " ec_total += z\n", "print()\n", "print('Final Results:',ec_total,'electoral college votes')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Swing States" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will go back to the qualitative experts in order to determine swing states.\n", "![example14](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/ex14.png)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StateCook
17MichiganLean Dem.
19WisconsinLean Dem.
21PennsylvaniaLean Dem.
22ColoradoLean Dem.
23New HampshireLean Dem.
24NevadaLean Dem.
27OhioLean Rep.
28IowaLean Rep.
30UtahLean Rep.
33GeorgiaLean Rep.
34ArizonaLean Rep.
\n", "
" ], "text/plain": [ " State Cook\n", "17 Michigan Lean Dem.\n", "19 Wisconsin Lean Dem.\n", "21 Pennsylvania Lean Dem.\n", "22 Colorado Lean Dem.\n", "23 New Hampshire Lean Dem.\n", "24 Nevada Lean Dem.\n", "27 Ohio Lean Rep.\n", "28 Iowa Lean Rep.\n", "30 Utah Lean Rep.\n", "33 Georgia Lean Rep.\n", "34 Arizona Lean Rep." ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "qual[qual['Cook'].str.startswith('Lea', na=False)]" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StateCook
25FloridaTossup
26North CarolinaTossup
29Maine (CD 2)*Tossup
31Nebraska (CD 2)*Tossup
\n", "
" ], "text/plain": [ " State Cook\n", "25 Florida Tossup\n", "26 North Carolina Tossup\n", "29 Maine (CD 2)* Tossup\n", "31 Nebraska (CD 2)* Tossup" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "qual[qual['Cook'].str.startswith('Tos', na=False)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now have 13 swing states and two swing districts. The four toss ups will get their own simulation results independent of each other. For the remaining swing states, we can either group according to the qualitative experts or group according to the qualitative experts and geography. Combining the qualitative experts with state geography allows us to capture regional attitudes, interests, and opinions. For example, Utah and Arizona have different public opinion polling than Colorado and Nevada on the issue of legalized marijuana." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "swing_states = ['Michigan', 'Wisconsin', 'Pennsylvania', 'Colorado', 'New Hampshire',\n", " 'Nevada', 'Ohio', 'Iowa', 'Utah', 'Georgia', 'Arizona','Florida', 'North Carolina','Maine CD2','Nebraska CD2']" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "lean_r_west = ['Utah','Arizona']\n", "lean_d_west = ['Colorado','Nevada']\n", "lean_r_lakes = ['Ohio', 'Iowa']\n", "lean_d_lakes = ['Michigan', 'Wisconsin', 'Pennsylvania',]\n", "tossups = ['Florida', 'North Carolina','Maine CD2','Nebraska CD2']" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Won Florida for 29 electoral college votes\n", "Won Maine for 2 electoral college votes\n", "Won Virginia for 13 electoral college votes\n", "Won Colorado for 9 electoral college votes\n", "Won Nevada for 6 electoral college votes\n", "Won New Mexico for 5 electoral college votes\n", "Won Wisconsin for 10 electoral college votes\n", "Won Oregon for 7 electoral college votes\n", "Won Connecticut for 7 electoral college votes\n", "Won Minnesota for 10 electoral college votes\n", "Won Maine CD1 for 1 electoral college votes\n", "Won Illinois for 20 electoral college votes\n", "Won New Jersey for 14 electoral college votes\n", "Won Washington for 12 electoral college votes\n", "Won Rhode Island for 4 electoral college votes\n", "Won Delaware for 3 electoral college votes\n", "Won Massachusetts for 11 electoral college votes\n", "Won New York for 29 electoral college votes\n", "Won California for 55 electoral college votes\n", "Won District Of Columbia for 3 electoral college votes\n", "Won Hawaii for 4 electoral college votes\n", "Won Maryland for 10 electoral college votes\n", "Won Vermont for 3 electoral college votes\n", "\n", "Final Results: 267 electoral college votes\n" ] } ], "source": [ "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand = list(df['clinton_rcp_prob'].values)\n", "sim_election = np.random.uniform(low=0.05)*100\n", "lean_r_west_sim = np.random.uniform()*100\n", "lean_d_west_sim = np.random.uniform()*100\n", "lean_r_lakes_sim = np.random.uniform()*100\n", "lean_d_lakes_sim = np.random.uniform()*100\n", "ec_total = 0\n", "for x, y, z in zip(cand, states, ec):\n", " if y in swing_states:\n", " if y in lean_r_west:\n", " sim_election = lean_r_west_sim\n", " if y in lean_d_west:\n", " sim_election = lean_d_west_sim\n", " if y in lean_r_lakes:\n", " sim_election = lean_r_lakes_sim\n", " if y in lean_d_lakes:\n", " sim_election = lean_d_lakes_sim\n", " if y in tossups:\n", " sim_election = np.random.uniform()*100\n", " if x > sim_election:\n", " print('Won',y,'for',z,'electoral college votes')\n", " ec_total += z\n", "print()\n", "print('Final Results:',ec_total,'electoral college votes')" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Won Florida for 29 electoral college votes\n", "Won Michigan for 16 electoral college votes\n", "Won Pennsylvania for 20 electoral college votes\n", "Won New Hampshire for 4 electoral college votes\n", "Won Arizona for 11 electoral college votes\n", "Won Wisconsin for 10 electoral college votes\n", "Won South Carolina for 9 electoral college votes\n", "Won Indiana for 11 electoral college votes\n", "Won Texas for 38 electoral college votes\n", "Won Missouri for 10 electoral college votes\n", "Won Utah for 6 electoral college votes\n", "Won Montana for 3 electoral college votes\n", "Won South Dakota for 3 electoral college votes\n", "Won Tennessee for 11 electoral college votes\n", "Won Alaska for 3 electoral college votes\n", "Won Kansas for 6 electoral college votes\n", "Won Nebraska CD2 for 1 electoral college votes\n", "Won Louisiana for 8 electoral college votes\n", "Won Mississippi for 6 electoral college votes\n", "Won Alabama for 9 electoral college votes\n", "Won Arkansas for 6 electoral college votes\n", "Won Kentucky for 8 electoral college votes\n", "Won Idaho for 4 electoral college votes\n", "Won Nebraska for 4 electoral college votes\n", "Won North Dakota for 3 electoral college votes\n", "Won Oklahoma for 7 electoral college votes\n", "Won West Virginia for 5 electoral college votes\n", "Won Wyoming for 3 electoral college votes\n", "\n", "Final Results: 254 electoral college votes\n" ] } ], "source": [ "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand = list(df['trump_rcp_prob'].values)\n", "ec_total = 0\n", "\n", "\n", "sim_election = np.random.uniform(low=0.05)*100\n", "lean_r_west_sim = np.random.uniform()*100\n", "lean_d_west_sim = np.random.uniform()*100\n", "lean_r_lakes_sim = np.random.uniform()*100\n", "lean_d_lakes_sim = np.random.uniform()*100\n", "for x, y, z in zip(cand, states, ec):\n", " if y in swing_states:\n", " if y in lean_r_west:\n", " sim_election = lean_r_west_sim\n", " if y in lean_d_west:\n", " sim_election = lean_d_west_sim\n", " if y in lean_r_lakes:\n", " sim_election = lean_r_lakes_sim\n", " if y in lean_d_lakes:\n", " sim_election = lean_d_lakes_sim\n", " if y in tossups:\n", " sim_election = np.random.uniform()*100\n", " if x > sim_election:\n", " print('Won',y,'for',z,'electoral college votes')\n", " ec_total += z\n", "print()\n", "print('Final Results:',ec_total,'electoral college votes')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running 20,000 Simulations" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "def electoral_college(ec, cand, state, sims=10):\n", " cand_wins = 0\n", " cand_ec_total = []\n", " cand_states = []\n", " for i in range(sims):\n", " cand_ec = 0\n", " cand_state = []\n", " sim_election = np.random.uniform(low=0.05)*100\n", " lean_r_west_sim = np.random.uniform()*100\n", " lean_d_west_sim = np.random.uniform()*100\n", " lean_r_lakes_sim = np.random.uniform()*100\n", " lean_d_lakes_sim = np.random.uniform()*100\n", " for x, y, z in zip(cand, states, ec):\n", " if y in swing_states:\n", " if y in lean_r_west:\n", " sim_election = lean_r_west_sim\n", " if y in lean_d_west:\n", " sim_election = lean_d_west_sim\n", " if y in lean_r_lakes:\n", " sim_election = lean_r_lakes_sim\n", " if y in lean_d_lakes:\n", " sim_election = lean_d_lakes_sim\n", " if y in tossups:\n", " sim_election = np.random.uniform()*100 \n", " if x > sim_election:\n", " cand_ec += z\n", " cand_state.append(y)\n", " cand_ec_total.append(cand_ec)\n", " cand_states.append(cand_state)\n", " if cand_ec > 269:\n", " cand_wins += 1\n", " return cand_wins, cand_ec_total, cand_states" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Monte Carlo Simulation of Electoral College Results\n", "\n", "Clinton Win Prob: 65.945\n", "Electoral College Results: Clinton 279\n", "Sim Percent Outcome: 0.0198\n", "\n", "Trump Win Prob: 22.335\n", "Electoral College Results: Trump 235\n", "Sim Percent Outcome: 0.01955\n" ] } ], "source": [ "print(\"Monte Carlo Simulation of Electoral College Results\")\n", "print()\n", "sims = 20000\n", "ec = list(df.ec.values)\n", "states = list(df.state.values)\n", "cand_1 = list(df['clinton_rcp_prob'].values)\n", "cand_1_wins, cand_1_ec_totals, cand_1_states = electoral_college(ec, cand_1, states, sims=sims)\n", "print('Clinton Win Prob:', (cand_1_wins/sims)*100)\n", "for i,j in Counter(cand_1_ec_totals).most_common(n=1):\n", " print('Electoral College Results: Clinton',i)\n", " print('Sim Percent Outcome:',j/20000)\n", "print()\n", "cand_2 = list(df['trump_rcp_prob'].values) \n", "cand_2_wins, cand_2_ec_totals, cand_2_states = electoral_college(ec, cand_2, states, sims=sims)\n", "print('Trump Win Prob:', (cand_2_wins/sims)*100)\n", "for i,j in Counter(cand_2_ec_totals).most_common(n=1):\n", " print('Electoral College Results: Trump',i)\n", " print('Sim Percent Outcome:',j/20000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Top 5 Results for Each Candidate" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Electoral College Results: Clinton 279\n", "Sim Percent Outcome: 0.0198\n", "Electoral College Results: Clinton 303\n", "Sim Percent Outcome: 0.01715\n", "Electoral College Results: Clinton 288\n", "Sim Percent Outcome: 0.01685\n", "Electoral College Results: Clinton 294\n", "Sim Percent Outcome: 0.01485\n", "Electoral College Results: Clinton 287\n", "Sim Percent Outcome: 0.0143\n" ] } ], "source": [ "for i,j in Counter(cand_1_ec_totals).most_common(n=5):\n", " print('Electoral College Results: Clinton',i)\n", " print('Sim Percent Outcome:',j/20000)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Electoral College Results: Trump 235\n", "Sim Percent Outcome: 0.01955\n", "Electoral College Results: Trump 259\n", "Sim Percent Outcome: 0.01855\n", "Electoral College Results: Trump 250\n", "Sim Percent Outcome: 0.0175\n", "Electoral College Results: Trump 230\n", "Sim Percent Outcome: 0.0165\n", "Electoral College Results: Trump 219\n", "Sim Percent Outcome: 0.0163\n" ] } ], "source": [ "for i,j in Counter(cand_2_ec_totals).most_common(n=5):\n", " print('Electoral College Results: Trump',i)\n", " print('Sim Percent Outcome:',j/20000)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(18,8))\n", "plt.hist(cand_2_ec_totals,500)\n", "plt.hist(cand_1_ec_totals,500)\n", "plt.axvline(x=270, color='k', linestyle='dashed')\n", "plt.title('Simulation Results')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Actual 2016 Electoral College Results\n", "\n", "![final](https://raw.githubusercontent.com/ahoaglandnu/election/master/images/final.png)\n", "\n", "### Conclusion\n", "\n", "The simulation gives us more reasonable probabilities for each candidate but does not overcorrect to replicate the 2016 Electoral College results. The polling errors in Wisconsin, Pennsylvania, and Michigan would have to have been identified **prior** to running simulations when assigning probabilities to each state. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }