Вопрос или проблема
У меня есть набор данных по избирательным участкам и результатам партий на различных выборах. После прочтения этой статьи мне очень захотелось использовать линейную регрессию, чтобы ответить на вопрос: как изменилось мнение избирателей с последних выборов?
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 Избирательный участок 1 63-1 2008 Парламентские 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 Объединенное национальное движение 22.83
1 1 Избирательный участок 10 63-10 2008 Парламентские 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 Объединенное национальное движение 28.87
...
136 159 Избирательный участок 8 63-1 2013 Президентские 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 Георгий Маргвелашвили 95.65
137 160 Избирательный участок 9 63-10 2013 Президентские 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 Георгий Маргвелашвили 95.68
Где указанный избирательный участок представлен в Название участка
.
Чтобы понять, какие избиратели изменили свое мнение, можно построить очень простую модель. Вы можете упростить выборы до системы с N партиями, исключив все партии, которые вам не интересны (или набрали менее определенного количества голосов как на первых, так и на вторых выборах). Тогда, если вы предположите, что все люди, голосовавшие аналогично в 2014 году, изменят свое мнение тем же образом в 2019 году. Более конкретно, люди, голосовавшие за партию Pᵢ в 2008 году, имеют такую же вероятность проголосовать за партию Pᵣ в 2013 году. (Я называю эту вероятность Xᵢᵣ)
Итак, для данного избирательного участка, чтобы «объяснить» или «предсказать» количество голосов Vᵣ²⁰¹⁹ за партию Pᵣ в 2013 году, основываясь на результатах 2008 года, я могу использовать вероятности Xᵢᵣ (или $\beta_i$ в более классической нотации) следующим образом:
$$V_r^{2013} = \sum_i V_i^{2008}\times X_{ir} $$
Это простая линейная регрессия. Итак, поскольку у нас есть 7 партий, результат должен быть для каждого $X_{r}$ (набор вероятностей голосовать за партию $r$) массивом размером 7. Однако с линейной регрессионной моделью, которую я покажу чуть позже, это не так.
Я попытался реализовать модель, она на Python 3:
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):
"""градиент (по отношению к бета)
соответствующий i-му квадратному ошибочному терму"""
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)
"""предполагает, что первый элемент каждого x_i равен 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):
"""генератор, который возвращает элементы данных в случайном порядке"""
indexes = [i for i, _ in enumerate(data)] # создаем список индексов
random.shuffle(indexes) # перемешиваем их
for i in indexes: # возвращаем данные в этом порядке
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 # начальная догадка
alpha = alpha_0 # начальный шаг
min_theta, min_value = None, float("inf") # минимум на данный момент
iterations_with_no_improvement = 0
# если мы когда-либо проходим 100 итераций без улучшений, останавливаемся
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:
# если мы нашли новый минимум, запоминаем его
# и возвращаемся к исходному размеру шага
min_theta, min_value = theta, value
iterations_with_no_improvement = 0
alpha = alpha_0
else:
# в противном случае мы не улучшаем, поэтому попробуем уменьшить размер шага
iterations_with_no_improvement += 1
alpha *= 0.9
# и делаем шаг градиента для каждой из точек данных
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]] # каждая организация внутри этого расположения - это % людей, которые проголосовали за партию в 2008 году
y = [[0.35], [0.35], [0.0], [0.0], [2.43], [0.0], [0.0], [96.87]] # каждое число - это % людей, которые проголосовали за партию в 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]]
Я ожидал, что в каждом массиве будет столько же значений, сколько партий.
Немного сложно понять ваш вопрос, не увидев данные. Однако давайте вспомним, как работает линейная регрессия. Простая модель с одной независимой переменной $x_1$ выглядит так:
$$ y = \beta_0 + \beta_1 x_{1,i}+u_i.$$
Здесь у нас есть одна независимая переменная $x_1$, $u_i$ – это ошибка. Для этой модели у нас есть два коэффициента: $\beta_0$ – это пересечение, а $\beta_1$ – коэффициент для $x_1$. Таким образом, для одного предиктора (независимой переменной) у нас есть два коэффициента.
Конечно, можно добавить больше $x$ в регрессию. Для $n$ независимых переменных у нас будет $n+1$ коэффициентов.
Обратите внимание, что если вы используете индикаторные переменные (также известные как фиктивные переменные), которые равны $1$, если правда, и $0$ в противном случае, вам нужно определить базовую категорию. Модель с одной непрерывной переменной $x_1$ и одним индикатором $x_2$ выглядела бы так:
$$ y = \beta_0 + \beta_1 x_{1,i}+\beta_2 x_{2,i}+u_i.$$
В этом случае $\beta_0$ – это пересечение, если $x_2=0$, а $\beta_0 + \beta_2$ – это пересечение, если $x_2=1$. Однако у вас все равно есть $n+1$ коэффициентов в модели.
Ответ или решение
Вопрос о том, почему линейная регрессия не возвращает ожидаемое количество коэффициентов (\beta_i), можно проанализировать, основываясь на предоставленной информации о ваших данных и реализации модели.
Понимание линейной регрессии
Линейная регрессия подразумевает, что зависимая переменная (y) может быть предсказана на основе одной или нескольких независимых переменных (x). Формула может быть записана как:
[
y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + … + \beta_n x_n + u
]
где:
- (\beta_0) — свободный член (пересечение),
- (\beta_1, \beta_2, …, \beta_n) — коэффициенты, соответствующие независимым переменным (x_1, x_2, …, x_n),
- (u) — ошибка.
Анализ ваших данных
Вы упомянули, что у вас есть 7 партий, и вы ожидаете, что линейная регрессия вернёт массив из 7 значений ((X_r)). Однако вы получили только одно значение для каждого массива выборов.
Этот результат может быть объяснён несколькими причинами:
-
Структура ваших данных: Возможно, вы неправильно организовали данные. Должны быть независимые переменные (в вашем случае результаты голосования за партии в 2008 году), которые формируют (X), и зависимая переменная (y) (результаты голосования в 2013 году). Если ваши (x) и (y) структуры не совпадают по размерности или форме, это приведет к неправильным результатам.
-
Единичная независимая переменная: В вашем коде при вызове
estimate_beta(x,y_i)
каждая (y_i) рассматривается как отдельная зависимая переменная для одного и того же набора независимых переменных (X). Если (X) содержит только одну последовательность значений (например, только для одной партии за 2008 год), то модель будет оказывать влияние только на одну переменную и, соответственно, будет возвращать всего один коэффициент. Для получения коэффициентов для каждой партии вам нужно передавать все результаты голосования для каждой партии в 2008 году как отдельные независимые переменные.
Предложение по исправлению
Чтобы исправить вашу реализацию и получить ожидаемые значения коэффициентов для каждой партии, попробуйте следующее:
-
Перепишите ваши данные в более подходящей форме. Например, вместо использования вложенного списка для независимых переменных (x) используйте матрицу, где каждая строка — это набор результатов за 2008 год для каждой партии.
-
Измените структуру вывода: Убедитесь, что при вызове
estimate_beta(x, y)
вы передаете правильное количество независимых переменных.
Пример структуры данных:
# x - каждая строка соответствует одной партии, каждый элемент в строке соответствует результатам 2008 года
x = [
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 77.17], # Партия 1
[0.35, 0.35, 0.0, 0.0, 2.43, 0.0, 0.0], # Партия 2
# и так далее для остальных партий
]
# y - результаты для каждой партии на выборах 2013 года
y = [96.87, 0.35, ...] # Результаты на 2013 год
Заключение
Подводя итог, ваше недоразумение связано с тем, что вы пытаетесь оценить линейную регрессию на одной и той же независимой переменной для каждой отдельной зависимости, что приводит к получению лишь одного коэффициента на каждую выборку. Для достижения желаемых коэффициентов (\beta) для всех партий убедитесь, что каждая партия представлена как отдельная колонка в ваших данных. Надеюсь, это поможет вам правильно настроить вашу модель линейной регрессии.