Линейная регрессия не возвращает ожидаемое число β - PullRequest
0 голосов
/ 15 октября 2019

У меня есть набор данных участков и результатов партий на разных выборах. После прочтения этой статьи я действительно хотел использовать линейную регрессию, чтобы ответить на вопрос: как избиратели изменили свое мнение после последних выборов?

Unnamed: 0  Map Level   Precinct ID Precinct Name   Election    Invalid Ballots (%) More Ballots Than Votes (#) More Votes Than Ballots (#) Total Voter Turnout (#) Total Voter Turnout (%) ... Average votes per minute (17:00-20:00)  CDM ED  FG  GD  LP  NR  UNM Results others
0   0   Precinct    1   63-1    2008 Parliamentary  0.0 0.0 0.0 749 62.11   ... 1.01    0.0 0.0 0.0 0.0 0.0 0.0 77.17   United National Movement    22.83
1   1   Precinct    10  63-10   2008 Parliamentary  0.0 0.0 0.0 419 70.42   ... 0.61    0.0 0.0 0.0 0.0 0.0 0.0 71.12   United National Movement    28.87
...
136 159 Precinct    8   63-1    2013 Presidential   1.75    0.0 0.0 506 50.75   ... 0.52    2.96    0.20    0.00    0.00    1.19    0.00    0.00    Giorgi Margvelashvili   95.65
137 160 Precinct    9   63-10   2013 Presidential   2.50    0.0 0.0 625 48.04   ... 0.66    1.92    0.80    0.00    0.00    1.60    0.00    0.00    Giorgi Margvelashvili   95.68

Где данный участок представлен в Precinct Name.

Чтобы понять, какие избиратели передумали, можно построить очень простую модель. Вы можете упростить выборы в N-партийную систему, отбросив все партии, которые вас не интересуют (или получили меньше количества голосов как на первых, так и на вторых выборах). Тогда, если вы сделаете предположение, что все люди, которые проголосовали аналогичным образом в 2014 году, также изменят свое мнение в 2019 году. Более конкретно, люди, которые проголосовали за партию Pᵢ в 2008 году, имеют одинаковую вероятность голосовать за партию Pᵣ в 2013 году. (Я называю эту вероятность Xᵢᵣ)

Итак, для данного избирательного участка, чтобы «объяснить» или «предсказать» количество голосов Vᵣ²ᵣ для партии Pᵣ в 2013 году, на основе результатов 2008 года я могу использовать вероятностиXᵢᵣ следующим образом:

$$V_r^{2013} = \sum_i V_i^{2008}\times X_{ir} $$

Это простая линейная регрессия. Итак, поскольку у нас есть 7 сторон, результат должен быть для каждого $ X_ {ir} $ массивом размера 7. Однако. С моделью линейной регрессии, которую я показываю сразу после того, как это не так.

Поэтому я попытался реализовать модель, она на Python, извините за это:

def error(x_i,y_i, beta):
    return y_i - predict(x_i, beta)

def squared_error(x_i, y_i, beta):
    return error(x_i, y_i, beta)**2

def squared_error_gradient(x_i, y_i, beta):
    """the gradient (with respect to beta)
    corresponding to the ith squared error term"""
    return [-2 * x_ij * error(x_i,y_i, beta)
           for x_ij in x_i]

def predict(x_i, beta):
    # x_i.insert(0,1)
    """assumes that the first element of each x_i is 1"""
    return dot(x_i, beta)

def dot(v, w):
    """v_1 * w_1 + ... + v_n * w_n"""
    return sum(v_i * w_i for v_i, w_i in zip(v, w))

def in_random_order(data):
    """generator that returns the elements of data in random order"""
    indexes = [i for i, _ in enumerate(data)] # create a list of indexes
    random.shuffle(indexes) # shuffle them
    for i in indexes: # return the data in that order
        yield data[i]

def minimize_stochastic(target_fn, gradient_fn, x, y, theta_0, alpha_0=0.01):
    data = zip(x, y)
    theta = theta_0 # initial guess
    alpha = alpha_0 # initial step size
    min_theta, min_value = None, float("inf") # the minimum so far
    iterations_with_no_improvement = 0

    # if we ever go 100 iterations with no improvement, stop
    while iterations_with_no_improvement < 100:
        value = sum( target_fn(x_i, y_i, theta) for x_i, y_i in data )
        if value < min_value:
            # if we've found a new minimum, remember it
            # and go back to the original step size
            min_theta, min_value = theta, value
            iterations_with_no_improvement = 0
            alpha = alpha_0
        else:
            # otherwise we're not improving, so try shrinking the step size
            iterations_with_no_improvement += 1
            alpha *= 0.9
            # and take a gradient step for each of the data points
        for x_i, y_i in in_random_order(data):
            gradient_i = gradient_fn(x_i, y_i, theta)
            theta = vector_subtract(theta, scalar_multiply(alpha, gradient_i))
    return min_theta

def estimate_beta(x,y):
    beta_initial = [random.random() for x_i in x[0]]
    return minimize_stochastic(squared_error,
                              squared_error_gradient,
                              x,y,
                              beta_initial,
                              0.001)

ДляНапример, скажем, у нас есть один выбор в 2008 году и один выбор в 2013 году:

x = [[0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [77.17], [22.83]] # each arrangement within this arrangement is the % of people who voted for a party in 2008
y = [[0.35], [0.35], [0.0], [0.0], [2.43], [0.0], [0.0], [96.87]] # each number is the % of people who voted for a party in 2013
random.seed(0)
random.seed(0)
probabilities = [estimate_beta(x,y_i)for y_i in y]
print(probabilities)

Возвращает:

[[0.8444218515250481], [0.7579544029403025], [0.420571580830845], [0.25891675029296335], [0.5112747213686085], [0.4049341374504143], [0.7837985890347726], [0.30331272607892745]]

Я ожидал столько значений, сколько партий в каждом массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...