application_vnd.jupyter.stderr_output_1.png image_output_1.png
import cvxpy as cvx

import numpy as np

import pandas as pd

import numpy as np
import pandas as pd
import cvxpy as cvx
import pylab as plt
import networkx as nx
def prepare_data(data, suffix):
    data = data.drop(data.columns[range(3, 8)], axis=1)
    data = data.drop(data.columns[range(0, 2)], axis=1)
    data = data.groupby('settlement_name_english').sum()
    data = data.add_suffix(suffix)
    return data
def join_data(x_data, y_data, x_title, y_title):
    M1 = x_data.shape[1]
    M2 = y_data.shape[1]
    n_votes_x = np.sum(x_data.values)
    n_votes_y = np.sum(y_data.values)
    data_joint = pd.merge(x_data, y_data, how='inner', left_index=True, right_index=True)
    x_data = data_joint[data_joint.columns[range(1, M1)]]
    y_data = data_joint[data_joint.columns[M1 + 1:]]
    retained_votes_x = np.int(100 * np.round(np.sum(x_data.values) / n_votes_x, 2))
    retained_votes_y = np.int(100 * np.round(np.sum(y_data.values) / n_votes_y, 2))
    x_data = x_data.div(x_data.sum(axis=1), axis=0)
    x_data = x_data.mul(y_data.sum(axis=1), axis=0)
    avg_growth_factor = np.int(100 * np.round(np.sum(x_data.values) / n_votes_x - 1, 2))
    return (x_data, y_data)

x_data = pd.read_csv('../input/results_by_booth_2013 - english - v2.csv', encoding='iso-8859-1')
y_data = pd.read_csv('../input/results_by_booth_2015 - english - v3.csv', encoding='iso-8859-1')
x_data = prepare_data(x_data, '_2013')
y_data = prepare_data(y_data, '_2015')
[x_data, y_data] = join_data(x_data, y_data, '2013', '2015')
M1 = x_data.shape[1]
M2 = y_data.shape[1]

def solve_transfer_coefficients(x_data, y_data):
    C = cvx.Variable(x_data.shape[1], y_data.shape[1])
    constraints = [0 <= C, C <= 1, cvx.sum_entries(C, axis=1) == 1]
    objective = cvx.Minimize(cvx.sum_entries(cvx.square(x_data.values * C - y_data.values)))
    prob = cvx.Problem(objective, constraints)
    prob.solve()
    C_mat = C.value
    misplaced_votes = np.sum(np.abs(x_data.values * C_mat - y_data.values))
    properly_placed_votes = np.int(100 * np.round(1 - misplaced_votes / np.sum(y_data.values), 2))
    return C_mat
def major_parties(data, threshold, title):
    party_is_major = data.sum(axis=0) / sum(data.sum(axis=0)) > threshold
    major_party_votes = np.sum(data.values[:, party_is_major], axis=0)
    votes_in_major_parties = np.int(100 * np.round(np.sum(major_party_votes) / np.sum(data.values), 2))
    major_party_votes = major_party_votes / sum(major_party_votes)
    M = sum(party_is_major)
    major_party_titles = [party_is_major.index.values[party_is_major == True][n][:-5] for n in range(0, M)]
    return (party_is_major, major_party_votes, major_party_titles)

C_mat = solve_transfer_coefficients(x_data, y_data)
party_threshold = 0.02
transfer_threshold = 0.01
[major_x, major_party_votes_x, major_party_titles_x] = major_parties(x_data, party_threshold, '2013')
M1 = major_party_votes_x.shape[0]
[major_y, major_party_votes_y, major_party_titles_y] = major_parties(y_data, party_threshold, '2015')
M2 = major_party_votes_y.shape[0]
C_mat = C_mat[:, major_y.values]
C_mat = C_mat[major_x.values, :]
vote_transfers = np.diag(major_party_votes_x) * C_mat
predicted_y = major_party_votes_x * C_mat
major_parties_error = np.sum(np.abs(major_party_votes_y - predicted_y))
major_parties_proper_votes = np.int(100 * np.round(1 - major_parties_error, 2))
print('Transfer model properly accounts for ' + str(major_parties_proper_votes) + '% of the votes for major parties')