BookmarkSubscribeRSS Feed

Hackathon Highlights: How we can use SAS AI to allocate political campaign funds more efficiently

Started ‎02-24-2020 by
Modified ‎03-02-2020 by
Views 4,055

Image by chayka1270 from PixabayImage by chayka1270 from Pixabay


In the 2016 election, says, Donald Trump “defied conventional wisdom, besting better financed candidates.” In doing so, he became the first presidential candidate since 1976 to defeat an opponent who raised more money. Such a rare event prompted my colleagues (Neal Vaidya, Pauline Emerald Ranjan, @joburn) and I to wonder if the Democratic campaign failed to make optimal use of their funds.


This begs the question: Can we optimize how campaigns allocate their funds?


SASHackathonHighlights.jpgOur team specifically wanted to know how a campaign can maximize the number of electoral votes won with a restricted budget. We took on the challenge to build an application to solve this problem during the SAS AI Hackathon, an internal competition in which we competed against other customer advisory teams. With the hackathon time constraint of 12 hours, our team created a basic optimization model to distribute campaign funds by state in order to maximize the number of electoral votes.



Below is the SAS® Visual Analytics dashboard we created, which depicts the optimal allocation of a candidate’s campaign funds by state. On the right is a breakdown of the allocation determined by our optimization model. As you can tell, some states in white do not have any campaign funding allocated to them. These states are strongly partisan in favor of the opposing candidate and thus viewed as a poor use of campaign funding or considered states where winning the popular vote is nearly guaranteed.


Campaing Funding Dashboard.JPG


Elections and campaigns are very complicated, so explaining them in terms of linear relationships is not simple nor comprehensive. However, linear programming is a great method for gaining a better understanding of a complex problem. Our model can have much more depth, but for a quick summary, this simplification gives an easily digestible view of where campaign funding would be best utilized for a Democratic candidate.


In order to explain the campaign funding allocation problem, some assumptions had to be made. It was also necessary to quantify everything, even aspects that are not traditionally quantified, such as the cost to win a vote and a state overall.



  • A candidate wins all electoral votes from a state by winning most of the popular vote. (This is true in all states except NE and ME, but for simplicity, we will assume they all reward electoral votes in the same manner.)
  • Each state has a percentage lean towards one party, reflecting the strength of the partisan preference of the state (called the Cook Partisan Voting Index).
    • For example, South Dakota has an R+14 lean, meaning the state voted 14% more Republican than the national average.
  • A state can be “won over” by converting a greater percentage of would be republican votes to democratic votes than the percentage lean.
    • For example, the Democratic Party must gain more than 14% of the voting population’s vote in South Dakota to win the electoral votes. South Dakota has a voting population of 429,000 people, so the Democratic Party would have to win 429,000 * .141 = 60,489 votes from the Republican Party.
  • We quantified the cost to “win over” a state in order to understand how much campaign funding should be invested in a state with this diminishing returns cost curve:

State Cost Curve.JPG

  • We ran the model from a Democratic candidate’s standpoint, but the same analysis could be performed from the Republican standpoint.


Optimization Model

There are many different forms of optimization models. One of the more basic models is linear programming. The goal of linear programming is to maximize or minimize an objective function based on specified constraints. These two ingredients, the objective function and constraints, are linear functions. Each linear function consists of decision variables. The decision variables in our case are the states—specifically whether the state was won or lost. Since all electoral votes of a state are awarded to the winning candidate of the popular vote, this becomes a zero-one integer linear programming model.


The goal is to maximize the number of states won in the election—the objective function. The objective function is represented by the following function:

Objective Function.JPG

The constraint for our optimization model is a budget of $1 billion, which is based on the budgets from the 2016 election. The other constraint represents that this is a zero-one integer linear program.



Running the Model

Our team decided to integrate SAS and Python to run the optimization model. We were able to write our model in native Python code, our preferred programming language, but then run the optimization model on the powerful SAS® Viya Cloud Analytic Services (CAS) analytics engine.


SAS has a few Python packages for optimization. We used sasoptpy, which is a Python package providing a modeling interface to SAS Viya and SAS/OR Optimization solvers. It provides a quick way for users to deploy optimization models and solve them using CAS actions. The sasoptpy package uses the swat package to communicate with SAS Viya. It also uses pandas structures extensively.


We ran the optimization 10 times with some variance to the party lean in each iteration because there will be some variance as the election moves along. Running the model 10 times and averaging the results also yields a more comprehensive answer because there is not one single way to distribute campaign funds.


Below is the Python code.


# Connect to CAS
s = swat.CAS("", 5570, 'user', 'password')

# Simulate model 10 times
recommendation = np.repeat(0.0,51)
iterations = 10

for i in range(iterations):
    sim_Data = SWV
    # Sample from vote probability distribution
    newlean = sim_Data.lean + np.random.normal(0, 5, 51)
    costs = (newlean/100 * SWV.voters)  ** 1.5           # cost per vote curve
    costs[np.isnan(costs)] = 0
    sim_Data['cost'] = costs
    # Set objective function and constraint
    m.set_objective(so.quick_sum(variables[state]*SWV.loc[SWV['state']==state,'votes'].iloc[0] for state in states), sense = so.MAX, name = 'objective')
    con_1 = m.add_constraints(so.quick_sum( variables[state]*SWV.loc[SWV['state']==state,'cost'].iloc[0] for state in states ) <= 1000000000) 
    # Calculate results
    result = m.solve()
    out = so.get_solution_table(variables).reset_index()
    out['cost'] = out.iloc[:,1] * SWV.cost
    recommendation += out.cost

  # Output results  
  rec_df = pd.DataFrame({'cost': recommendation/iterations})
  rec_df['state'] = SWV['state']


SAS makes it very easy to connect to the CAS server from Python. All you need is the swat package, the host name, port, username, and password.



The results from the optimization model are output in a pandas data frame. We converted the pandas output to a CSV file, which we uploaded to SAS Viya. The Visual Analytics dashboard (seen at the beginning of the blog) displays the allocation of campaign funds by state on the map. There is also a breakdown by state in the table on the right. The total funding is shown in the bottom right corner of the dashboard. A total of $966 Million was distributed out of the $1 Billion budget constraint.


Below is the CSV version of the results. This gives a full breakdown of the distribution of campaign funds by state. One of the key benefits of the model is highlighting which states are worth investment and which are not, so that funds can be invested in a more optimal way towards other states. For example, no money was allocated to Texas because it was deemed too expensive to win over enough of the voting population to ultimately win the 38 electoral votes. This is because it leans so heavily Republican. As you can see, no money was allocated to California either. California leans so strongly Democratic that the party is highly likely to win the popular vote without further investment.



Campaign Funding State Breakdown.JPG



Want to Learn More?

As part of the AI Hackathon, our team turned an abstract, complex problem into a quantifiable solution. We produced the results in an easily consumable and shareable medium in the form of a visually appealing dashboard. All this was accomplished in just 12 hours thanks to the power and seamless integration that the SAS Viya platform provides with open source programming languages.


Plus, it was a lot of fun to investigate a problem that interested all of us!


If you enjoyed this article, here is an article about how optimization can improve our daily lives from better cancer treatment to reduced contamination risks....


Texas doesn't lean so heavily as it once did.  Problem is that 50.00001%=38, so everybody else gets no representation at all.

Version history
Last update:
‎03-02-2020 11:44 AM
Updated by:



SAS is headed back to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team.

Interested in speaking? Content from our attendees is one of the reasons that makes SAS Innovate such a special event!

Submit your idea!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Tags