**11/8/16 Note:** Hey, so when I was rerunning my model on election day, I noticed a serious error. I accidentally had Clinton and Trump’s numbers swapped in West Virginia. There is an extremely low chance of Clinton winning there. It has been corrected now. It didn’t change the prediction much, but did drop her probability from 91% to 86% in the original prediction. I reran the numbers with today’s averages and it’s up to 96%.

**11/9/16 Note:** Turns out the title of this post is very, very wrong and I should not have loved these polls.

### Time to Make a Prediction

Here we are, just two more sleeps until the 2016 Presidential election, maybe the most terrifying election in my lifetime. How am I dealing with this anxiety? I’m becoming obsessed with polling and prediction modeling. It hasn’t really helped, but I have learned a lot about how people like Nate Silver and Nate Cohn, and people not named Nate I’m sure, make educated guesses about who’s going to win the highest office in the land.

I decided a few days ago that I wanted to try to make my own. The problem is that I decided way too late to get a good handle on the complex nature of election modeling. Maybe I’ll try to put together a more complex model for future elections, but I created one for this year that takes a simple approach to modeling possible error on polling averages. I used this model to make a state-by-state prediction on who will win this election.

### The Model

Before I go any further, let me reiterate: this is a very simple model for something as complex as election prediction. To state (what should be) the obvious, polling is the best predictor for who will win a presidential election. Between 1968 and 2012, the absolute error between poll averages and actual election results ranged from 0.1% (1992) and 7.2% (1980), with a standard deviation of 1.99%. That’s pretty good, considering all of the factors that push around that single day in November. I decided to start here and model arbitrary polling error ranges.

The model (written in Python, with code below) looks at state-by-state polling averages and uses a pseudo Monte Carlo method. It first applies a random shift within a specified error range to the polling average in the state, then compares the adjusted average and determines a winner. If the candidate has a higher randomly adjusted polling average, the candidate wins the state and the electoral vote number is added to their total. If the candidate wins 270 or more, they win the election. The model writes each final electoral vote count to a text file, and the percentage of winning outcomes per state is written to a second. This allows me to make a prediction.

For my primary test, I used a an absolute polling error range of 5% and statewide polling averages from November 5th, 2016 (sorry for the 1-day delay, but I don’t think they’ve changed much). A 5% polling error is *pretty* high. It’s about 2.5 times the standard deviation of historical polling error. I simulated the election 10,000 times.

Fairly simple. I’m basically just converting polling averages into win probabilities. I’m hoping something this simple will show accurate results on election night.

### Who Will be the 45th President of the U.S.?

According to my test, the next President of the United States will be:

#### Hillary Clinton – 86.2% – 293 Electoral Votes

#### Electoral Map

Missing from this map are the split districts: ME 1st (100%, Clinton), ME 2nd (61% Trump), NE 1st (100% Trump), NE 2nd (92.83 % Trump), and NE 3rd (100% Trump).

#### Electoral College Outcomes

Clinton won the election 86% of the 10,000 simulations with an average Electoral Vote count of 293. Specifically, Clinton won 8,625 times, Trump won 1227 times, and there were 149 ties.

This histogram shows the number of electoral college outcomes in the 10,000 simulations by final electoral votes by candidate. You can see here that Clinton has far more positive outcomes than Trump.

For my main simulations, the arbitrary polling error was set at 5%. I wondered what happens to her chances at victory as that absolute error grows or shrinks. I ran the script 50 times, simulating errors ranging from 1% to 50% (remember, more than 7-8% is unheard of in modern polling averages. The results can be seen in the chart below:

#### Chance of Clinton Victory by Simulated Polling Error

At an imagined 50% polling error (which is totally ridiculous), she still has a 61.26% shot at winning the White House. If her position we weaker, we would expect her odds to drop to 50% much faster. It seems to me that, statistically, she’s got this in the bag.

### Final Thoughts

Let me stress one more time that this only simulates an arbitrary range of possible polling errors. Clinton won this because she clearly has the edge in polling. We’re seeing consistent results across the board because we’re assuming a standard polling error across all states, not each state individually. If there is a large polling error in a single state (say, Pennsylvania or New Hampshire) but not others we could see a totally different outcome.

Another thing to note is that the model is extremely close in a state like Nevada (currently 49.92% to 50.08%). This is so absurdly close (0.16%) that I imagine it could go either way. If I were to include early voting in my equation, it could easily look like Clinton is winning there and in Florida as well. Alas, my quick model is not designed to handle that. I would not be surprised if Clinton won Nevada, North Carolina, and Florida. I would be surprised if she won other swing states like Ohio and Iowa. I would be *shocked* if she won Arizona.

My model is also not designed to account for major news stories that drop while I’m writing this up. My model puts her at winning 293 electoral votes to Trump’s 245. I would not be surprised in the least if she outperforms that by a large margin.

My results seem to fall in line with models like PredictWise, the Princeton Election Consortium, Daily Kos, and the Huffington Post. It looks somewhat like the New York Times. My prediction do not look like FiveThirtyEight, which is far more conservative than anything else out there. Nate Silver’s model is, obviously, far more sophisticated. He still gives Clinton a 64.5% chance of winning as of this writing. This corresponds to a 38% absolute polling polling error in my model. I guess if (when) Clinton wins, we’ll all be correct. ¯\_(ツ)_/¯

I’ll write an assessment up on Tuesday night or Wednesday. I hope I can make it that long.

### Update, Clarification, Reiteration – 11/7/16

Alright, some people have taken issue with the methods here, which often happens when you make any kind of prediction about a thing people care about and open your formula to the public. There are a lot of fair criticisms that can be made if this were a true prediction model. Let me reiterate that this model does not take into account trends or correlate polling error across different states or account for individual state polling errors or individual poll margins of error. I’m also not doing anything to correct for polling missteps, like underpolling certain demographics. It imagines a world where each state’s polling error is completely independent and completely random (it’s not). All this model does is take current (well, now old) polling averages, imagine an arbitrary polling error range, and apply the error range independently to each state. As I stated above, **what I am essentially doing is just converting current polling averages to win probabilities by simulation**. My final electoral map is just a reflection of the current polls, and I don’t think that’s a bad thing. The states each candidate won in my model are the states where they are up in the polls. It’s super simple for four reasons:

**1)** I decided to do this 3 days before the election and thus didn’t have time to write and test all of the other variables that might be pertinent

**2)** it’s super simple by design because I don’t want to be guilty of making biased assumptions that I have no business making

**3)** I’m really just interested in how polling error might affect the deviation between Clinton and Trump’s polling averages, and how that might affect the election

**4)** I’m just learning here–I’m not an authority, this is not authoritative, and I’m doing this for fun.

I think it’s very likely that Clinton will win Nevada. It looks pretty likely that she’ll win North Carolina as well. Florida may be a true toss-up. I do not believe she will lose any of the states that my model currently shows her winning. But those are just my *feelings*, and I don’t currently have the data and analysis to back that up.

### Election Day update, for due diligence – 11/8/16

I’ve updated the final poll averages for this Election Day and have a new number. Hillary Clinton’s numbers have gone up over the past couple days. This model now puts her final probability at **96%** with **306 Electoral Votes**. She won 9601, lost 356, and tied 44 simulations.

In this map, Clinton’s probability of winning some key swing states increased to put her over the top. Florida increased to 56.9%, North Carolina to 57.4%, New Hampshire to 86.1%, and Nevada to 63.1%. Remember, if she maintains the “blue wall” in this election, she only needs to win one of those states to get over 270. Things are looking pretty good for her right now. The first big round of poll closings happens in a few hours.

Sorry that the percents aren’t formatted correctly. I’m doing this *very* quickly.

### Update – 11/9/16

**12:29 AM – ** I don’t even know what to say. I don’t think anyone knows what to say.

**8:15 AM – ** I’m looking into what might have gone wrong with the poll averages. It looks right now like the final polling error is going to fall somewhere around 4%. I suspect that the polling error by state is going be huge in some places. Clinton managed to over-perform in a lot of places, but none of them were swing states. Trump pretty much beat expectations everywhere. There’s going to be a lot of soul-searching and hand wringing among pollsters and statisticians, and people like me who ran with the numbers and made a very, very wrong prediction. It looks like Trump is going to win the electoral vote, but arguably not by much of a mandate. Interestingly, Clinton is likely to walk away with the popular vote–only the fifth time in history a candidate has lost the electoral vote but won the popular vote (the last one being the infamous Bush/Gore election of 2000).

### The Code

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
import random ######################################## Set Parameters ################################################################ # Trump/Clinton polling averages ClintonAvg = {'AL': .365, 'AK': .406, 'AZ': .449, 'AR': .368, 'CA': .584, 'CO': .473, 'CT': .523, 'DE': .527, 'DC': .832, 'FL': .479, 'GA': .451, 'HI': .585, 'ID': .352, 'IL': .536, 'IN': .405, 'IA': .454, 'KS': .388, 'KY': .376, 'LA': .394, 'ME': .495, 'ME1': .530, 'ME2': .456, 'MD': .605, 'MA': .575, 'MI': .483, 'MN': .489, 'MS': .402, 'MO': .414, 'MT': .367, 'NE': .358, 'NE1': .369, 'NE2': .444, 'NE3': .260, 'NV': .467, 'NH': .468, 'NJ': .535, 'NM': .446, 'NY': .576, 'NC': .479, 'ND': .336, 'OH': .458, 'OK': .332, 'OR': .512, 'PA': .492, 'RI': .534, 'SC': .441, 'SD': .368, 'TN': .407, 'TX': .420, 'UT': .270, 'VT': .594, 'VA': .497, 'WA': .529, 'WV': .333, 'WI': .492, 'WY': .269} TrumpAvg = {'AL': .584, 'AK': .482, 'AZ': .484, 'AR': .569, 'CA': .361, 'CO': .441, 'CT': .414, 'DE': .407, 'DC': .127, 'FL': .482, 'GA': .500, 'HI': .342, 'ID': .565, 'IL': .410, 'IN': .526, 'IA': .484, 'KS': .523, 'KY': .567, 'LA': .560, 'ME': .435, 'ME1': .405, 'ME2': .468, 'MD': .341, 'MA': .351, 'MI': .446, 'MN': .441, 'MS': .554, 'MO': .526, 'MT': .529, 'NE': .560, 'NE1': .547, 'NE2': .487, 'NE3': .657, 'NV': .467, 'NH': .449, 'NJ': .422, 'NM': .392, 'NY': .376, 'NC': .481, 'ND': .573, 'OH': .484, 'OK': .604, 'OR': .427, 'PA': .458, 'RI': .402, 'SC': .512, 'SD': .540, 'TN': .540, 'TX': .518, 'UT': .382, 'VT': .332, 'VA': .448, 'WA': .409, 'WV': .608, 'WI': .451, 'WY': .641} # Number of election simulations to run iterations = 10000 # Absolute polling error to test (limit to +/- absolute error) AbsError = 0.05 # Output electoral vote text file outtext = r'D:\ElectionPrediction\EVout.txt' # Output states won text file wintext = r'D:\ElectionPrediction\wintext.txt' # Fixed Variables - Do not edit states = ['AL','AK','AZ','AR','CA','CO','CT','DE','DC','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','ME1','ME2', 'MD','MA','MI','MN','MS','MO','MT','NE','NE1','NE2','NE3','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA', 'RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY'] stateEVs = {'AL': 9, 'AK': 3, 'AZ': 11, 'AR': 6, 'CA': 55, 'CO': 9, 'CT': 7, 'DE': 3, 'DC': 3, 'FL': 29, 'GA': 16, 'HI': 4, 'ID': 4, 'IL': 20, 'IN': 11, 'IA': 6, 'KS': 6, 'KY': 8, 'LA': 8, 'ME': 2, 'ME1': 1, 'ME2': 1, 'MD': 10, 'MA': 11, 'MI': 16, 'MN': 10, 'MS': 6, 'MO': 10, 'MT': 3, 'NE': 2, 'NE1': 1, 'NE2': 1, 'NE3': 1, 'NV': 6, 'NH': 4, 'NJ': 14, 'NM': 5, 'NY': 29, 'NC': 15, 'ND': 3, 'OH': 18, 'OK': 7, 'OR': 7, 'PA': 20, 'RI': 4, 'SC': 9, 'SD': 3, 'TN': 11, 'TX': 38, 'UT': 6, 'VT': 3, 'VA': 13, 'WA': 12, 'WV': 5, 'WI': 10, 'WY': 3} stateWins = {'AL': [], 'AK': [], 'AZ': [], 'AR': [], 'CA': [], 'CO': [], 'CT': [], 'DE': [], 'DC': [], 'FL': [], 'GA': [], 'HI': [], 'ID': [], 'IL': [], 'IN': [], 'IA': [], 'KS': [], 'KY': [], 'LA': [], 'ME': [], 'ME1': [], 'ME2': [], 'MD': [], 'MA': [], 'MI': [], 'MN': [], 'MS': [], 'MO': [], 'MT': [], 'NE': [], 'NE1': [], 'NE2': [], 'NE3': [], 'NV': [], 'NH': [], 'NJ': [], 'NM': [], 'NY': [], 'NC': [], 'ND': [], 'OH': [], 'OK': [], 'OR': [], 'PA': [], 'RI': [], 'SC': [], 'SD': [], 'TN': [], 'TX': [], 'UT': [], 'VT': [], 'VA': [], 'WA': [], 'WV': [], 'WI': [], 'WY': []} ######################################### Functions #################################################################### # Generate random polling error def randPollError(low, high): randError = random.uniform(low, high) return randError # Simulate election in a state def simElection(rawerror, cand1, cand2, stateEVs): error = (rawerror/2) newCand1 = cand1 + error newCand2 = cand2 - error if newCand1 > newCand2: return stateEVs else: return 0 # Check if candidate won def checkWin(EVoteTotal): if EVoteTotal > 270: return "Win" elif EVoteTotal == 269: return "Tie" else: return "Loss" # Simple calculate average in list, for calculating average wins in state simulations def avgWins(wins): avg = float(sum(wins)) / float(len(wins)) return avg # Main loop def mainLoop(states, stateEVs, cand1AVG, cand2AVG): i = 0 w = 0 t = 0 l = 0 totals = [] tally = [] while i <= iterations: EVoteTotal = 0 for state in states: newEVs = int((simElection(randPollError(-(AbsError), AbsError), cand1AVG[state], cand2AVG[state], stateEVs[state]))) EVoteTotal = EVoteTotal + newEVs if newEVs > 0: stateWins[state].append(1) else: stateWins[state].append(0) totals.append(EVoteTotal) tally.append(checkWin(EVoteTotal)) i = i + 1 for item in tally: if item == 'Win': w = w + 1 elif item == 'Tie': t = t + 1 else: l = l + 1 print("Wins: " + str(w) + " Ties: " + str(t) + " Losses: " + str(l)) print("Average EV Count: " + str(sum(totals) / len(totals))) print("Odds of a Clinton win: " + (str(float(w) / (float(w) + float(t) + float(l))))) with open(outtext, 'w') as f: for total in totals: f.write(str(total) + '\n') with open(wintext, 'w') as f: for state in states: f.write(state + "," + str(avgWins(stateWins[state])) + "," + str(stateEVs[state]) + '\n') ############################################## Run Model ############################################################### mainLoop(states, stateEVs, ClintonAvg, TrumpAvg) |

## Leave a Reply

Be the First to Comment!