Построение прогностических моделей логистическая регрессия на языке Python

Прогнозирование с помощью логистической регрессии на языке Python

 

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

Представьте себе задачу бинарной классификации с классами 0 и 1. Логистическая регрессия подгоняет логистическую или сигмоидную функцию к входным данным и предсказывает вероятность того, что точка запроса принадлежит классу 1. Интересно, не так ли?

В этом руководстве мы узнаем о логистической регрессии с самого начала, рассмотрим:

  • Логистическую (или сигмоидную) функцию
  • Как мы переходим от линейной к логистической регрессии
  • Как работает логистическая регрессия

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

 

Логистическая функция

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

   

Когда вы строите график сигмоидной функции, он будет выглядеть так:

   

Из графика видно, что:

  • Когда x = 0, σ(x) принимает значение 0.5.
  • Когда x стремится к +∞, σ(x) стремится к 1.
  • Когда x стремится к -∞, σ(x) стремится к 0.

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

 

От линейной регрессии к логистической регрессии

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

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

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

  

Как же мы переходим от линейной к логистической регрессии? В линейной регрессии предсказываемый выход задается выражением:

Где βs – коэффициенты, а X_is – предикторы (или признаки).

Без потери общности предположим, что X_0 = 1:

Итак, у нас может быть более краткое выражение:

   

В логистической регрессии нам нужна предсказанная вероятность p_i в интервале [0,1]. Мы знаем, что логистическая функция сжимает входные данные, чтобы они принимали значения в интервале [0,1].

Подставляя это выражение в логистическую функцию, мы получаем предсказанную вероятность:

   

 

Под капотом логистической регрессии

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

Оценка максимального правдоподобия (MLE) используется для оценки параметров модели логистической регрессии путем максимизации функции правдоподобия. Рассмотрим процесс MLE в логистической регрессии и формулировку функции стоимости для оптимизации, используя градиентный спуск.

 

Разбор оценки максимального правдоподобия

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

   

Здесь βs – параметры модели или коэффициенты. X_1, X_2,…, X_n – предикторные переменные.

MLE стремится найти значения β, которые максимизируют правдоподобие наблюдаемых данных. Функция правдоподобия, обозначаемая как L(β), представляет собой вероятность наблюдения данных результатов при заданных значениях предикторов в модели логистической регрессии.

 

Формулирование функции логарифма правдоподобия

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

Функция логарифма правдоподобия для логистической регрессии задается следующим образом:

   

 

Функция стоимости и градиентный спуск

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

 

Функция стоимости для логистической регрессии

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

   

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

 

Градиентный спуск в логистической регрессии

 

Градиентный спуск – это итерационный алгоритм оптимизации, который обновляет параметры модели β в противоположном направлении градиента функции стоимости относительно β. Правило обновления на шаге t+1 для логистической регрессии с использованием градиентного спуска задается следующим образом:

   

Где α – скорость обучения.

Частные производные могут быть вычислены с использованием правила цепочки. Градиентный спуск итеративно обновляет параметры до сходимости с тем, чтобы минимизировать логистическую потерю. При сходимости он находит оптимальные значения β, которые максимизируют правдоподобие наблюдаемых данных.

 

Логистическая регрессия на Python с помощью Scikit-Learn

 

Теперь, когда вы знаете, как работает логистическая регрессия, давайте построим прогностическую модель с использованием библиотеки scikit-learn.

Мы будем использовать набор данных ионосферы из репозитория машинного обучения UCI для этого учебного руководства. Набор данных состоит из 34 числовых признаков. Результат является бинарным и может быть «хорошим» или «плохим» (обозначается как «g» или «b»). Метка «хорошего» относится к ЭХО в ионосфере, обнаружившему некоторую структуру.

 

Шаг 1 – Загрузка набора данных

 Сначала загрузите набор данных и прочтите его в pandas dataframe:

import pandas as pd
import urllib
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/ionosphere/iphere.data"
data = urllib.request.urlopen(url)
df = pd.read_csv(data, header=None)

 

Шаг 2 – Изучение набора данных

 

Давайте посмотрим на первые несколько строк dataframe:

# Отобразить первые несколько строк DataFrame
df.head()

 

Усеченный вывод df.head()

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

# Получить информацию о наборе данных
print(df.info())

 

Усеченный вывод df.info()

Поскольку у нас есть только числовые признаки, мы также можем получить некоторую описательную статистику, используя метод describe() для dataframe:

# Получить описательную статистику набора данных
print(df.describe())

 

Усеченный вывод df.describe()

 The имена столбцов в настоящее время являются 0 до 34 – включая метку. Поскольку набор данных не предоставляет описательных имен для столбцов, он просто называет их attribute_1 до attribute_34, если вы хотите, вы можете переименовать столбцы фрейма данных, как показано ниже:

column_names = ["attribute_1", "attribute_2", "attribute_3", "attribute_4", "attribute_5","attribute_6", "attribute_7", "attribute_8", "attribute_9", "attribute_10","attribute_11", "attribute_12", "attribute_13", "attribute_14", "attribute_15","attribute_16", "attribute_17", "attribute_18", "attribute_19", "attribute_20","attribute_21", "attribute_22", "attribute_23", "attribute_24", "attribute_25","attribute_26", "attribute_27", "attribute_28", "attribute_29", "attribute_30","attribute_31", "attribute_32", "attribute_33", "attribute_34", "class_label"]
df.columns = column_names

 

Примечание: Этот шаг является чисто необязательным. Вы можете продолжить с исходными именами столбцов, если предпочитаете.

 

# Отобразить первые несколько строк DataFrame
df.head()

 Усеченный вывод df.head() [После переименования столбцов]

 

Шаг 3 – Переименование классов и визуализация распределения классов

Поскольку метки классов на выходе – «g» и «b», нам необходимо преобразовать их в 1 и 0 соответственно. Вы можете сделать это с помощью map() или replace():

# Преобразовать метки классов из 'g' и 'b' в 1 и 0 соответственно
df["class_label"] = df["class_label"].replace({'g': 1, 'b': 0})

 

Давайте также визуализируем распределение меток классов:

import matplotlib.pyplot as plt# Подсчитаем количество точек данных в каждом классеclass_counts = df['class_label'].value_counts()# Создадим график-гистограмму для визуализации распределения классовplt.bar(class_counts.index, class_counts.values)plt.xlabel('Метка класса')plt.ylabel('Количество')plt.xticks(class_counts.index)plt.title('Распределение классов')plt.show()

 

Распределение классов 

Мы видим, что есть дисбаланс в распределении. В классе 1 больше записей, чем в классе 0. При построении модели логистической регрессии мы учтем этот дисбаланс классов.

 

Шаг 5 – Предварительная обработка набора данных

 Соберем признаки и метки классов следующим образом:

X = df.drop('class_label', axis=1)  # Признакиy = df['class_label']               # Целевая переменная

 

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

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

Модуль StandardScaler из библиотеки scikit-learn поможет нам справиться с этой задачей.

from sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import train_test_split# Разделим набор данных на тренировочный и тестовыйX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Получим индексы числовых признаковnumerical_feature_indices = list(range(34))  # Предполагается, что числовые признаки находятся в столбцах с 0 по 33# Инициализируем StandardScalerscaler = StandardScaler()# Нормализуем числовые признаки в тренировочном набореX_train.iloc[:, numerical_feature_indices] = scaler.fit_transform(X_train.iloc[:, numerical_feature_indices])# Нормализуем числовые признаки в тестовом наборе с использованием обученного для тренировочного набора набора scalerX_test.iloc[:, numerical_feature_indices] = scaler.transform(X_test.iloc[:, numerical_feature_indices])

 

Шаг 6 – Построение модели логистической регрессии

 Теперь мы можем создать экземпляр классификатора логистической регрессии. Класс LogisticRegression является частью модуля linear_model в библиотеке scikit-learn.

Обратите внимание, что мы установили параметр class_weight в значение ‘balanced’. Это позволит учесть дисбаланс классов, назначив вес каждому классу, обратно пропорциональный количеству записей в классах.

После создания экземпляра класса мы можем обучить модель на тренировочном наборе данных:

from sklearn.linear_model import LogisticRegressionmodel = LogisticRegression(class_weight='balanced')model.fit(X_train, y_train)

 

Шаг 7 – Оценка модели логистической регрессии

 Для получения прогнозов модели вы можете вызвать метод predict().

В дополнение к показателю точности, мы также можем получить отчет о классификации с показателями, такими как точность, полнота и F-мера.

 

from sklearn.metrics import accuracy_score, classification_reporty_pred = model.predict(X_test)accuracy = accuracy_score(y_test, y_pred)print(f"Точность: {accuracy:.2f}")classification_rep = classification_report(y_test, y_pred)print("Отчет о классификации:\n", classification_rep)

Поздравляем, вы создали свою первую модель логистической регрессии!

 

Заключение

 В этом руководстве мы подробно рассмотрели логистическую регрессию: от теории и математики до кодирования классификатора логистической регрессии.

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

 

Данный набор данных

Набор данных Ionosphere лицензирован в соответствии с лицензией Creative Commons Attribution 4.0 International (CC BY 4.0):

Sigillito,V., Wing,S., Hutton,L., and Baker,K.. (1989). Ionosphere. UCI Machine Learning Repository. https://doi.org/10.24432/C5W01B.

  

[Bala Priya C](https://twitter.com/balawc27) – разработчик и технический писатель из Индии. Она любит работать на стыке математики, программирования, анализа данных и создания контента. Ее областями интересов и экспертизы являются DevOps, анализ данных и обработка естественного языка. Она любит читать, писать, программировать и пить кофе! В данный момент она работает над обучением и обменом своими знаниями среди сообщества разработчиков, создавая учебники, инструкции, мнения и многое другое.