---
title: "State and National Poll Aggregation"
author: Pierre-Antoine Kremp
output: 
  html_document:
    theme: readable
    highlight: tango
---

Twitter: [`@pakremp`](http://twitter.com/pakremp)

---

New: [What is the probability that your vote will decide the election?](http://pkremp.github.io/pr_decisive_vote.html) (with Andrew Gelman). R code available [here](https://github.com/pkremp/polls/blob/master/pr_decisive_vote.R).

New: [Updating the Forecast on Election Night with R](http://pkremp.github.io/update_prob.html). R code available [here](https://github.com/pkremp/polls/blob/master/update_prob.R).

---

```{r echo=FALSE, message=FALSE}
setwd("~/GitHub/polls")
knitr::read_chunk('graphs.R')
```

```{r echo=FALSE, message=FALSE}
<<read_data_create_functions>>
```



Last update: `r paste(format(time_lastrun, format = "%A, %B %e, %l:%M%P", tz = "US/Eastern"), "ET") %>% gsub("  ", " ", .)`.

---

This is a Stan implementation of Drew Linzer's dynamic Bayesian election forecasting model, with some tweaks to incorporate national poll data, pollster house effects, correlated priors on state-by-state election results and correlated polling errors. 

For more details on the original model: 

Linzer, D. 2013. "Dynamic Bayesian Forecasting of Presidential Elections in the States." _Journal of the American Statistical Association_. 108(501): 124-134.  [(link)](http://votamatic.org/wp-content/uploads/2013/07/Linzer-JASA13.pdf)

The Stan and R files are available [here](http://github.com/pkremp/polls).

---

`r nrow(df)` polls available since `r format(as.Date(start_date), format = "%B %d, %Y")`
(including `r nrow(df[df$state != "--",])` state polls and `r nrow(df[df$state == "--",])` national polls).

---

# Electoral College 

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<plot_ev>>
```

Note: the model does not account for the specific electoral vote allocation rules in place in Maine and Nebraska.


# National Vote 

This graph shows Hillary Clinton's share of the Clinton and Trump national vote, derived from the weighted average of latent state-by-state vote intentions (using the same state weights as in the 2012 presidential election, adjusted for state adult population growth between 2011 and 2015). In the model (described below), national vote intentions are defined as:

$$\pi^{clinton}[t, US] = \sum_{s \in S} \omega_s \cdot \textrm{logit}^{-1} (\mu_a[t] + \mu_b[t, s])$$

The thick line represents the median of posterior distribution of national vote intentions; the light blue area shows the 90% credible interval. The thin blue lines represent 100 draws from the posterior distribution. The fundamentals-based prior is shown with the dotted black line.

<!--
From today to November 8, Hillary Clinton's share of the national vote is predicted to shrink partially towards the fundamentals-based prior (shown with the dotted black line).
-->

Each national poll (raw numbers, unadjusted for pollster house effects) is represented as a dot (darker dots indicate narrower margins of error). On average, Hillary Clinton's national poll numbers seem to be running slightly below the level that would be consistent with the latent state-by-state vote intentions.

<!-- Hillary Clinton's national poll numbers seem to be running about 
`r round(((inv_logit(logit(pred$p[pred$t == all_t[length(all_t)]  & pred$state == "--"])) - inv_logit(logit(pred$p[pred$t == all_t[length(all_t)] & pred$state == "--"]) + median(alpha))))*100, 1)` point below the level that would be consistent with the latent state-by-state vote intentions.
-->

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<plot_national>>
```



# State Vote 

The following graphs show vote intention by state (with 100 draws from the posterior distribution represented as thin blue lines):

$$\pi^{clinton}[t,s] = \textrm{logit}^{-1} (\mu_a[t] + \mu_b[t, s])$$

States are sorted by predicted Clinton score on election day.

```{r echo=FALSE, message=FALSE, fig.width = 8, fig.height = 5, fig.align='center'}
<<plot_states>>
```

# Current Vote Intentions and Forecast By State


```{r echo=FALSE, message=FALSE}
<<table_predictions>>
```

# State-by-State Probabilities 

```{r echo=FALSE, message=FALSE, fig.width = 5, fig.height = 8, fig.align='center'}
<<plot_state_probabilities>>
```


# Map

```{r echo=FALSE, message=FALSE, fig.width = 9, fig.height = 4.5, fig.align='center'}
<<map>>
```

# Pollster House Effects

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<plot_house_effects>>
```

Most pro-Clinton polls:

```{r echo=FALSE, message=FALSE}
<<polls_most_pro_clinton>>
```

Most pro-Trump polls:

```{r echo=FALSE, message=FALSE}
<<polls_most_pro_trump>>
```

# Discrepancy between national polls and weighted average of state polls

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<alpha>>
```

# Data 

The [`runmodel.R`](http://github.com/pkremp/polls/runmodel.R) R script downloads state and national polls from the [HuffPost Pollster website](http://http://elections.huffingtonpost.com/pollster) as `.csv` files before processing the data.

The model ignores third-party candidates and undecided voters.
I restrict each poll's sample to respondents declaring vote intentions for Clinton or Trump, so that $N = N^{clinton} + N^{trump}$. (This is problematic for Utah).

When multiple polls are available by the same pollster, at the same date, and for the same state, I pick
polls of likely voters rather than registered voters, and polls for which $N^{clinton} + N^{trump}$ is
the smallest (assuming that these are poll questions in which respondents are given the option to choose a
third-party candidate, rather than questions in which respondents are only asked to choose between the two leading candidates). 

Polls by the same pollster and of the same state with partially overlapping dates are dropped so that only non-overlapping polls are retained, starting from the most recent poll.

To account for the fact that polls can be conducted over several days, I set the poll date to the midpoint between the day the poll started and the day it ended.

# Model 

The model is in the file [`state and national polls.stan`](http://github.com/pkremp/polls/state and national polls.stan). It has a backward component, which aggregates poll history to derive unobserved latent vote intentions; and a forward component, which predicts how these unobserved latent vote intentions will evolve until election day. The backward and forward components are linked through priors about vote intention evolution: in each state, latent vote intentions follow a reverse random walk in which vote intentions "start" on election day $T$ and evolve in random steps (correlated across states) as we go back in time. The starting point of the reverse random walk is the final state of vote intentions, which is assigned a reasonable prior, based on the Time-for-change, fundamentals-based electoral prediction model. The model reconciles the history of state and national polls with prior beliefs about final election results and about how vote intentions evolve.

## Backward Component: Poll Aggregation

For each poll $i$, the number of respondents declaring they intended to vote for 
Hillary Clinton $N^{clinton}_i$ is drawn from a binomial distribution:

$$
N^{clinton}_i \sim \textrm{Binomial}(N_i, \pi^{clinton}_i)
$$

where $N_i$ is poll sample size, and $\pi^{clinton}_i$ is share of the
Clinton vote for this poll.

The model treats national and state polls differently.

### State polls 

If poll $i$ is a state poll, I use a day/state/pollster multilevel model:

$$\textrm{logit} (\pi^{clinton}_i) = \mu_a[t_i] + \mu_b[t_i, s_i] + \mu_c[p_i] + u_i + e[s_i]$$

What this model does is simply to decompose the log-odds of reported vote intentions towards Hillary Clinton $\pi^{clinton}_i$ into a national component, shared across all states ($\mu_a$), a state-specific component ($\mu_b$), a pollster house effect ($\mu_c$), a poll-specific measurement noise term ($u$), and a polling error term ($e$) shared across all polls of the state (the higher $e$, the more polls overestimate Hillary Clinton's true score).

On the day of the last available poll $t_{last}$, the national component $\mu_a[t_{last}]$ is set to zero, so that the predicted share of the Clinton vote in state $s$ (net of pollster house effects and measurement noise) after that date and until election day $T$ is: 

$$\pi^{clinton}_{ts} = \textrm{logit}^{-1} (\mu_b[t, s])$$

To reduce the number of parameters, the model only takes weekly values for $\mu_b$, so that: 

$$\mu_b[t, s] = \mu_b^{weekly}[w_t, s]$$

where $w_t$ is the week of day $t$.

### National polls 

If poll $i$ is a national poll, I use the same multilevel approach (with random intercepts for pollster house effects $\mu_c$) but I add a little tweak: the share of the Clinton vote in a national poll should also reflect the weighted average of state-by-state scores at the time of the poll. I model the share of vote intentions in national polls in the following way:

$$\textrm{logit} (\pi^{clinton}_i) =  \textrm{logit}\left( \sum_{s \in \{1 \dots S\}} \omega_s \cdot \textrm{logit}^{-1} (\mu_a[t_i] + \mu_b^{weekly}[w_{t_i}, s] + e[s]) \right) + \alpha + \mu_c[p_i] + u_i$$

where $\omega_s$ represents the share of state $s$ in the total votes of the set of polled states $1 \dots S$ (based on 2012 turnout numbers adjusted for adult population growth in each state between 2011 and 2015). The $\alpha$ parameter corrects for possible discrepancies between national polls and the weighted average of state polls. Possible sources of discrepancies may include: 

* the fact that when polls are not available for all states, polled states can be on average more blue or more red than the country as a whole (not a problem since the first 50-state Washington Post/SurveyMonkey poll in early September); 
* changes in state weights since 2012; 
* any possible (time-invariant) bias in national polls relative to state polls. 

The idea is that while national poll _levels_ may be off and generally not very indicative of the state of the race, national poll _changes_ may contain valuable information to update $\mu_a$ and (to a lesser extent) $\mu_b$ parameters.

### How vote intentions evolve

In order to smooth out vote intentions by state and obtain latent vote intentions at dates in which no polls were conducted, I use 2 reverse random walk priors for $\mu_a$ and $\mu_b^{weekly}$ from $t_{last}$ to April 1:

$$\mu_b^{weekly}[w_t-1, s] \sim \textrm{Normal}(\mu_b^{weekly}[w_t, s], \sigma_b \cdot \sqrt{7})$$

$$\mu_a[t-1]   \sim \textrm{Normal}(\mu_a[t], \sigma_a)$$

Both $\sigma_a$ and $\sigma_b$ are given uniform priors between 0 and 0.05. 

Their posterior marginal distributions are shown below. The median day-to-day total standard deviation of vote intentions is about `r round(sd(inv_logit(rnorm(1e4,0, sqrt(median(sigma_walk_a_past)^2 + median(sigma_walk_b_past)^2))))*100, 1)`%. The model seems to find that most of the changes in latent vote intentions are attributable to national swings rather than state-specific swings (national swings account on average for about `r round(median(sigma_walk_a_past)^2/(median(sigma_walk_a_past)^2 + median(sigma_walk_b_past)^2),2)*100`% of the total day-to-day variance). 

```{r echo=FALSE, message=FALSE, fig.width = 8, fig.height = 4, fig.align='center'}
<<sigma_walk>>
```



## Forward Component: Vote Intention Forecast

### Final outcome

I use a multivariate normal distribution for the prior of the final outcome. Its mean is based on the Time-for-Change model -- which predicts that Hillary Clinton should receive 48.6% of the national vote (based on Q2 GDP figures, the current President's approval rating and number of terms). The prior expects state final scores to remain on average centered around $48.6\% + \delta_s$, where $\delta_s$ is the excess Obama performance relative to the national vote in 2012 in state $s$.

$$\mu_b[T, 1 \dots S] \sim \textrm{Multivariate Normal}(\textrm{logit} (0.486 + \delta_{1 \dots S}), \mathbf{\Sigma})$$

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<priors>>
```

```{r echo=FALSE, message=FALSE, fig.align='center'}
<<correlation_states>>
```


For the covariance matrix $\mathbf{\Sigma}$, I set the variance to `r sigma_mu_b_end[1,1]` and the covariance to `r sigma_mu_b_end[1,2]` for all states and pairs of states -- which corresponds to a correlation coefficient of `r sigma_mu_b_end[1,2]/sigma_mu_b_end[1,1]` across states. 

* This prior is relatively imprecise as to the expected final scores in any given state; for example, in a state like Virginia, which Obama won by `r round(states2012["VA",]$score*100,1)`% in 2012 (a score identical to his national score), Hillary Clinton is expected to get `r round(inv_logit(mu_b_prior["VA"])*100,1)`% of the vote, with a 95% certainty that her score will not fall below `r round(quantile(inv_logit(m[,"VA"]), .025)*100)`% or exceed `r round(quantile(inv_logit(m[,"VA"]), .975)*100)`%. 

* State scores are also expected to be correlated with each other. For example, according to the prior (before looking at polling data), there is only a `r round(mean(m[,"TX"] > m[,"VA"])*100, 1)`% chance that Hillary Clinton will perform worse in Virginia than in Texas. If the priors were independent, this unlikely event could happen with a `r round(mean(m0[,"TX"] > m0[,"VA"])*100)`% probability.

```{r echo=FALSE, message=FALSE, fig.width = 8, fig.height = 4, fig.align='center'}
<<TX-VA-example>>
```

The covariance matrix implies that the correlation between the 2012 state scores and 2016 state priors is expected to be about `r round(median(rho),2)` (as opposed to `r round(median(rho0),2)` if covariances were set to zero). The simulated distribution of correlations between state priors and 2012 scores is in line with observed correlations of state scores with previous election results since 1988 [http://election.princeton.edu/2016/06/02/the-realignment-myth/].

```{r echo=FALSE, message=FALSE, fig.width = 8, fig.height = 4, fig.align='center'}
<<correlation_states_graph>>
```

To put it differently, the model does not have a very precise prior about final scores, but it does assume that most of this uncertainty is attributable to national-level swings in vote intentions. 


### How vote intentions evolve

From election day to the date of the latest available poll $t_{last}$, vote intentions by state "start" at $\mu_b[T,s]$ and follow a random walk with correlated steps across states:

$$\mu_b^{weekly}[w_t-1, 1 \dots S] \sim \textrm{Multivariate Normal}(\mu_b^{weekly}[w_t, 1 \dots S], \mathbf{\Sigma_b^{walk}})$$

I set $\mathbf{\Sigma_b^{walk}}$ so that all variances equal $`r sprintf(sqrt(sigma_walk_b_forecast[1,1]/7), fmt = "%0.3f")`^2 \times 7$ and all covariances equal `r sprintf(sigma_walk_b_forecast[1,2], fmt = "%0.5f")` ($\rho =$ `r sigma_walk_b_forecast[1,2]/sigma_walk_b_forecast[1,1]`). This implies a `r round(sd(inv_logit(rnorm(1e4, 0, sqrt(sigma_walk_b_forecast[1,1])/sqrt(7))))*100, 1)`% standard deviation in daily vote intentions changes in a state where Hillary Clinton's score is close to 50%. To put it differently, the prior is 95% confident that Hillary Clinton's score in any given state where she is currently polling around 50% should not move up or down by more than `r round(100*sqrt(as.numeric(election_day - Sys.Date())) * sd(inv_logit(rnorm(1e5, 0, sqrt(sigma_walk_b_forecast[1,1])/sqrt(7))))*1.96, 1)`% over the remaining `r as.numeric(election_day - Sys.Date())` days until the election. 

<!---
The graph below shows shows 3 random draws from the prior distribution of $mu_b$, to help visualize the assumptions regarding the forward component of the model.

```{r echo=FALSE, message=FALSE, fig.width = 8, fig.height = 4}
<<rnd_walk>>
```
--->

### Poll house effects

Each pollster $p$ can be biased towards Clinton or Trump:

$$\mu_c[p] \sim \textrm{Normal}(0, \sigma_c)$$

$$\sigma_c \sim \textrm{Uniform}(0, 0.1)$$

### Discrepancy between national polls and the average of state polls

I give the $\alpha$ parameter a prior centered around the observed distance of polled state voters
from the national vote in 2012 (this was useful until early September, when lots of solid red states had still not been polled and the average polled state voter was more pro-Clinton than the average US voter.): 

$$\bar{\delta_S} = \sum_{s \in \{1 \dots S\}} \omega_s \cdot \pi^{obama'12}_s - \pi^{obama'12}$$

$$\alpha \sim \textrm{Normal}(\textrm{logit} (\bar{\delta_S}), 0.2)$$

### Measurement noise

The measurement noise term $u_i$ is normally distributed around zero, with standard error $\sigma_u^{national}$ for national polls, and $\sigma_u^{state}$ for state polls. I give both standard errors a uniform distribution between 0 and 0.10.

$$\sigma_u^{national} \sim \textrm{Uniform}(0, 0.1)$$
$$\sigma_u^{state} \sim \textrm{Uniform}(0, 0.1)$$

### Polling error

To account for the possibility that polls might be off on average, even after adjusting for pollster house effects, the model includes a polling error term shared by all polls of the same state $e[s]$. For example, the presence of an unexpectedly large share of Trump voters (undetected by the polls) in a given state would translate into large positive $e$ values for that state. This polling error will remain unknown until election day; however it can be included in the form of an unidentified random parameter in the likelihood of the model, that increases the uncertainty in the posterior distribution of $\mu_a$ and $\mu_b$. 

Because I expect polling errors to be correlated across states, I use a multivariate normal distribution: 

$$e \sim \textrm{Multivariate Normal}(0, \mathbf{\Sigma_e})$$

To construct $\mathbf{\Sigma_e}$, I set the variance to $0.04^2$ and the covariance to 0.00175; this corresponds to a standard deviation of about 1 percentage point for a state in which Clinton's score is close to 50% (or a 95% certainty that polls are not off by more than 2 percentage points either way); and a 0.7 correlation of polling errors across states.

---

# Recently added polls 

```{r echo=FALSE, message=TRUE}
knitr::kable(last_polls, col.names = c("Entry Date", "Source", "State", "% Clinton / (Clinton + Trump)", "% Trump / (Clinton + Trump)", "N (Clinton + Trump)"))
```


# Convergence checks 


With 4 chains and 2000 iterations (the first 1000 iterations of each chain are discarded), the model runs in less than 15 minutes on my 4-core Intel i7 MacBookPro.

```{r echo=FALSE}
<<model_checks>>
```
