Контролируемая регрессия и горячее кодирование для классификации избирателей на основе данных опроса

Эксперимент

Мы собираемся передать модели машинного обучения некоторые выборочные данные (которые мы собираемся сгенерировать случайным образом) о небольшой группе (выдуманных) избирателей и о том, как они говорят, что собираются голосовать на предстоящих выборах. Затем модель или алгоритм будет учитьсяна этих обучающих данных(т. применить это ко всей остальной избирательной базе.

В конце мы получим прогноз того, как люди будут голосовать на наших выдуманных выборах.

Мы будем использовать две разные модели машинного обучения, чтобы сравнить результаты и понять, почему One-Hot Encoding полезен.

Генерация набора данных

Я собираюсь случайным образом сгенерировать все данные для наших выдуманных выборов (нам не нужно много для этого эксперимента, поэтому это можно сделать вручную).

Первый набор строк будет имитировать опрос о том, как двадцать человек указали, что они будут голосовать, а также данные о них (возраст, пол, профессия и местонахождение). Это будут обучающие данные, которые мы собираемся обработать, а затем передать в модель машинного обучения. В идеале мы хотели бы получить больше данных, потому что тогда модель научилась бы становиться более точной, но сохранение небольшого пула делает все более читаемым для этой статьи.

Вы увидите, что на этих выборах есть только две партии, за которые люди могут голосовать, но их может быть сколько угодно, поскольку модель без проблем работает для нескольких классификаций.

Вторая группа строк в наборе данных состоит из списка всех других избирателей на этих выборах (да, это небольшие выборы!), и это люди, которых мы хотим попытаться классифицировать относительно того, каким образом они потенциально могли бы проголосовать. .

Данные не содержат строк, поскольку модели машинного обучения, как правило, не работают с данными, которые не представлены в виде чисел. Поэтому пол, профессия и местонахождение меняются на число, которое их представляет. Нет необходимости раскрывать, какие категории представляют эти числа, поскольку это эксперимент, и все, что нам нужно, — это числа, представляющие разные категории для каждого измерения (или столбца).

Поэтому следующий «список списков» содержит сначала обучающие данные, а затем данные, которые мы хотим классифицировать. В нашей программе (полный исходный код показан далее в этой статье) все эти данные хранятся в одной структуре для простоты и потому, что однократное кодирование может стать несопоставимым, если двоичное кодирование различается в двух наборах данных, то есть проще закодировать все данные одним ударом и разделить их позже.

Во-первых, данные обучения:

# location, age, gender, income_bracket, how_voted
    [4,55,1,5,1],
    [8,65,2,8,1],
    [7,70,1,1,1],
    [9,68,2,10,1],
    [14,45,1,11,1],
    [15,33,2,12,1],
    [15,55,1,10,1],
    [16,65,2,15,1],
    [17,70,1,4,1],
    [19,42,1,11,1],
    [20,25,2,14,2],
    [21,33,1,20,2],
    [24,25,2,10,2],
    [28,65,1,15,2],
    [27,30,2,16,2],
    [29,28,1,15,2],
    [34,25,2,18,2],
    [21,33,1,24,2],
    [24,25,2,18,2],
    [21,18,1,21,2],

Во-вторых, тестовые данные:

Это фактические данные, которые мы хотим классифицировать, и вы увидите, что в последнем столбце есть ноль, который просто действует как заполнитель, поэтому столбцы не пусты.

# location, age, gender, income_bracket, NA
    [6,65,1,6,0],
    [9,55,2,8,0],
    [4,69,1,2,0],
    [9,66,2,8,0],
    [3,48,1,10,0],
    [11,39,2,14,0],
    [11,57,1,10,0],
    [14,63,2,11,0],
    [12,62,1,6,0],
    [10,45,2,8,0],
    [9,60,1,9,0],
    [9,75,2,9,0],
   
    [24,28,2,15,0],
    [24,30,1,21,0],
    [24,24,2,13,0],
    [25,60,1,14,0],
    [26,20,2,17,0],
    [26,26,1,17,0],
    [30,25,2,20,0],
    [22,23,1,23,0],
    [22,35,2,19,0],
    [24,28,1,25,0],
    [30,23,2,23,0],
    [21,27,1,19,0],
    [18,35,2,25,0],

Как работает модель

Этот тип машинного обучения, который мы собираемся здесь использовать, известен как классификация с учителем.

Контролируемый означает, что ему нужны некоторые результаты, чтобы он мог скорректировать свои ответы в соответствии с результатами, пока не будет достигнут разумный уровень ошибки. Как и люди, когда мы делаем предположения о вещах, которых не знаем, а затем сверяем их с ответами или нашим опытом; затем, если мы ошибаемся, мы просто корректируем свое мышление, пока не получим более точные ответы на эти вопросы. Другими словами, мы учимся на опыте, и это то, что машина будет делать на этапе обучения (когда мы вызываем метод fit()).

Классификация означает, что он попытается поместить строки данных, составляющие набор данных, в разные группы голосования, и эти группы предоставляются обучающими данными (в данном случае две голосующие стороны).

Используемые модели (или алгоритмы)

SVM — машины опорных векторов, как описано здесь, на веб-сайте scikit-learn https://scikit-learn.org/stable/modules/svm.html.

Наивный Байес — как описано здесь, на https://scikit-learn.org/stable/modules/naive_bayes.html

Можно ли использовать этот тип машинного обучения только для выборов?

Нет, его можно использовать для любого приложения, которое включает в себя классификацию данных по группам. Например, его можно использовать, чтобы выяснить, получали ли вы спам по электронной почте или подходят ли условия для занятий вашим любимым видом спорта.

Полный исходный код:

import pandas as pd
import random
from sklearn import svm
from sklearn.naive_bayes import GaussianNB
voting_data = [
    
    # location, age, gender, income_bracket, how_voted
    [4,55,1,5,1],
    [8,65,2,8,1],
    [7,70,1,1,1],
    [9,68,2,10,1],
    [14,45,1,11,1],
    [15,33,2,12,1],
    [15,55,1,10,1],
    [16,65,2,15,1],
    [17,70,1,4,1],
    [19,42,1,11,1],
    [20,25,2,14,2],
    [21,33,1,20,2],
    [24,25,2,10,2],
    [28,65,1,15,2],
    [27,30,2,16,2],
    [29,28,1,15,2],
    [34,25,2,18,2],
    [21,33,1,24,2],
    [24,25,2,18,2],
    [21,18,1,21,2],
    
    
    # location, age, gender, income_bracket, NA
    [6,65,1,6,0],
    [9,55,2,8,0],
    [4,69,1,2,0],
    [9,66,2,8,0],
    [3,48,1,10,0],
    [11,39,2,14,0],
    [11,57,1,10,0],
    [14,63,2,11,0],
    [12,62,1,6,0],
    [10,45,2,8,0],
    [9,60,1,9,0],
    [9,75,2,9,0],
   
    [24,28,2,15,0],
    [24,30,1,21,0],
    [24,24,2,13,0],
    [25,60,1,14,0],
    [26,20,2,17,0],
    [26,26,1,17,0],
    [30,25,2,20,0],
    [22,23,1,23,0],
    [22,35,2,19,0],
    [24,28,1,25,0],
    [30,23,2,23,0],
    [21,27,1,19,0],
    [18,35,2,25,0],
]
df = pd.DataFrame(voting_data,columns=["Location","Age","Gender","Income Bracket","How Voted"])        
        
from sklearn.preprocessing import OneHotEncoder
# Create a new dataframe that has all columns apart from the last one
X = df.iloc[:, :-1].values
# Build Y by taking just the training rows and then just the last column
Y = df.iloc[0:20, -1:]
# One-hot encode the category columns which are location and gender ( not age and income bracket as the number sequence means something )
oh_df = OneHotEncoder( categorical_features = [0,2])
enc = oh_df.fit_transform(X).toarray()
    
# Now split the dataframe up into a training set 
training_X = enc[:20]
# and the set we want to categorise
unknown_X = enc[20:]
model = svm.SVC()
model2 = GaussianNB()
model.fit(training_X, Y)
model2.fit(training_X, Y)
training_predictions = model.predict(training_X)
    
training_predictions2 = model2.predict(training_X)
from sklearn.metrics import accuracy_score
print ("SVM training data accuracy is", str(accuracy_score(Y, model.predict(training_X))),"%",
       "Naive Bayes training data accuracy is", str(accuracy_score(Y, model2.predict(training_X))),"%")
predictions = model.predict(unknown_X)
predictions2 = model2.predict(unknown_X)
for count in range(0,len(predictions)):
    print ("Person_" + str(count+1),"is predicted to vote by SVM for Party",str(predictions[count]),"and is predicted to vote by NB for Party",str(predictions2[count]))

Результаты

Используя как SVM (машины опорных векторов), так и наивные байесовские алгоритмы, мы получаем следующие ответы для категоризации:

SVM training accuracy is 0.95 % Naive Bayes training accuracy is 1.0 %
Person_1 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_2 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_3 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_4 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_5 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_6 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_7 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_8 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_9 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_10 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_11 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_12 predicted to vote by SVM for Party 1 and by NB for Party 1
Person_13 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_14 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_15 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_16 predicted to vote by SVM for Party 1 and by NB for Party 2
Person_17 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_18 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_19 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_20 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_21 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_22 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_23 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_24 predicted to vote by SVM for Party 2 and by NB for Party 2
Person_25 predicted to vote by SVM for Party 2 and by NB for Party 2

Анализ результатов

В обучающих данных разница между двумя группами совершенно очевидна для человеческого глаза: более молодые избиратели, похоже, отдают предпочтение одной партии, а не другой. В тестовых данных (данных, которые мы просим модели делать прогнозы) я также намеренно сделал данные достаточно поляризованными, чтобы облегчить отслеживание результатов. Вы можете видеть, что некоторые столбцы более чувствительны, чем другие, в отношении того, за какую партию, по мнению модели, люди собираются голосовать.

Имея это в виду, модель SVM лучше справляется с классификацией избирателей на основе предвзятости, которая была заложена в данные. Наивный Байес, однако, делает некоторые предсказания, которые кажутся несколько неточными, но все же неплохо справляется с классификацией.

Однако эти прогнозы не являются ни правильными, ни неправильными, а просто продуктом данных, которые мы выбираем, и модели, которую мы к ним применили. SVM использует гиперплоскость, чтобы попытаться разделить различные классификации, и в этом конкретном случае использования это, вероятно, более логичный подход, чем вероятностный подход, который использует Наивный Байес. Конечно, мы могли бы использовать и другие алгоритмы, чтобы увидеть, какую разницу они дадут, и я призываю людей, читающих это, сделать именно это.

Таким образом, большая часть машинного обучения сводится к преобразованию данных в пригодный для использования формат и выбору модели, которая дает результаты таким образом, который моделирует то, как человек будет думать и решать ту же проблему. Следовательно, модели машинного обучения могут быть такими же неточными, как и человек при решении этих задач, но если они будут признаны точными, то вы выиграете в скорости! Мы могли бы предоставить информацию о 100 миллионах избирателей, и эта программа могла бы затем предсказать, как все эти люди будут голосовать за очень короткое время по сравнению с тем, что мог бы сделать любой человек.

Горячее кодирование — в чем его важность и зачем его использовать?

Вы видели в исходном коде, что я использовал One-Hot Encoding, и что это такое?

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

Например, Возраст является последовательным, и эта последовательность имеет значение. Мы хотим, чтобы наша модель знала, что по мере увеличения (или уменьшения) возраста сравнение допустимо.

Однако, когда дело доходит до категоризации таких вещей, как профессия (и помните, что строки не разрешены в большинстве алгоритмов ML), после того, как мы преобразуем каждую категорию профессии в целое число, мы не хотим, чтобы алгоритм думал, что существует связь между числами, потому что если это это сделает неправильные расчеты.

Например, если бы у нас была категория животных, и мы дали бы каждому животному целочисленное значение, скажем, слон = 1, кошка = 2 и мышь = 3, тогда мы бы хотели, чтобы алгоритм ML решил, что, поскольку 3 больше, чем 1, что мышь больше слона?

Решением этой проблемы является One-Hot Encode, при котором вы конвертируете эти целые числа в двоичные числа, и когда они передаются алгоритму, он понимает, что ассоциации нет.

Вы должны быть осторожны, чтобы кодировать правильные столбцы. Кодирование возраста, например, было бы катастрофой, поскольку нам нужна взаимосвязь последовательности, иначе модель не поняла бы, что 56-летний и 57-летний люди более связаны, чем 28-летний человек, для определенных приложений.

Если вы хотите понять эффект кодирования, просто закомментируйте строки, которые применяют его в программе выше, и вы увидите, что прогнозы голосования несколько меняются, потому что модель начинает выполнять вычисления на основе неверных предположений, которые вы ей показали ( сказав, что вы можете решить, что определенные профессии связаны, и дать им целочисленные значения для построения последовательности, возможно, на основе средней заработной платы, которую они платят, и в этом случае вы НЕ хотите кодировать их в двоичном формате).

Таким образом, это ключевой момент в машинном обучении; независимо от того, насколько хороши данные, которые вы предоставляете алгоритму, если они обрабатываются таким образом, что модель, вероятно, делает предположения, с которыми вы не согласны, тогда не имеет значения, используете ли вы что-то простое, например, линейную регрессию или что-то сложное вроде нейронной сети, вы всегда будете получать неверные ответы. Поэтому вам, вероятно, лучше инвестировать больше времени в обработку данных и моделирование того, как вы хотите повернуть данные, а не в элемент машинного обучения вашего программирования, потому что именно из этого часто будет исходить реальная ценность.

Надеюсь, эта статья окажется полезной, и, пожалуйста, дайте мне возможность задать вопросы или оставить отзыв, и я постараюсь ответить, когда у меня будет такая возможность.

Спасибо за чтение.