No, the Alabama Special Election Was Not Rigged

A quick logistical note: I have rewritten some of my code to make it easier to follow along at home (if you’re into that sort of thing) The bulk of the analysis code is contained in a file called election_analysis.py, which defines several Python classes that make pretty plots and do machine learning. If you’d like to reproduce the plots or results in any of my blog posts, just head to the scripts folder in my GitHub and download the appropriate script (for instance, this post’s script is located here) along with election_analysis.py. Then you should just be able to run the script directly (assuming you have the proper dependencies installed) and the plots should be made. You’ll have to do a bit of handholding if you want to reproduce everything perfectly, but if you’ve gotten to that point I think you can probably figure it out yourself. I haven’t finished writing all of the scripts quite yet, but expect that to be done in the next couple of weeks.

Back to your regularly scheduled programming

As I mentioned previously, Democrats are coming into the 2018 midterm elections with a fair amount of wind in their sails due to a string of high-profile victories in 2017. Not the least of these was the surprise election of Doug Jones over Roy Moore in the race for the Alabama’s Senate seat vacated by Jeff Sessions. But even after Jones’s victory, Roy Moore made claims that “it’s not over” and claimed large-scale voter fraud may have pushed several important Alabama counties to Jones.

Fortunately for Roy Moore, he doesn’t have to speculate wildly- the election data is public, and I’m here to help him understand what actually happened.

As you may recall from reading my first blog post, I’ve looked at whether there was vote fraud in the 2016 presidential election (although in that case, I was concerned more about Russian interference than in-person fraud). So I already had the framework of an analysis written, and I just needed the data from the Alabama election.

I scraped the official election results from Alabama’s Secretary of State helpful spreadsheet, which lists the vote tally on a county-by-county basis. Here’s what the data looks like:

Figure 1: Alabama special election results, 2017. Click to download the image.
Figure 1: Alabama special election results, 2017. Click to download the image.


Then, I used a simple linear regression on about 50 different demographic variables to predict the vote share in each county (just like I did before). I also tried using a neural net, but Alabama only has 67 counties and it didn’t seem to be enough to train successfully on. In any case, the linear regression gave very reasonable results so I am going to stick with it.

The same caveat applies here as did previously- you should really think of this analysis as outlier detection instead of true prediction. So extremely wide-spread vote fraud would be difficult to detect, because there wouldn’t be any outliers. But as a check of internal self-consistency, I think this works pretty well:

Figure 2: Residuals (data-model) from a neural network trained on the Alabama 2017 special election results. The results appear completely random as far as I can tell, which indicates that nothing suspicious was going on in Alabama. Click to download the image.
Figure 2: Residuals (data-model) from a neural network trained on the Alabama 2017 special election results. The results appear completely random as far as I can tell, which indicates that nothing suspicious was going on in Alabama. Click to download the image.


As you might have expected, the residuals of the model versus the data are reasonably small in magnitude and don’t show any spatial patterns that would be consistent with voter fraud.

Figure 3: Comparison of the 2016 presidential election and 2017 special election results in Alabama. As usual, each bubble represents a county, and the size of the bubble represents the county population. The bubbles are colored by their vote in 2016. Click to download the image.
Figure 3: Comparison of the 2016 presidential election and 2017 special election results in Alabama. As usual, each bubble represents a county, and the size of the bubble represents the county population. The bubbles are colored by their vote in 2016. Click to download the image.


One interesting trend that I found when exploring the data is shown in Figure 3 above, where I compared the change in vote between 2016 and 2017 to the vote in 2016. There are two takeaways:

  1. All the counties have a y-value below zero, in other words every single county in Alabama went more Democratic than in the 2016 election. Not a particularly surprising result given how poor a candidate Roy Moore was (although, I wonder if you couldn’t say the same thing about Donald Trump).
  2. There’s a pronounced dip in the center of the diagram, indicating that voters in “swing” counties were the most likely to change their vote from Republican to Democrat between 2016 and 2017. I think the interpretation is straightforward- Roy Moore couldn’t lose much support in counties that already voted strongly in favor of the Democrats, and strongly Republican counties were more likely to stick to their man. But counties that fall in the center of the political spectrum were especially turned off by Roy Moore.

The conclusion? I see no evidence that the results of the Alabama special election are anything but consistent with the idea that the people of Alabama simply wanted a Democrat in the Senate. Roy Moore, it’s time to concede.