Skip to content

Instantly share code, notes, and snippets.

@bdoohan
Last active February 12, 2018 13:25
Show Gist options
  • Save bdoohan/587bc3834ef059ef46cc132918b474e6 to your computer and use it in GitHub Desktop.
Save bdoohan/587bc3834ef059ef46cc132918b474e6 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<script>\n",
"code_show=true; \n",
"function code_toggle() {\n",
" if (code_show){\n",
" $('div.input').hide();\n",
" } else {\n",
" $('div.input').show();\n",
" }\n",
" code_show = !code_show\n",
"} \n",
"$( document ).ready(code_toggle);\n",
"</script>\n",
"<form action=\"javascript:code_toggle()\"><input type=\"submit\" value=\"Click here to toggle on/off the raw code.\"></form>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import HTML\n",
"\n",
"HTML('''<script>\n",
"code_show=true; \n",
"function code_toggle() {\n",
" if (code_show){\n",
" $('div.input').hide();\n",
" } else {\n",
" $('div.input').show();\n",
" }\n",
" code_show = !code_show\n",
"} \n",
"$( document ).ready(code_toggle);\n",
"</script>\n",
"<form action=\"javascript:code_toggle()\"><input type=\"submit\" value=\"Click here to toggle on/off the raw code.\"></form>''')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ward D Election Results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Brendan Doohan \n",
"February 10, 2018"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import seaborn as sns; sns.set()\n",
"import warnings\n",
"warnings.filterwarnings('ignore')\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import os\n",
"#os.chdir(\"C:\\\\Users\\\\nwdoohanbr\\\\Desktop\\\\WardD\\\\Jersey-City-Ward-D-Election\")\n",
"os.chdir(\"/Users/brendandoohan/Desktop/Jersey City Ward D Election/Jersey-City-Ward-D-Election\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/District%20Guide.jpeg?raw=true\" alt=\"Districts\" height=\"600\" width=\"600\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This whitepaper analyzes the results of Jersey City city council race for Ward D that was held on November 7th. In that election, incumbent Michael Yun (\"Yun\") ran against Moriah Kinberg (\"Mo\"), Carmen Vega (\"Vega\") and Rafael Torres (\"Torres\"). Yun won the election.</p> \n",
"\n",
"- Yun won with **2,613** votes \\* \n",
"- Mo had **1,335** votes \n",
"- Vega had **397** votes \n",
"- Torres had **131** votes\n",
"\n",
"<sub>* These numbers are taken from the voting machine printouts from November 7th. The final totals cannot be broken out from the data given by the Board of Elections.</sub> \n",
"<p>This paper breaks down the results by district, race, and candidate. The predictive model used to identify likely voters is also analyzed.</p>\n",
"<br clear=\"left\"></br>\n",
"<p>Specifically, this paper addresses the following questions:</p> "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results = pd.read_csv(\"JC_WARD_D_edited.csv\", header=0, error_bad_lines=False, verbose=False, encoding=\"UTF-7\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results = results.drop('Unnamed: 8', axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Questions to Ask"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. How was turnout by district?\n",
"2. What was the racial makeup of those who did vote?\n",
"3. Did Mo's supporters come out and vote? \n",
"4. Where did Mo perform best? How about the rest of the candidates?\n",
"5. Was the [Random Forest model](https://en.wikipedia.org/wiki/Random_forest) successful in identifying likely voters?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The paper then concludes by aggregating these insights to summarize what can be learned from the results of election. The insights aim to shed light on the voting behavior of Ward D--a ward experiencing rapid changes in terms of development and demographics."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Q1. How was turnout by district?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://raw.githubusercontent.com/bdoohan/Jersey-City-Ward-D-Election/master/All%20Voters%20Prcnt%20Labels.jpeg\" alt=\"Districts\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart breaks down voter turnout by District. The colors correspond to the percent of total voters that each district represents. Blue colors show districts that had a high percentage of the total votes.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>This chart shows the percet of total voters from each district. District 4, for example, had about 4.8% of the total votes.</p>\n",
"<br clear=\"left\"></br>\n",
" <p>Districts 13, 4, 5, 7 and 15 had high turnout. Overall, <b>the East side of the Heights came out and voted.</b> This is a section where Mo had strong support. The districts will be broken out for each candidate in the later sections.</p>\n",
"<br clear=\"left\"></br>\n",
"\n",
"<p>Here are the vote percentages for each district:</p> "
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style>\n",
" .dataframe thead tr:only-child th {\n",
" text-align: right;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: left;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>Dist_VotI</th>\n",
" <th>1.0</th>\n",
" <th>2.0</th>\n",
" <th>3.0</th>\n",
" <th>4.0</th>\n",
" <th>5.0</th>\n",
" <th>6.0</th>\n",
" <th>7.0</th>\n",
" <th>8.0</th>\n",
" <th>9.0</th>\n",
" <th>10.0</th>\n",
" <th>11.0</th>\n",
" <th>12.0</th>\n",
" <th>13.0</th>\n",
" <th>14.0</th>\n",
" <th>15.0</th>\n",
" <th>16.0</th>\n",
" <th>17.0</th>\n",
" <th>18.0</th>\n",
" <th>19.0</th>\n",
" <th>20.0</th>\n",
" <th>21.0</th>\n",
" <th>22.0</th>\n",
" <th>23.0</th>\n",
" <th>24.0</th>\n",
" <th>25.0</th>\n",
" <th>26.0</th>\n",
" <th>27.0</th>\n",
" <th>28.0</th>\n",
" <th>29.0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>District</th>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>3</td>\n",
" <td>4</td>\n",
" <td>5</td>\n",
" <td>6</td>\n",
" <td>7</td>\n",
" <td>8</td>\n",
" <td>9</td>\n",
" <td>10</td>\n",
" <td>11</td>\n",
" <td>12</td>\n",
" <td>13</td>\n",
" <td>14</td>\n",
" <td>15</td>\n",
" <td>16</td>\n",
" <td>17</td>\n",
" <td>18</td>\n",
" <td>19</td>\n",
" <td>20</td>\n",
" <td>21</td>\n",
" <td>22</td>\n",
" <td>23</td>\n",
" <td>24</td>\n",
" <td>25</td>\n",
" <td>26</td>\n",
" <td>27</td>\n",
" <td>28</td>\n",
" <td>29</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Voter_Prcnt</th>\n",
" <td>2.8481</td>\n",
" <td>2.8481</td>\n",
" <td>3.35443</td>\n",
" <td>4.84177</td>\n",
" <td>4.36709</td>\n",
" <td>3.25949</td>\n",
" <td>3.9557</td>\n",
" <td>3.59177</td>\n",
" <td>4.03481</td>\n",
" <td>3.84494</td>\n",
" <td>2.34177</td>\n",
" <td>3.79747</td>\n",
" <td>5.77532</td>\n",
" <td>2.43671</td>\n",
" <td>3.98734</td>\n",
" <td>2.54747</td>\n",
" <td>3.37025</td>\n",
" <td>2.86392</td>\n",
" <td>3.37025</td>\n",
" <td>4.38291</td>\n",
" <td>3.60759</td>\n",
" <td>3.60759</td>\n",
" <td>2.54747</td>\n",
" <td>2.2943</td>\n",
" <td>3.84494</td>\n",
" <td>3.08544</td>\n",
" <td>4.11392</td>\n",
" <td>1.17089</td>\n",
" <td>3.71835</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"Dist_VotI 1.0 2.0 3.0 4.0 5.0 6.0 7.0 \\\n",
"District 1 2 3 4 5 6 7 \n",
"Voter_Prcnt 2.8481 2.8481 3.35443 4.84177 4.36709 3.25949 3.9557 \n",
"\n",
"Dist_VotI 8.0 9.0 10.0 11.0 12.0 13.0 14.0 \\\n",
"District 8 9 10 11 12 13 14 \n",
"Voter_Prcnt 3.59177 4.03481 3.84494 2.34177 3.79747 5.77532 2.43671 \n",
"\n",
"Dist_VotI 15.0 16.0 17.0 18.0 19.0 20.0 21.0 \\\n",
"District 15 16 17 18 19 20 21 \n",
"Voter_Prcnt 3.98734 2.54747 3.37025 2.86392 3.37025 4.38291 3.60759 \n",
"\n",
"Dist_VotI 22.0 23.0 24.0 25.0 26.0 27.0 28.0 \\\n",
"District 22 23 24 25 26 27 28 \n",
"Voter_Prcnt 3.60759 2.54747 2.2943 3.84494 3.08544 4.11392 1.17089 \n",
"\n",
"Dist_VotI 29.0 \n",
"District 29 \n",
"Voter_Prcnt 3.71835 "
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import display\n",
"pd.options.display.max_columns = None\n",
"tots = results[results.Dist_VotI!=31][\"Voter_ID\"].count()\n",
"adf = pd.DataFrame(\n",
" 100*(results[results.Dist_VotI!=31].groupby('Dist_VotI')[\"Voter_ID\"].count()/tots)\n",
")\n",
"adf[\"District\"] = adf.index\n",
"adf.columns = [\"Voter_Prcnt\", \"District\"]\n",
"adf[\"District\"] = adf.District.astype(int).copy()\n",
"adf[[\"District\", \"Voter_Prcnt\"]].astype(object).T"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Q2. What was the racial makeup of those who did vote?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using [U.S. Census data](https://www.census.gov/topics/population/genealogy/data/2000_surnames.html), the race of each voter was identified. This method is not without its faults; however, it does serve as a functioning proxy for race classification."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### White voters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Prcnt%20White%20Labels.jpeg?raw=true\" alt=\"White_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the percent of Ward D <b>white voters</b> for each District. Blue colors show districts that had a high percentage of the total <b>white voters</b>.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts 4, 5, 7 and 9 have a high percentage of the total white votes. Overall, <b>the East side of the Heights is where much of the white voters live.</b> This is also a section where Mo had strong support.</p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Hispanic voters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Prcnt%20hispanic%20Labels.jpeg?raw=true\" alt=\"Hispanic_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the percent of Ward D <b>hispanic voters</b> for each District. Blue colors show districts that had a high percentage of the total <b>hispanic voters</b>.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts 13, 20, 5, 27 and 22 have a high percentage of the total hispanic votes. Overall, <b>the North and West sides of the Heights are where much of the hispanic voters live.</b></p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Black voters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Prcnt%20Black%20Labels.jpeg?raw=true\" alt=\"Black_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the percent of Ward D <b>black voters</b> for each District. Blue colors show districts that had a high percentage of the total <b>black voters</b>.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts 12, 13, and 20 have a high percentage of the total black votes. Overall, <b>the center of the Heights is where much of the black voters live.</b></p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Asian voters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Prcnt%20Asian%20Labels.jpeg?raw=true\" alt=\"Asian_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the percent of Ward D <b>Asian voters</b> for each District. Blue colors show districts that had a high percentage of the total <b>Asian voters</b>.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts 22, 23, 25, 27 and 29 have a high percentage of the total Asian votes. Overall, <b>the westside of the Heights is where much of the Asian voters live.</b></p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Q3. Did Mo's supporters come out and vote?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Mo%20Supporters%20Prcnt%20Labels.jpeg?raw=true\" alt=\"Mo_supporters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows where most of Mo's supporters live in Ward D. Blue colors show districts that had a high percentage of <b>Mo's supporters</b>.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts 4, 7 and 13 have a high percentage of Mo's supporters. Overall, <b>Mo's supporters live east of Central Avenue and near Congress Street.</b></p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Overall, **52%** of Mo's supporters voted on Election Day. Here is the **percent turnout** by District:"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo[\"turnout_rate\"] = results_mo.voted.astype(float)/results_mo.mo_supporter.astype(float)\n",
"results_mo[\"turnout_rate\"] = results_mo[\"turnout_rate\"].astype(float)"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo = results_mo[results_mo[\"Dist_VotI_y\"] != 'District'].copy()"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo[\"Dist_VotI_x\"] = results_mo[\"Dist_VotI_x\"].astype(float)\n",
"results_mo[\"Dist_VotI_y\"] = results_mo[\"Dist_VotI_y\"].astype(float)"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo[\"District\"] = results_mo[[\"Dist_VotI_x\", \"Dist_VotI_y\"]].max(axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 164,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turnout = pd.DataFrame(results_mo.groupby(\"District\")[\"turnout_rate\"].mean())\n",
"turnout[\"District\"] = turnout.index\n",
"turnout = turnout[turnout.District.between(1,29)]"
]
},
{
"cell_type": "code",
"execution_count": 165,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turnout[\"District\"] = turnout.District.astype(int)"
]
},
{
"cell_type": "code",
"execution_count": 201,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1a18b4de10>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import math \n",
"turnout.set_index(turnout.District)\n",
"turnout.turnout_rate.plot(kind=\"bar\")\n",
"plt.xlabel(\"District\")\n",
"plt.ylabel(\"Turnout Rate\")\n",
"plt.title(\"Turnout Rate by District\", fontsize=20)\n",
"plt.axhline(y=0.5, color='r', linestyle='--')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p align=\"left\"> Districts <b>4, 5, 6, 7 and 19</b> stood out from the rest. Mo's base in <b>the eastern section of the Heights</b> did come out and vote. However, supporters outside of this section largely failed to come out on Election day.</p>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Q4. Where did Mo perform best? How about the rest fo the candidates?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**N.B.** Color coding is specific to each candidate. Red colors show where the candidate did worse relative to his/her average number of votes. Blue shows where they did above average."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Mo%20Total%20Labels.jpeg?raw=true\" alt=\"Mo_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the <b>total</b> votes for Mo for each District. Blue colors show districts with higher vote counts.</p> \n",
"<br clear=\"left\"></br>\n",
" <p>Districts <b>3, 4, 5, 7, 8, 9 and 10</b> were the best for Mo.</p>\n",
"<br clear=\"left\"></br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Yun"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Yun%20Total%20Labels.jpeg?raw=true\" alt=\"Yun_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the <b>total</b> votes for Yun for each District. Blue colors show districts with higher vote counts.</p> \n",
"<br clear=\"left\"></br>\n",
"<p align=\"left\">Yun did well on the Western Slope and in the hispanic neighborhoods.</p> \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Vega"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Carmen%20Total%20Labels.jpeg?raw=true\" alt=\"Yun_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the <b>total</b> votes for Vega for each District. Blue colors show districts with higher vote counts.</p> \n",
"<br clear=\"left\"></br>\n",
"<p align=\"left\">Vega had low turnout in most districts.</p> "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Torres"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://github.com/bdoohan/Jersey-City-Ward-D-Election/blob/master/Torres%20Totals%20Labels.jpeg?raw=true\" alt=\"Yun_Voters\" height=\"700\" width=\"700\" align=\"right\" hspace=0>\n",
"<p align=\"left\">This chart shows the <b>total</b> votes for Torres for each District. Blue colors show districts with higher vote counts.</p> \n",
"<br clear=\"left\"></br>\n",
"<p align=\"left\">Torres had low turnout across Ward D.</p> "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Q5. How did the model do at predicting whether someone was going to vote?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For Mo's campaign a [Random Forest](https://en.wikipedia.org/wiki/Random_forest) model was used to predict who would vote. The model assigned a likelihood of voting to each voter. A likelihood close to 0 meant that the person was unlikely to vote; a value closer to 1 meant they were likely to vote. These predictions were then used to focus canvassing and phone banking efforts. \n",
"\n",
"Usually any likelihood greater than .50 (50%) is interpreted as a positive event. So, for example, if someone's likelihood was 0.55, they would be labelled as likely to vote. However, for this campaign, a decision was made to only label people with likelihoods of 0.85 or higher as people likely to vote. This made the model's predictions much more accurate. \n",
"\n",
"Using the 0.85 likelihood cutoff, the model had an accuracy of **75%**. This means that the model correctly predicted whether or not a voter would vote 75% of the time. Part of this success is due to the fact that turnout overall was low. Many people did not come out and vote, compared to previous elections. That is, having a high cutoff value of 85% meant that most people were predicted not to vote. This is exactly what happened since turnout was so low."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Summary"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- **Demographic** \n",
" \n",
" - Mo won the white vote on the eastern side of the Ward \n",
" - Mo lost the Western Slope, which is predominantly asian \n",
"\n",
" \n",
"\n",
"- **Geographic** \n",
"\n",
" - Mo struggled west of Central Avenue\n",
" - Mo did well east of Central Avenue \n",
"\n",
" \n",
"\n",
"- **Base health** \n",
"\n",
" - 52% of Mo's supporters came out to vote\n",
" - Most of this turnout came from supporters east of Central Avenue\n",
"\n",
"\n",
"\n",
"- **Competitors** \n",
" \n",
" - Yun did well across most districts, with strong performance in the asian and hispanic neighborhoods\n",
"\n",
"\n",
"\n",
"- **Change Research Survey** \n",
" \n",
" - The survey indicated that those who knew Mo liked her and would vote for her\n",
" - Data from the election confirm this finding, showing that Mo did well where most of her supporters lived\n",
" - Survey had Yun with 62% and Mo with 30%; actual results were Yun 52% and Mo with 38%"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_last(string):\n",
" return(str(string).split(\"|\")[0])\n",
"def get_first(string):\n",
" try:\n",
" return(str(string).split(\"|\")[1])\n",
" except:\n",
" return(\"\")\n",
"def get_middle(string):\n",
" try:\n",
" return(str(string).split(\"|\")[2])\n",
" except:\n",
" return(\"\")\n",
"\n",
"results[\"last_name\"] = results.Voter_Name.apply(get_last)\n",
"results[\"first_name\"] = results.Voter_Name.apply(get_first)\n",
"results[\"middle_name\"] = results.Voter_Name.apply(get_middle)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"url = 'https://raw.githubusercontent.com/fivethirtyeight/data/master/most-common-name/surnames.csv'\n",
"races = pd.read_csv(url,index_col=0)"
]
},
{
"cell_type": "code",
"execution_count": 205,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"races[\"last_name\"] = races.index\n",
"races = races.reset_index()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_race(arow): \n",
" if arow[\"pctblack\"]==\"((S))\":\n",
" arow[\"pctblack\"] = 0.00\n",
" if arow[\"pctaian\"]==\"((S))\":\n",
" arow[\"pctaian\"] = 0.00\n",
" try:\n",
" guess = arow[[\"pctwhite\", \"pctblack\", \"pctapi\", \"pctaian\", \"pct2prace\", \"pcthispanic\"]].astype(float).idxmax(axis=1)\n",
" return(guess)\n",
" except:\n",
" return(\"Unidentified\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mapping = {'(S)':.00001}\n",
"races = races.replace({'pctblack': mapping, 'pctaian': mapping,\n",
" 'pctwhite': mapping, 'pctapi': mapping, \n",
" 'pct2prace': mapping, 'pcthispanic': mapping})"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"races[\"guess\"] = races.apply(lambda x: get_race(x), axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"races[\"guess\"] = races.guess.str.replace(\"pct\", \"\")"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_race = pd.merge(results, races, on=\"last_name\", how=\"left\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_race.guess.fillna(\"Unidentified\", inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_base = pd.read_csv(\"Election Day Mo Supporter List - Master 11052017.csv\", \n",
" names = [\"first_name\", \"last_name\", \"full_name\", \"address\", \"Dist_VotI\", \"email\", \"phone\"])"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_base[\"mo_supporter\"] = int(1)"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results['first_name'] = results['first_name'].apply(lambda x: x.strip(\" \"))\n",
"results['first_name'] = results['first_name'].apply(lambda x: x.upper())"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results['last_name'] = results['last_name'].apply(lambda x: x.strip(\" \"))\n",
"results['last_name'] = results['last_name'].apply(lambda x: x.upper())"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_base['first_name'] = mo_base['first_name'].astype(str).apply(lambda x: x.strip(\" \"))\n",
"mo_base['last_name'] = mo_base['last_name'].astype(str).apply(lambda x: x.strip(\" \"))\n",
"mo_base['first_name'] = mo_base['first_name'].astype(str).apply(lambda x: x.split(',', 1)[0])\n",
"mo_base['last_name'] = mo_base['last_name'].apply(lambda x: x.upper())\n",
"mo_base['first_name'] = mo_base['first_name'].apply(lambda x: x.upper())"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results[\"voted\"] = int(1)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo = pd.merge(results, mo_base[[\"first_name\", \"last_name\", \"mo_supporter\", \"Dist_VotI\"]],\n",
" on=[\"last_name\", \"first_name\"], how=\"right\")"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo.drop_duplicates(inplace=True, subset=[\"Voter_ID\", \"last_name\", \"first_name\", \"voted\", \"mo_supporter\"])"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_mo.fillna(0, inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = results_race_mo.groupby([\"Dist_VotI\", \"guess\"])[\"Voter_ID\"].count().unstack()\n",
"races_dist = pd.DataFrame(x)\n",
"races_dist[\"District\"] = races_dist.index"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = results_race_mo.groupby(\"Dist_VotI\")[\"Voter_ID\"].count()\n",
"votes = pd.DataFrame(x)\n",
"votes[\"District\"] = votes.index"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_groupby = mo_base.groupby(\"Dist_VotI\", as_index=False).mo_supporter.count() "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_race_mo[\"Dist_VotI\"] = results_race_mo.Dist_VotI.astype(str).copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_groupby[\"Dist_VotI\"] = mo_groupby.Dist_VotI.astype(str).copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_race_mo[\"Dist_VotI\"] = results_race_mo.Dist_VotI.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_groupby = pd.DataFrame(\n",
" results_race_mo.groupby([\"Dist_VotI\", \"mo_supporter\"])[\"Voter_ID\"].count().fillna(0).replace('NaN', 0)\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_groupby.unstack()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_groupby = results_groupby.unstack()\n",
"#results_groupby[\"Dist_VotI\"] = results_groupby.index\n",
"#results_groupby[\"Dist_VotI\"] = results_groupby[\"Dist_VotI\"].round(0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_groupby = mo_groupby.convert_objects(convert_numeric=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"results_groupby.transpose().head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_turnout = pd.merge(\n",
" results_groupby.transpose(),\n",
" mo_groupby,\n",
" on=\"Dist_VotI\",\n",
" how=\"inner\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_turnout.columns = [\"District\", \"Total_Voters\", \"Mo_Voters\", \"District_x\", \"Mo_supporters\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mo_turnout[\"turnout_rate\"] = mo_turnout[\"Mo_Voters\"]/ mo_turnout.Mo_supporters"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"#import plotly.plotly as py\n",
"# Learn about API authentication here: https://plot.ly/python/getting-started\n",
"# Find your api_key here: https://plot.ly/settings/api\n",
"\n",
"y = mo_turnout.turnout_rate\n",
"x = mo_turnout.District\n",
"width = 1/1.5\n",
"plt.bar(x, y, width, color=\"blue\")\n",
"#fig = plt.gcf()\n",
"#plot_url = py.plot_mpl(fig, filename='mpl-basic-bar')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"probs = pd.read_csv(\"Data/voters_with_petition_flag.csv\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"probs[\"Voter_ID\"] = probs[\"VOTER.ID\"].astype(str)\n",
"results_race_mo[\"Voter_ID\"] = results_race_mo[\"Voter_ID\"].astype(str) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval = pd.merge(probs[[\"Voter_ID\", \"LAST.NAME\", \"FIRST.NAME\", \n",
" \"likely_to_vote\"]], results_race_mo, on=\"Voter_ID\", how=\"left\")"
]
},
{
"cell_type": "code",
"execution_count": 206,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval = pd.read_csv(\"model_eval.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 207,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"#model_eval.to_csv(\"model_eval.csv\", index=False)"
]
},
{
"cell_type": "code",
"execution_count": 221,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval[\"pred_vote\"] = model_eval.likely_to_vote.apply(lambda x: 1 if x>0.85 else 0)"
]
},
{
"cell_type": "code",
"execution_count": 222,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import math\n",
"model_eval[\"act_vote\"] = model_eval.Voter_Name.apply(lambda x: 0 if pd.isnull(x) == True else 1)"
]
},
{
"cell_type": "code",
"execution_count": 223,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval_deduped = pd.DataFrame(\n",
" model_eval.fillna(0).groupby([\"Voter_ID\", \"LAST.NAME\", \"FIRST.NAME\"])[[\"Dist_VotI\", \"pred_vote\", \"act_vote\"]].max()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 224,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval_deduped[\"Voter_ID\"] = model_eval_deduped.index.get_level_values(0)\n",
"model_eval_deduped[\"LAST.NAME\"] = model_eval_deduped.index.get_level_values(1)\n",
"model_eval_deduped[\"FIRST.NAME\"] = model_eval_deduped.index.get_level_values(2)"
]
},
{
"cell_type": "code",
"execution_count": 225,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"model_eval_deduped.sort_values(\"Voter_ID\", inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": 228,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from sklearn.metrics import cohen_kappa_score\n",
"from sklearn.metrics import accuracy_score"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment