diff --git a/_assets/img/models/AZ_jul2.png b/_assets/img/models/AZ_jul2.png new file mode 100644 index 0000000..810840c Binary files /dev/null and b/_assets/img/models/AZ_jul2.png differ diff --git a/_assets/img/models/GA_jul2.png b/_assets/img/models/GA_jul2.png new file mode 100644 index 0000000..7b95d3a Binary files /dev/null and b/_assets/img/models/GA_jul2.png differ diff --git a/_assets/img/models/MI_jul2.png b/_assets/img/models/MI_jul2.png new file mode 100644 index 0000000..20ae05c Binary files /dev/null and b/_assets/img/models/MI_jul2.png differ diff --git a/_assets/img/models/NC_jul2.png b/_assets/img/models/NC_jul2.png new file mode 100644 index 0000000..6ff5949 Binary files /dev/null and b/_assets/img/models/NC_jul2.png differ diff --git a/_assets/img/models/NV_jul2.png b/_assets/img/models/NV_jul2.png new file mode 100644 index 0000000..dd00c2b Binary files /dev/null and b/_assets/img/models/NV_jul2.png differ diff --git a/_assets/img/models/PA_jul2.png b/_assets/img/models/PA_jul2.png new file mode 100644 index 0000000..6f2c5fa Binary files /dev/null and b/_assets/img/models/PA_jul2.png differ diff --git a/_assets/img/models/WI_jul2.png b/_assets/img/models/WI_jul2.png new file mode 100644 index 0000000..12b6668 Binary files /dev/null and b/_assets/img/models/WI_jul2.png differ diff --git a/_assets/objs/AZ_jul2_p_sample.bson b/_assets/objs/AZ_jul2_p_sample.bson new file mode 100644 index 0000000..0d78cda Binary files /dev/null and b/_assets/objs/AZ_jul2_p_sample.bson differ diff --git a/_assets/objs/GA_jul2_p_sample.bson b/_assets/objs/GA_jul2_p_sample.bson new file mode 100644 index 0000000..1f6c795 Binary files /dev/null and b/_assets/objs/GA_jul2_p_sample.bson differ diff --git a/_assets/objs/MI_jul2_p_sample.bson b/_assets/objs/MI_jul2_p_sample.bson new file mode 100644 index 0000000..cdbf94e Binary files /dev/null and b/_assets/objs/MI_jul2_p_sample.bson differ diff --git a/_assets/objs/NC_jul2_p_sample.bson b/_assets/objs/NC_jul2_p_sample.bson new file mode 100644 index 0000000..c3693bb Binary files /dev/null and b/_assets/objs/NC_jul2_p_sample.bson differ diff --git a/_assets/objs/NV_jul2_p_sample.bson b/_assets/objs/NV_jul2_p_sample.bson new file mode 100644 index 0000000..a836583 Binary files /dev/null and b/_assets/objs/NV_jul2_p_sample.bson differ diff --git a/_assets/objs/PA_jul2_p_sample.bson b/_assets/objs/PA_jul2_p_sample.bson new file mode 100644 index 0000000..dfcea23 Binary files /dev/null and b/_assets/objs/PA_jul2_p_sample.bson differ diff --git a/_assets/objs/WI_jul2_p_sample.bson b/_assets/objs/WI_jul2_p_sample.bson new file mode 100644 index 0000000..c1fa1f7 Binary files /dev/null and b/_assets/objs/WI_jul2_p_sample.bson differ diff --git a/_assets/objs/jul2_polls.bson b/_assets/objs/jul2_polls.bson new file mode 100644 index 0000000..8f972ec Binary files /dev/null and b/_assets/objs/jul2_polls.bson differ diff --git a/_assets/objs/jul_polls.bson b/_assets/objs/jul_polls.bson new file mode 100644 index 0000000..37025af Binary files /dev/null and b/_assets/objs/jul_polls.bson differ diff --git a/_assets/scripts/insert_jul.jl b/_assets/scripts/insert_jul.jl index 3a5962f..ec6d9a8 100644 --- a/_assets/scripts/insert_jul.jl +++ b/_assets/scripts/insert_jul.jl @@ -7,102 +7,101 @@ using Statistics using StatsPlots using Turing -# const DESIGN_ERROR = . - -@enum Month mar apr may jul jul aug sep oct nov +@enum Month mar apr may jul jul2 aug sep oct nov @enum Pollster begin ag aj am - bi - bi - bl - bl - cb - cb - cn - cn + bi2 + bi3 + bl2 + bl3 + cb2 + cb3 + cn2 + cn3 ea - ec - ec + ec2 + ec3 ep eu - fm - fm - fo - fo - hi - hi + fm2 + fm3 + fo2 + fo3 + hi2 + hi3 hp ia - ma - ma - mi - mi + ma2 + ma3 + mi2 + mi3 mq - mr - mr + mr2 + mr3 ns pp ny - qi - qi + qi2 + qi3 rr - si - si - sp - sp - su - su + si2 + si3 + sp2 + sp3 + su2 + su3 tr - wa - wa + wa2 + wa3 ws wsl wss yg end + @enum State PA GA NC MI AZ WI NV struct Poll - biden_support::Float - trump_support::Float - sample_size::Int + biden_support::Float64 + trump_support::Float64 + sample_size::Int64 end @load "../objs/jun_polls.bson" months -months[jul][AZ][bl] = [Poll(45,48,781)] -months[jul][AZ][ec] = [Poll(40,50,1000)] +months[jul][AZ][bl2] = [Poll(45,48,781)] +months[jul][AZ][ec2] = [Poll(40,50,1000)] months[jul][AZ][ia] = [Poll(44,49,800)] months[jul][AZ][pp] = [Poll(43,51,596)] months[jul][AZ][yg] = [Poll(37,44,900)] -months[jul][GA][bl] = [Poll(41,43,790)] -months[jul][GA][ec] = [Poll(48,41,1000)] -months[jul][GA][ia] = [Poll(42/,48,800)] +months[jul][GA][bl2] = [Poll(41,43,790)] +months[jul][GA][ec2] = [Poll(48,41,1000)] +months[jul][GA][ia] = [Poll(42,48,800)] months[jul][GA][yg] = [Poll(40,44,1000)] -months[jul][MI][bl] = [Poll(45,39,694)] -months[jul][MI][ec] = [Poll(42,45,1000)] +months[jul][MI][bl2] = [Poll(45,39,694)] +months[jul][MI][ec2] = [Poll(42,45,1000)] months[jul][MI][ep] = [Poll(36,42,600)] months[jul][MI][tr] = [Poll(43,45,1059)] months[jul][MI][yg] = [Poll(40,42,1000)] -months[jul][NC][bl] = [Poll(42,40,696)] -months[jul][NC][ec] = [Poll(41,48,1000)] +months[jul][NC][bl2] = [Poll(42,40,696)] +months[jul][NC][ec2] = [Poll(41,48,1000)] months[jul][NC][yg] = [Poll(40,44,1000)] -months[jul][NV][bl] = [Poll(39,45,452)] -months[jul][NV][ec] = [Poll(40,56,1000)] +months[jul][NV][bl2] = [Poll(39,45,452)] +months[jul][NV][ec2] = [Poll(40,56,1000)] months[jul][NV][ia] = [Poll(42,49,800)] months[jul][NV][yg] = [Poll(42,46,800)] -months[jul][PA][bl] = [Poll(44,51,794)] +months[jul][PA][bl2] = [Poll(44,51,794)] months[jul][PA][ia] = [Poll(45,49,800)] months[jul][PA][yg] = [Poll(40,43,1000)] -months[jul][PA][ec] = [Poll(43,48,1000)] +months[jul][PA][ec2] = [Poll(43,48,1000)] months[jul][PA][ny] = [Poll(43,47,1000)] -months[jul][WI][bl] = [Poll(47,44,695)] -months[jul][WI][ec] = [Poll(43,48,1000)] +months[jul][WI][bl2] = [Poll(47,44,695)] +months[jul][WI][ec2] = [Poll(43,48,1000)] months[jul][WI][ia] = [Poll(47,47,546)] months[jul][WI][ns] = [Poll(44,46,600)] months[jul][WI][yg] = [Poll(39,43,900)] diff --git a/_assets/scripts/insert_jul2.jl b/_assets/scripts/insert_jul2.jl new file mode 100644 index 0000000..2ba7503 --- /dev/null +++ b/_assets/scripts/insert_jul2.jl @@ -0,0 +1,99 @@ +using BSON: @save, @load +using CSV +using DataFrames +using LinearAlgebra +using PrettyTables +using Printf +using Serialization +using Statistics +using StatsPlots +using Turing + +@enum Month mar apr may jul jul2 aug sep oct nov + +@enum Pollster begin + ag + aj + am + bi2 + bi3 + bl2 + bl3 + cb2 + cb3 + cn2 + cn3 + ea + ec2 + ec3 + ep + eu + fm2 + fm3 + fo2 + fo3 + hi2 + hi3 + hp + ia + ma2 + ma3 + mi2 + mi3 + mq + mr2 + mr3 + ns + pp + ny + qi2 + qi3 + rr + si2 + si3 + sp2 + sp3 + su2 + su3 + tr + wa2 + wa3 + ws + wsl + wss + yg +end + +@enum State PA GA NC MI AZ WI NV + +struct Poll + biden_support::Float64 + trump_support::Float64 + sample_size::Int64 +end + + +@load "../objs/jul_polls.bson" months + +months[jul2][AZ][bl2] = [Poll(48,47,804)] +months[jul2][AZ][ec2] = [Poll(44,49,800)] +months[jul2][GA][bl2] = [Poll(47,47,799)] +months[jul2][GA][ec2] = [Poll(46,48,800)] +months[jul2][MI][bl2] = [Poll(53,42,706)] +months[jul2][MI][ec2] = [Poll(45,46,800)] +months[jul2][MI][fo2] = [Poll(43,45,1012)] +months[jul2][NC][bl2] = [Poll(46,48,706)] +months[jul2][NV][bl2] = [Poll(47,45,454)] +months[jul2][PA][bl2] = [Poll(46,50,804)] +months[jul2][PA][fo2] = [Poll(45,43,1034)] +months[jul2][PA][am] = [Poll(45,47,600)] +months[jul2][PA][ec2] = [Poll(46,48,850)] +months[jul2][WI][bl2] = [Poll(49,47,700)] +months[jul2][WI][ec2] = [Poll(47,47,854)] +months[jul2][WI][fo2] = [Poll(46,46,1046)] + + +# needs to be done manually rather than with include() +#@save "../objs/jul2_polls.bson" months + + diff --git a/_assets/scripts/insert_jul_pre.jl b/_assets/scripts/insert_jul_pre.jl index 3f67e32..c87ea2d 100644 --- a/_assets/scripts/insert_jul_pre.jl +++ b/_assets/scripts/insert_jul_pre.jl @@ -7,9 +7,7 @@ using Statistics using StatsPlots using Turing -# const DESIGN_ERROR = . - -@enum Month mar apr may jun jul aug sep oct nov +@enum Month mar apr may jun jul jul2 aug sep oct nov @enum Pollster begin ag @@ -109,6 +107,6 @@ months[jul][WI][yg] = [Poll(39,43,900)] # needs to be done manually rather than with include() -#@save "../objs/jul_pre_polls.bson" months +@save "../objs/jul_polls.bson" months diff --git a/_assets/scripts/polls.jl b/_assets/scripts/polls.jl index 3adf4ab..2b90393 100644 --- a/_assets/scripts/polls.jl +++ b/_assets/scripts/polls.jl @@ -1,18 +1,18 @@ @enum State PA GA NC MI AZ WI NV -@enum Month mar apr may jun jul aug sep oct +@enum Month mar apr may jun jul jul2 aug sep oct STATE = State -prior_month = "jun" -mon = jul -MON = "jul" -Mon = "jul" -st = "NV" -ST = NV +prior_month = "jul" +mon = jul2 +MON = "jul2" +Mon = "jul2" +st = "AZ" +ST = AZ -include("polls_head.jl") +#include("polls_head.jl") prior_poll = BSON.load("../objs/"*"$st"*"_"*"$prior_month"*"_p_sample.bson") -@load "../objs/"*"$MON"*"_pre_polls.bson" months +@load "../objs/"*"$MON"*"_polls.bson" months current_month = remove_empties(months[mon]) diff --git a/_assets/scripts/polls_head.jl b/_assets/scripts/polls_head.jl index 9130205..921e8b6 100644 --- a/_assets/scripts/polls_head.jl +++ b/_assets/scripts/polls_head.jl @@ -20,6 +20,10 @@ using Serialization using Statistics using StatsPlots using Turing + + + + #------------------------------------------------------------------ @@ -93,7 +97,7 @@ end struct Poll biden_support::Float64 trump_support::Float64 - sample_size::Int + sample_size::Int64 end #------------------------------------------------------------------ Month_names = Dict( @@ -102,12 +106,13 @@ Month_names = Dict( "may" => "May", "jun" => "June", "jul" => "July", + "jul2" => "July-post", "aug" => "August", "sep" => "September", "oct" => "October") #------------------------------------------------------------------ margins = CSV.read("../objs/margins.csv", DataFrame) -margin = first(margins[margins.st .== st, :pct]) +margin = first(margins[margins.st .== st, :pct]) #------------------------------------------------------------------ """ filter_empty_entries(dict::Dict{Pollster, Vector{Poll}}) -> Dict{Pollster, Vector{Poll}} @@ -197,7 +202,7 @@ function draw_density() fig = Figure(size = (600, 400)) # Add an axis to the figure - ax = Axis(fig[1, 1], xlabel = "Likelihood of Biden win", ylabel = "Number of draws", title = "Model: Biden results in $ST from 2020 election and polling through " * Month_names[Mon]) + ax = Axis(fig[1, 1], xlabel = "Likelihood of Harris win", ylabel = "Number of draws", title = "Model: Harris results in $ST from 2020 election and polling through " * Month_names[Mon]) # Plot the full density curve lines!(ax, kde_result.x, kde_result.density, color = "#a3b35c", linewidth = 3, strokewidth = 4, strokecolor = GREENBAR, label = "Draws") diff --git a/_assets/scripts/reset_prior.jl b/_assets/scripts/reset_prior.jl new file mode 100644 index 0000000..d17307a --- /dev/null +++ b/_assets/scripts/reset_prior.jl @@ -0,0 +1,263 @@ +@enum State PA GA NC MI AZ WI NV +@enum Month mar apr may jun jul jul2 aug sep oct +#------------------------------------------------------------------ +STATE = State +prior_month = "jul" +mon = jul2 +MON = "jul2" +Mon = "jul2" +st = "NV" +ST = NV +#------------------------------------------------------------------ +using BSON: @load, @save +using BSON +using Colors +using Combinatorics +using CSV +using DataFrames +using Distributions +using Format +using HTTP +using GLMakie +using KernelDensity +using LinearAlgebra +using MCMCChains +using Missings +using PlotlyJS +using Plots +using PrettyTables +using Printf +using Serialization +using Statistics +using StatsPlots +using Turing +#------------------------------------------------------------------ +struct Poll + biden_support::Float64 + trump_support::Float64 + sample_size::Int64 +end +#------------------------------------------------------------------ +@enum Pollster begin + ag + aj + am + bi2 + bi3 + bl2 + bl3 + cb2 + cb3 + cn2 + cn3 + ea + ec2 + ec3 + ep + eu + fm2 + fm3 + fo2 + fo3 + hi2 + hi3 + hp + ia + ma2 + ma3 + mi2 + mi3 + mq + mr2 + mr3 + ns + pp + ny + qi2 + qi3 + rr + si2 + si3 + sp2 + sp3 + su2 + su3 + tr + wa2 + wa3 + ws + wsl + wss + yg +end +#------------------------------------------------------------------ +Month_names = Dict( + "mar" => "March", + "apr" => "April", + "may" => "May", + "jun" => "June", + "jul" => "July", + "jul2" => "July-post", + "aug" => "August", + "sep" => "September", + "oct" => "October") +#------------------------------------------------------------------ +const states = ["NV", "WI", "AZ", "GA", "MI", "PA", "NC"] +const FLAGRED = "rgb(178, 34, 52)" +const FLAGBLUE = "rgb( 60, 59, 110)" +const PURPLE = "rgb(119, 47, 81)" +const GREENBAR = "rgb( 47, 119, 78)" +const LORANGE = "rgb(225, 170, 110)" +#------------------------------------------------------------------ +function draw_density() + # Create a new figure with specified resolution + fig = Figure(size = (600, 400)) + + # Add an axis to the figure + ax = Axis(fig[1, 1], xlabel = "Likelihood of Harris win", ylabel = "Number of draws", title = "Model: Harris results in $ST from 2020 election and polling through " * Month_names[Mon]) + # Plot the full density curve + lines!(ax, kde_result.x, kde_result.density, color = "#a3b35c", linewidth = 3, strokewidth = 4, strokecolor = GREENBAR, label = "Draws") + + # Find the indices corresponding to the posterior interval + indices = findall((posterior_interval[1] .<= kde_result.x) .& (kde_result.x .<= posterior_interval[2])) + + # Extract the x and y values within the posterior interval + x_region = kde_result.x[indices] + y_region = kde_result.density[indices] + + # Fill the specific area under the curve + band!(ax, x_region, fill(0, length(x_region)), y_region, color = (LORANGE), label = "Credible Interval") + + # Find the y-value corresponding to the specified x-value + y_value = kde_result.density[argmin(abs.(kde_result.x .- margin))] + + # Add a vertical line at the specified x-value from 0 to the y-value + vlines!(ax, [margin], [0, y_value], color = FLAGBLUE, linestyle = :dash, linewidth = 4, label = "2020 Actual") + + # Add a legend to the plot + axislegend(ax) + + # Adjust the plot limits to fit the density line + Makie.xlims!(ax, extrema(p_vec)) + Makie.ylims!(ax, 0, nothing) + + # Display the figure + fig +end +#------------------------------------------------------------------ +function process_polls(polls::Vector{Poll}) + result = Int64.(collect(collect([(p.biden_support, p.sample_size) for p in polls])[1])) + return [Int64(floor(result[1] / 100 * result[2])), result[2]] +end +#------------------------------------------------------------------ +function remove_empties(the_month::Dict) + Dict(state => Dict(pollster => polls for (pollster, polls) in pollsters + if !isempty(polls)) for (state, pollsters) in the_month) +end +#------------------------------------------------------------------ +# Define the new model with additional binomial uncertainty +@model function updated_model(y, n) + # Use the existing chain as a prior for p + p ~ Normal(mean(p_prior_flat), std(p_prior_flat)) + + # Ensure p is within [0, 1] + p_clamped = clamp(p, 0, 1) + + # Add additional binomial uncertainty + q ~ Beta(2, 2) # Weakly informative prior for additional uncertainty + + # Ensure the final probability is within [0, 1] + prob = clamp(q * p_clamped, 0, 1) + + # Likelihood + y ~ Binomial(n, prob) +end +#------------------------------------------------------------------ +margins = CSV.read("../objs/margins.csv", DataFrame) +@load "../objs/"*"$MON"*"_polls.bson" months +prior_poll = BSON.load("../objs/"*"$st"*"_"*"$prior_month"*"_p_sample.bson") +#------------------------------------------------------------------ +margin = first(margins[margins.st .== st, :pct]) +current_month = remove_empties(months[mon]) +#------------------------------------------------------------------ +# Extract the relevant data from the existing chain +prior_chain = prior_poll[:deep] +p_prior = Array(prior_chain[:p]) +# Total results of current polls +processed_polls = Dict(state => + Dict(pollster => + process_polls(polls) for (pollster, polls) in pollsters) + for (state, pollsters) in current_month) + +processed_polls_totals = Dict(state => + Dict("num_wins" => + sum(first(values(polls)) for polls in values(pollsters)), + "num_votes" => + sum(last(values(polls)) for polls in values(pollsters))) + for (state, pollsters) in processed_polls) + +num_wins = processed_polls_totals[ST]["num_wins"] +num_votes = processed_polls_totals[ST]["num_votes"] +#------------------------------------------------------------------ +# Create a kernel density estimate of the prior +# Flatten p_prior to a vector +p_prior_flat = vec(p_prior) + +# Create the new model instance +new_model = updated_model(num_wins, num_votes) + +# Sample from the new model to create an updated posterior +chain = sample(new_model, NUTS(), 10000) + +# Now 'chain' contains your reset posterior, which you can use as a prior for future analyses +#------------------------------------------------------------------ +# poll_posterior = prior_poll +# +# posterior_mean = mean(poll_posterior[:deep][:p]) +# posterior_var = var(poll_posterior[:deep][:p]) +# prior_alpha = posterior_mean * +# (posterior_mean * (1 - posterior_mean) / posterior_var - 1) +# prior_beta = (1 - posterior_mean) * (posterior_mean * +# (1 - posterior_mean) / posterior_var - 1) +# prior_dist = Beta(prior_alpha, prior_beta) +# +# model = poll_model(num_votes, num_wins, prior_dist) +# sampler = NUTS(0.65) +# num_samples = 10000 +# num_chains = 4 +# init_params = [Dict(:p => 0.5)] +# chain = sample(poll_model(num_votes, num_wins, prior_dist), +# sampler, num_samples, init_params=init_params) + +p_intv = quantile(chain[:p], [0.025, 0.975]) +p_mean = summarystats(chain)[1,:mean] +p_mcse = summarystats(chain)[1,:mcse] +p_rhat = summarystats(chain)[1,:rhat] +p_df = DataFrame(median = median(chain[:p]), + mean = mean(chain[:p]), + mode = mode(chain[:p]), + q025 = p_intv[1], + q975 = p_intv[2], + mcse = summarystats(chain)[1,:mcse], + rhat = summarystats(chain)[1,:rhat]) + +p_samples = chain[:p] +p_vec = vec(p_samples) +kde_result = kde(p_vec) + +deep = deepcopy(chain) + +posterior_interval = p_intv +fig = draw_density() + +out = Vector(p_df[1,:]) +out = round.(out,digits = 4) +p_df[1,:] = out +pretty_table(p_df,backend=Val(:html),show_subheader = false) +chain +summarystats(chain) +autocor(chain) +hpd(chain) +#------------------------------------------------------------------ +save(("../img/models/"*"$st"*"_"*"$mon"*".png"), fig) +@save ("../objs/"*"$st"*"_"*"$mon"*"_p_sample.bson") deep diff --git a/az.md b/az.md index 30f6e74..3a9f433 100644 --- a/az.md +++ b/az.md @@ -2,6 +2,7 @@ title = "Arizona" +++ +* [July assessmenbt from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-xcampaign) * [June assessment](#June-assessment) * [May assessment](#may-assessment) @@ -18,7 +19,6 @@ title = "Arizona" In the 2020 election President Biden won 50.16% (0.5016) of the votes cast for Biden or Trump in Arizona. This leaves out votes for third-party candidates. Taking the actual result as a starting point, the model introduces some uncertainty into the result to create a range of outcomes for that election from 50.10% to 50.21%. Next, the results of each month's polling are factored in on a rolling basis. When the plot shows that more of the credible interval lies to the left of the 2020 margin it indicates that Harris is losing ground compared to the 2020 election results, taking the polls at face value. - Beginning with polls conducted from July 23 - July 31, 2024, the model that used results through July 22, 2024 plus an allowance for the uncertainty introduced by the entry of Vice President Harris in place of President Biden will be used as the starting point, to be updated fortnightly by later poll results. Assessments are based on three criteria. @@ -27,6 +27,38 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed* criterion. + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.50130.50130.50130.50070.50180.01.0004
+ +~~~ + ## July assessment through end of Biden campaign Biden wins under the *Relaxed* criterion. @@ -56,7 +88,7 @@ Biden wins under the *Relaxed* criterion. - + ~~~ diff --git a/ga.md b/ga.md index 7449174..68b1ade 100644 --- a/ga.md +++ b/ga.md @@ -2,6 +2,7 @@ title = "Georgia" +++ +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#june-assessment) * [May assessment](#may-assessment) @@ -24,6 +25,38 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed* criterion. + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.5010.5010.50130.50050.50140.01.0001
+ +~~~ + ## July assessment through end of Biden campaign ~~~ @@ -51,7 +84,7 @@ Assessments are based on three criteria. - + ~~~ ## June assessment @@ -589,7 +622,9 @@ The scenario tables below show the possible outcomes that involve Georgia. Geor Tie + ~~~ + ### Trump wins ~~~ diff --git a/index.md b/index.md index 7bf103e..0bc86b6 100644 --- a/index.md +++ b/index.md @@ -4,35 +4,33 @@ title = "Latest" ## Superseding event -As of July 22, 2024, Vice President Harris will replace President Harris as the nominee of the Democratic Party and a new model will need to be developed to reflect that change. The plan is to aggregate the polls conducted in July prior to July 21, 2024 (when Harris withdrew) as the prior distribution, after introducing some variability to partially account for the added uncertainty. +Vice President Harris replaced President President as the nominee of the Democratic Party. The model has been revised to take into account the polls conducted in July prior to July 21, 2024 (when Biden withdrew) as the prior distribution, after introducing some variability to partially account for the added uncertainty introduced by the substitution For polls conducted through the end of the month, the model will be updated and every fortnight thereafter. Consideration will also be given to reassessing swing states, depending on initial results. It is expected that most Blue and Red states will remain as such, but some swing states will move. -## Allocation of electoral college votes corrected\ +## Allocation of electoral college votes corrected -Harris starts with the 226 (not 225) votes won in 2020, using the revised 2024 electoral college vote allocations. +Harris starts with the 226 (not 225) votes won by Biden in 2020, using the revised 2024 electoral college vote allocations. -## Overall assessment for polling through June +## Overall assessment for polling through July ### Stringent view -Based on the criterion that the model must show Harris taking at least 50.25% of the two-candidate split, Bidin would win none of the swing states, resulting in **225-313 Electoral College loss.** +Based on the criterion that the model must show Harris taking at least 50.25% of the two-candidate split, Harris would win none of the swing states, resulting in **226-312 Electoral College loss.** ### Historical view -Based on the criterion that the model shows Harris doing at least as well as he did in 2020 in the two-candidate split, Harris would win none of the swing states resulting in a **225-313 Electoral College loss.** +Based on the criterion that the model shows Harris doing at least as well as Biden did in 2020 in the two-candidate split, Harris would win none of the swing states resulting in a **226-312 Electoral College loss.** ### Relaxed view -Based on the criterion that the model shows Harris winning by at least 50% plus one vote of the two-candidate split, Harris would six of the seven swing states (having lost in North Carolina), Harris would take 77 electoral votes resulting in a **302-236 Electoral College victory.** +Based on the criterion that the model shows Harris winning by at least 50% plus one vote of the two-candidate split, Harris would six of the seven swing states (having lost in North Carolina), taking 77 electoral votes resulting in a **303-235 Electoral College victory.** -The poll results conducted in the seven swing states in March, April, May and June show presidential preference divided, but favoring Trump in more states than Harris. Each of the poll results has a greater or smaller degree of uncertainty that depends primarily on how many answers were collected. Taking into account, however, the results of 2020, although there are signs of erosion in Harris's support, the performance is better than the standalone polls would suggest. +The poll results conducted in the seven swing states in March, April, May, June and July show presidential preference divided, but favoring Trump in more states than Harris. Each of the poll results has a greater or smaller degree of uncertainty that depends primarily on how many answers were collected. Taking into account, however, the results of 2020, although there are signs of erosion in Harris's support, the performance is better than the standalone polls would suggest. The choice of model is intended to dampen volatility. To date, the results are consistent with an eroding margin in the swing states won by the Democrats in 2020. North Carolina has been static -Only one June poll has been reported for swing state was taken on the day of the debate nd the day after. That one has partisan affiliation, so it was not included. +The model is based on the *Bayesian analysis* described in [Methodology](/method]) It begins with the relative share of the two-candidate popular vote won by Biden in each of the swing states in 2020 adjusted by the effect of polling conducted to date. -The model is based on the *Bayesian analysis* described in [Methodology](/method]) It begins with the relative share of the two-candidate popular vote won by Harris in each of the swing states in 2020 adjusted by the effect of polling conducted in April. Beginning next month, the beginning point will be adjusted to reflect a cumulative model in which cumulative results will be reporting. - -A total of 45 electoral votes from the swing states is a win, given his safe state edge of 225-220 over Trump. +A total of 44 electoral votes from the swing states is a win, given her safe state edge of 226-219 over Trump. The model is **not** a prediction, but only a projection using stated assumptions. Is is only a mathematical representation of the combined information that is derivable from the actual results of millions of voters in those states and the survey responses of hundreds of voters from the same states. Little weight should be given to the likelihoods so far in advance of the election. Beginning with the reports of August polls, expected in early September, political polls historically begin to approximate electoral results. diff --git a/mi.md b/mi.md index fb7062a..7329316 100644 --- a/mi.md +++ b/mi.md @@ -2,6 +2,7 @@ title = "Michigan" +++ +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#june-assessment) * [May assessment](#may-assessment) @@ -25,6 +26,39 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed criterion* + +~~~ +
+ + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.51390.51390.51360.51340.51430.01.0
+ + +~~~ + ## July assessment through end of Biden campaign ~~~ diff --git a/nc.md b/nc.md index 9b7bdce..7218a1e 100644 --- a/nc.md +++ b/nc.md @@ -2,12 +2,14 @@ title = "North Carolina" +++ +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#jun-assessment) * [May assessment](#may-assessment) * [April assessment](#april-assessment) * [March assessment](#march-assessment) * [2020 election](#2020-election) +* [Scenarios](#scenarios) * [2022 demographics](#2022-demographics) * [Terms](#terms) @@ -20,6 +22,39 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed criterion* + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.4930.4930.49290.49260.49340.01.0
+ + +~~~ + ## July assessment through end of Biden campaign A Biden victory is not within the credible interval under any of the scenarios. @@ -208,7 +243,11 @@ A Biden victory is not within the credible interval under any of the scenarios. ~~~ -## Harris wins +## Scenarios + +The scenario tables below show the possible outcomes that involve Georgia. Georgia is represented in 46 of the 128 possible outcomes. *The combinations shown are those representing swing states taken by Harris.* + +### Harris wins ~~~ @@ -548,7 +587,7 @@ A Biden victory is not within the credible interval under any of the scenarios.
~~~ -## Trump wins +### Trump wins ~~~ @@ -676,285 +715,199 @@ A Biden victory is not within the credible interval under any of the scenarios.
~~~ -## Harris wins without North Carolina +### Harris wins without North Carolina ~~~ -~~~ - -~~~ - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + +
States won by Harris Electoral VotesHarrisTrumpWinnercombovotesharristrumpresult
NV6232306Trump
WI10236302Trump
AZ11237301Trump
MI15241297Trump
NV and WI16242296Trump
GA16242296Trump
NV and AZ17243295TrumpWI, MI and PA44270268Harris
PA19245293TrumpWI, GA and PA45271267Harris
NV and MI21247291TrumpAZ, MI and PA45271267Harris
WI and AZ21247291TrumpNV, WI, AZ and PA46272266Harris
NV and GA22248290TrumpAZ, GA and PA46272266Harris
NV and PA25251287TrumpNV, WI, GA and MI47273265Harris
WI and MI25251287TrumpNV, AZ, GA and MI48274264Harris
WI and GA26252286TrumpNV, WI, MI and PA50276262Harris
AZ and MI26252286TrumpGA, MI and PA50276262Harris
AZ and GA27253285TrumpNV, WI, GA and PA51277261Harris
NV, WI and AZ27253285TrumpNV, AZ, MI and PA51277261Harris
WI and PA29255283TrumpNV, AZ, GA and PA52278260Harris
AZ and PA30256282TrumpWI, AZ, GA and MI52278260Harris
GA and MI31257WI, AZ, MI and PA55 281Trump
NV, WI and MI31 257281Trump
NV, WI and GA32258280Trump
NV, AZ and MI32258280Trump
NV, AZ and GA33259279Trump
MI and PA34260278Trump
GA and PA35261277TrumpHarris
NV, WI and PA35261277TrumpNV, GA, MI and PA56282256Harris
NV, AZ and PA36262276TrumpWI, AZ, GA and PA56282256Harris
WI, AZ and MI36262276TrumpNV, WI, AZ, GA and MI58284254Harris
NV, GA and MI37263275TrumpWI, GA, MI and PA60286252Harris
WI, AZ and GA37263275TrumpNV, WI, AZ, MI and PA61287251Harris
NV, MI and PA40266272TrumpAZ, GA, MI and PA61287251Harris
WI, AZ and PA40266272TrumpNV, WI, AZ, GA and PA62288250Harris
NV, GA and PA41267271TrumpNV, WI, GA, MI and PA66292246Harris
WI, GA and MI41267271TrumpNV, AZ, GA, MI and PA67293245Harris
NV, WI, AZ and MI42268270TrumpWI, AZ, GA, MI and PA71297241Harris
AZ, GA and MI42268270TrumpNV, WI, AZ, GA, MI and PA77303235Harris
+ ~~~ diff --git a/nv.md b/nv.md index 16bd562..b5596fe 100644 --- a/nv.md +++ b/nv.md @@ -2,6 +2,7 @@ title = "Nevada" +++ +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#june-assessment) * [May assessment](#may-assessment) @@ -24,6 +25,38 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed criterion* + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.51170.51170.51150.51090.51250.00.9999
+ + +~~~ ## July assessment through end of Biden campaign Biden wins under the *Relaxed criterion* diff --git a/pa.md b/pa.md index 4ce7df2..788b1d2 100644 --- a/pa.md +++ b/pa.md @@ -2,6 +2,7 @@ title = "Pennsylvania" +++ +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#June-assessment) * [May assessment](#may-assessment) @@ -16,7 +17,6 @@ title = "Pennsylvania" # Model results - In the 2020 election President Biden won 50.59% (0.5059) of the votes cast for Biden or Trump in Pennsylvania This leaves out votes for third-party candidates. Taking the actual result as a starting point, the model introduces some uncertainty into the result to create a range of outcomes for that election from 50.56% to 50.63%. Next, the results of each month's polling are factored in on a rolling basis. When the plot shows that more of the credible interval lies to the left of the 2020 margin it indicates that Harris is losing ground compared to the 2020 election results, taking the polls at face value. Beginning with polls conducted from July 23 - July 31, 2024, the model that used results through July 22, 2024 plus an allowance for the uncertainty introduced by the entry of Vice President Harris in place of President Biden will be used as the starting point, to be updated fortnightly by later poll results. @@ -27,6 +27,38 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed criterion* + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.50570.50570.50550.50530.50610.01.0001
+ +~~~ + ## July assessment through end of Biden campaign ~~~ diff --git a/sources.md b/sources.md index fbb9e14..a7f18d7 100644 --- a/sources.md +++ b/sources.md @@ -42,7 +42,8 @@ df = CSV.read(IOBuffer(csv_data), DataFrame) - [Bloomberg/Morning Consult: conducted April](https://pro-assets.morningconsult.com/wp-uploads/2024/04/Bloomberg_2024-Election-Tracking-Wave-7.pdf) - [Bloomberg/Morning Consult: conducted May](https://pro-assets.morningconsult.com/wp-uploads/2024/05/Bloomberg-Election-Tracking-Wave-8-Toplines-Crosstabs.pdf) - [Bloomberg/Morning Consult: conducted March](https://pro-assets.morningconsult.com/wp-uploads/2024/03/Bloomberg_2024-Election-Tracking-Wave-6.pdf) - - [Bloomberg/Morning Consult: conducted July pre-July](https://pro-assets.morningconsult.com/wp-uploads/2024/07/Bloomberg-Election-Tracking-Wave-9-Toplines-Crosstabs.pdf) + - [Bloomberg/Morning Consult: conducted after July 21](https://pro-assets.morningconsult.com/wp-uploads/2024/07/Bloomberg-Swing-State-Wave-10.pdf) + - [Bloomberg/Morning Consult: conducted July pre-July 21](https://pro-assets.morningconsult.com/wp-uploads/2024/07/Bloomberg-Election-Tracking-Wave-9-Toplines-Crosstabs.pdf) - [Emerson College: conducted June](https://docs.google.com/spreadsheets/d/1vGeTKW3MRDR5dXHM2IjM8ORz7HOyP5Le/edit?gid=532631346#gid=532631346) - [Emerson College: conducted April](https://emersoncollegepolling.com/trump-holds-edge-over-biden-in-seven-key-swing-state-polls/) - [Emerson College: conducted March](https://emersoncollegepolling.com/category/state-poll/) @@ -80,11 +81,14 @@ df = CSV.read(IOBuffer(csv_data), DataFrame) - [Quinnipiac University: conducted March](https://poll.qu.edu/poll-release?releaseid=3893) - [Quinnipiac University: conducted June](https://poll.qu.edu/images/polling/ga/ga06052024_ggwb04.pdf) - [Fox News: conducted June](https://static.foxnews.com/foxnews.com/content/uploads/2024/06/Fox_June-1-4-2024_NEVADA_Topline_June-6-Release.pdf) + - [Fox News: conducted post-July 21](https://static.foxnews.com/foxnews.com/content/uploads/2024/07/Fox_July-22-24-2024_Michigan_Topline_July-26-Release.pdf) - [EPIC-MRA: conducted in July, pre-Harris](https://ssl2002.webhosting.comcast.net/epic-mra/press/Stwd_Survey_July2024_Media_Freq.pdf) - [Trafalger: conducted July pre-Harris](https://www.thetrafalgargroup.org/wp-content/uploads/2024/07/MI-Gen-Pres-Poll-Report-0718.pdf) * Pennsylvania - [CBS: conducted April](https://www.scribd.com/document/727318459/Cbsnews-20240428-PA-SUN) - [Franklin & Marshall College Poll: conducted March](https://www.fandmpoll.org/franklin-marshall-poll-release-april-2024) + - [Fox News: conducted after July 21](https://static.foxnews.com/foxnews.com/content/uploads/2024/07/Fox_July-22-24-2024_Pennsylvania_Topline_July-26-Release.pdf) + - [American Greatness: conducted after July 21](https://cdn.amgreatness.com/app/uploads/2024/07/PA-July-Toplines.pdf) * North Carolina - [High Point: conduct May](https://www.highpoint.edu/src/files/2023/08/103memo.pdf) - [Marist: conducted March ](https://maristpoll.marist.edu/wp-content/uploads/2024/03/Marist-Poll_North-Carolina-NOS-and-Tables_202403181357.pdf) @@ -98,6 +102,7 @@ df = CSV.read(IOBuffer(csv_data), DataFrame) * Wisconsin - [CBS: conducted April](https://www.scribd.com/document/727319278/Cbsnews-20240428-WI-SUN) - [Fox News: conducted April](https://static.foxnews.com/foxnews.com/content/uploads/2024/04/b002d3b3-Fox_April-11-16-2024_WISCONSIN_Topline_April-18-Release.pdf) + - [Fox News: conducted after July 21](https://static.foxnews.com/foxnews.com/content/uploads/2024/07/Fox_July-22-24-2024_Wisconsin_Topline_July-26-Release.pdf) - [Quinnipiac conducted May](https://poll.qu.edu/images/polling/wi/wi05082024_wizz76.pdf) --- diff --git a/wi.md b/wi.md index b807d68..2881070 100644 --- a/wi.md +++ b/wi.md @@ -2,6 +2,8 @@ title = "Wisconsin" +++ + +* [July assessment from beginning of Harris campaign](#July-assessment-from-beginning-of-Harris-campaign) * [July assessment through end of Biden campaign](#July-assessment-through-end-of-Biden-campaign) * [June assessment](#june-assessment) * [May assessment](#may-assessment) @@ -9,6 +11,7 @@ title = "Wisconsin" * [March assessment](#march-assessment) * [2020 election](#2020-election) * [Scenarios](#scenarios) +* [Scenarios](#scenarios) * [State facts](#state-facts) * [2022 demographics](#2022-demographics) * [Terms](#terms) @@ -25,6 +28,39 @@ Assessments are based on three criteria. * **Historical**—fewer than 2.5% of the values in the credible interval are less than 2020 margin. * **Relaxed**—fewer than 2.5% of the values in the credible interval are less than 50.01% of the two candidate vote. + +## July assessment from beginning of Harris campaign + +Harris wins under the *Relaxed criterion* + +~~~ + + + + + + + + + + + + + + + + + + + + + + + +
medianmeanmodeq025q975mcserhat
0.5030.5030.50280.50250.50360.01.0002
+ + +~~~ ## July assessment through end of Biden campaign Biden wins under the *Relaxed* criterion. @@ -59,7 +95,7 @@ Biden wins under the *Relaxed* criterion. ~~~ ## June assessment -Harris wins under the *Relaxed* criterion. +Biden wins under the *Relaxed* criterion. ~~~ @@ -91,7 +127,7 @@ Harris wins under the *Relaxed* criterion. ## May assessment -Harris wins under the *Relaxed* criterion. +Biden wins under the *Relaxed* criterion. ~~~
@@ -123,7 +159,7 @@ Harris wins under the *Relaxed* criterion. ## April assessment -Harris wins under the *Relaxed* criterion. +Biden wins under the *Relaxed* criterion. ~~~
@@ -154,7 +190,7 @@ Harris wins under the *Relaxed* criterion. ~~~ ## March assessment -Harris wins under the *Relaxed* criterion. +Biden wins under the *Relaxed* criterion. ~~~
@@ -202,13 +238,13 @@ Harris wins under the *Relaxed* criterion. - - - - - + + + + + - +
0.50320.50320.50310.50260.50370.5030.5030.5030.50250.5036 0.01.01.0007
@@ -721,254 +757,222 @@ The scenario tables below show the possible outcomes that involve Wisconsin. Wi ~~~ -~~~ - -~~~ - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + -
States won by HarrisElectoral VotesHarrisTrumpResultcombovotesharristrumpresult
NV6232306TrumpAZ, MI and PA45271267Harris
AZ11237301TrumpAZ, GA and PA46272266Harris
MI15241297TrumpAZ, PA and NC46272266Harris
GA16242296TrumpGA, MI and NC47273265Harris
NC16242296TrumpNV, AZ, GA and MI48274264Harris
NV and AZ17243295TrumpNV, AZ, MI and NC48274264Harris
PA19245293TrumpNV, AZ, GA and NC49275263Harris
NV and MI21247291TrumpGA, MI and PA50276262Harris
NV and GA22248290TrumpMI, PA and NC50276262Harris
NV and NC22248290TrumpNV, AZ, MI and PA51277261Harris
NV and PA25251287TrumpGA, PA and NC51277261Harris
AZ and MI26252286TrumpNV, AZ, GA and PA52278260Harris
AZ and GA27253285TrumpNV, AZ, PA and NC52278260Harris
AZ and NC27253285TrumpNV, GA, MI and NC53279259Harris
AZ and PA30256NV, GA, MI and PA56 282Trump
GA and MI31257281Trump
MI and NC31257281Trump
GA and NC32258280Trump
NV, AZ and MI32258280Trump256Harris
NV, AZ and GA33259279TrumpNV, MI, PA and NC56282256Harris
NV, AZ and NC33259279TrumpNV, GA, PA and NC57283255Harris
MI and PA34260278TrumpAZ, GA, MI and NC58284254Harris
GA and PA35261277TrumpAZ, GA, MI and PA61287251Harris
PA and NC35261277TrumpAZ, MI, PA and NC61287251Harris
NV, AZ and PA36262276TrumpAZ, GA, PA and NC62288250Harris
NV, GA and MI37263275TrumpNV, AZ, GA, MI and NC64290248Harris
NV, MI and NC37263275TrumpGA, MI, PA and NC66292246Harris
NV, GA and NC38264274TrumpNV, AZ, GA, MI and PA67293245Harris
NV, MI and PA40266272TrumpNV, AZ, MI, PA and NC67293245Harris
NV, GA and PA41267271TrumpNV, AZ, GA, PA and NC68294244Harris
NV, PA and NC41267271TrumpNV, GA, MI, PA and NC72298240Harris
AZ, GA and MI42268270TrumpAZ, GA, MI, PA and NC77303235Harris
AZ, MI and NC42268270TrumpNV, AZ, GA, MI, PA and NC83309229Harris
-~~~ +~~~ ## Wisconsin facts