Ваш гид по логистической регрессии с Titanic Dataset

Следующий алгоритм машинного обучения, о котором мы поговорим, - это логистическая регрессия (также называемая сигмовидной функцией). По мере того, как я запишу, я узнаю больше, как и вы. Итак, давайте совершим путешествие к логистической регрессии и отметим еще один алгоритм как ВЫПОЛНЕНО!

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

Так объясняет Википедия. Выглядит довольно просто, правда? Цель модели - дать нам 0 или 1. Модель предсказывает значение от 0 до 1, и это значение показывает вероятность такой ситуации.

Логистическая регрессия не позволяет прогнозировать непрерывные значения. Логистическая регрессия позволяет определить, является ли что-то истинным или ложным.

Давайте рассмотрим пример. На самом деле, довольно известный. Набор данных Titanic. У вас есть несколько функций, и с помощью логистической регрессии вы предсказываете, мертвы они или нет. Если значение, предсказываемое моделью, будет 0,79, это будет означать, что человек на 79% жив, 21% мертв.

Когда вероятность больше или равна 0,5, двоичное значение равно 1, когда вероятность меньше 0,5, двоичное значение равно 0. Таким образом, человек, которого я только что упомянул выше, будет классифицирован как 1, жив. Модель возвращает 1 (верно).

График логистической регрессии выглядит как «S» между 0 и 1, как вы можете видеть здесь:

Кривая показывает вероятность случая.

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

Какая максимальная вероятность ?!

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

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

Вы можете прочитать эту статью, если хотите узнать больше.



Или вы можете посмотреть это видео.

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

Набор данных доступен через библиотеку Seaborn. Если у вас еще не установлена ​​библиотека Seaborn, вы можете установить ее в командной строке следующим образом:

pip3 install seaborn # check Seaborn documentations for details

Теперь мы можем импортировать наши библиотеки:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from seaborn import load_dataset # this method will help us to #download the Titanic dataset
%matplotlib inline # if you use jupyter notebook
plt.style.use('ggplot') # check for more with plt.style.available

Скачивание набора данных:

data = load_dataset("titanic")
data

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

data.info()

Как видите, у нас есть нулевые значения в столбцах age, embarked, deck, embarked_town. Некоторые из них мы отбросим, ​​а с остальными разберемся.

Некоторые столбцы имеют одинаковые значения с разными типами значений или именами. Например, "who", "sex" и "adult_male". Я не хочу, чтобы они были в моей модели.

columns = ['alive', 'alone', 'embark_town', 'who', 'adult_male', 'deck']
data_2 = data.drop(columns, axis=1)

Список столбцов содержит имена, которые я хочу удалить из своего набора данных. Метод drop их отбросит. axis = 1 означает, что мы хотим удалить столбец.

Я назначил свой новый набор данных другой переменной. При желании вы можете внести постоянные изменения в исходные данные с помощью «inplace = True».

data_2.describe(include='all').T

print(f"Max value of age column : {data_2['age'].max()}")
print(f"Min value of age column : {data_2['age'].min()}")
>> Max value of age column : 80.0
>> Min value of age column : 0.42

Мы можем классифицировать столбец возраста со значениями от 0 до 80.

bins = [0, 5, 17, 25, 50, 80]
labels = ['Infant', 'Kid', 'Young', 'Adult', 'Old']
data_2['age'] = pd.cut(data_2['age'], bins = bins, labels=labels)

Метод «вырезки» панд позволит нам сделать нашу собственную категоризацию.

pd.DataFrame(data_2['age'].value_counts())

Воля! Мы видим, что большинство составляют взрослые.

У нас по-прежнему есть нулевые значения в столбце "возраст".

data_3['age'].mode()[0]
>> 'Adult'

Мы можем заполнить нулевые значения режимом этого столбца. Это вариант, и я этим займусь!

data_4 = data_3.fillna({'age' : data_3['age'].mode()[0]})

Мы закончили со столбцом «Возраст». Да! Пришло время колонки «встал».

data_2['embarked'].unique()
>> array(['S', 'C', 'Q', nan], dtype=object)

В наших столбцах «началось» явно есть «S, C, Q» и «nan».

print(f"How many 'S' on embarked column : {data_2[data_2['embarked'] == 'S'].shape[0]}")
print(f"How many 'C' on embarked column : {data_2[data_2['embarked'] == 'C'].shape[0]}")
print(f"How many 'Q' on embarked column : {data_2[data_2['embarked'] == 'Q'].shape[0]}")
>> How many 'S' on embarked column : 644
>> How many 'C' on embarked column : 168
>> How many 'Q' on embarked column : 77

Похоже, мы можем использовать режим этого столбца для заполнения значений nan.

data_3 = data_2.fillna({'embarked' : 'S'})
data_4[['pclass', 'survived']].groupby(['pclass']).sum().sort_values(by='survived')

data_4[['sex', 'survived']].groupby(['sex']).sum().sort_values(by='survived')

bins = [-1, 7.9104, 14.4542, 31, 512.330]
labels = [’low’, 'medium-low’, 'medium’, 'high’]
data_4[’fare’] = pd.cut(data_4["fare"], bins = bins, labels = labels)

Мы также можем классифицировать столбец тарифов, как в приведенном выше коде.

Финальная версия нашего набора данных.

Мы также должны отбросить "class", потому что он такой же, как pclass, а pclass уже числовой.

data_5 = data_4.drop('class', axis=1)
sns.distplot(data_5['survived'])

plt.figure(figsize=(20, 10))
plt.subplot(321)
sns.barplot(x = 'sibsp', y = 'survived', data = data_5)
plt.subplot(322)
sns.barplot(x = 'fare', y = 'survived', data = data_5)
plt.subplot(323)
sns.barplot(x = 'pclass', y = 'survived', data = data_5)
plt.subplot(324)
sns.barplot(x = 'age', y = 'survived', data = data_5)
plt.subplot(325)
sns.barplot(x = 'sex', y = 'survived', data = data_5)
plt.subplot(326)
sns.barplot(x = 'embarked', y = 'survived', data = data_5);

Теперь модели машинного обучения ненавидят нечисловые значения. Мы не можем поместить их в наш поезд и тестовые данные. Нам нужно преобразовать их в числовые значения. У вас есть два варианта для этого; Label Encoder и метод Pandas get_dummies. Я не буду вдаваться в подробности. Я собираюсь использовать get_dummies.

dummies = ['fare', 'age', 'embarked', 'sex']
dummy_data = pd.get_dummies(data_5[dummies])

Приоткроем немного. «Dummies» содержит имена столбцов, которые мы хотим преобразовать в числовые значения. Каждая переменная в них станет столбцом, и их отсутствие будет определять как 0 и 1, верны они для этого пассажира или нет.

dummy_data.shape
>> (891, 10)

Мы объединим два фрейма данных и отбросим старые столбцы.

data_6 = pd.concat([data_5, dummy_data], axis = 1)
data_6.drop(dummies, axis=1, inplace=True)

Теперь у нас 891 строка, 18 столбцов. Мы готовы построить нашу модель.

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix

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

X = data_6.drop('survived', axis = 1)
y = data_6['survived']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.33, random_state = 0)
# X contains independent values, y contains dependent value

Построение модели:

log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
y_pred = log_reg.predict(X_test)
y_pred

y_pred выглядит так:

array([0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1,
       0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
       1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
       1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0,
       1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
       0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0,
       1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
       1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1,
       0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
       0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
       0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1])

Мы можем проверить оценку точности нашей модели.

accuracy_score(y_pred, y_test)
>> 0.8067796610169492
confusion_matrix(y_pred, y_test)
>> array([[158,  31],
          [ 26,  80]])
# 31 + 26 = 57 wrong prediction

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

Хорошо, что теперь вы знаете алгоритм логистической регрессии и знаете, как его реализовать!