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

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

  1. Проблема и данные
  2. Настройка фреймворка
  3. Выбор показателей
  4. Почему точности недостаточно
  5. Точность и отзыв
  6. Оценка F1
  7. Показатель ROC AUC
  8. Модель
  9. Заключение

Проблема и данные

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

Мы начинаем с стандартного импорта некоторых полезных библиотек и соответствующих данных.

#We import the libraries and the data
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# import the data
data = pd.read_csv('AER_credit_card_data.csv')

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

data.head()

print(data.shape)
(1319, 12)

Мы видим, что у нас есть 12 столбцов в нашем наборе данных, один из которых будет нашей целевой переменной (той, которую мы пытаемся предсказать). Это будет столбец «карта», который означает одобрение или отклонение заявки на кредитную карту.

Мы также видим, что у нас есть много столбцов со значением да/нет. Мы можем сделать их логическими, заменив их на 1 или 0 соответственно.

data = data.replace(['yes','no'],[1,0])

Теперь сводка столбцов выглядит следующим образом:

data.info()

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

data.describe()

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

y = data['card']
X = data.drop(['card'], axis=1)

Настройка фреймворка

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

Мы видели, что данные состоят из 1319 выборок, поэтому разумным разделением будет 60%/20%/20% для обучающих, проверочных и тестовых наборов соответственно.

from sklearn.model_selection import train_test_split
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(X_temp, y_temp, test_size=0.25 , random_state=1)
print(X_train.shape, y_train.shape)
print(X_val.shape, y_val.shape)
print(X_test.shape, y_test.shape)

(791, 11) (791,)
(264, 11) (264,)
(264, 11) (264,)

Выбор показателей

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

Где I — индикаторная функция, которая принимает значение 1, только если аргумент истинен, в противном случае принимает значение 0. Проще говоря, точность — это среднее количество правильно классифицированных наблюдений.

Почему точности недостаточно

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

Представьте, например, что у нас есть модель, которая должна классифицировать наши наблюдения между двумя классами, назовем их бинарными, 1 и 0. Рассмотрим ситуацию, когда наши выборочные данные (и данные совокупности) распределены таким образом, что только 1% точек данных принадлежит классу 1. В таком случае очень фиктивный классификатор, который всегда предсказывает класс 0, будет иметь точность 99%! Однако это ничего не говорит нам о его способности обнаруживать данные класса 1, что ужасно. Фактически, он не может предсказать данные класса 1 по построению.

Из приведенного выше простого примера видно, что точности как метрики недостаточно, особенно когда у нас высокий дисбаланс классов. Нам нужны еще некоторые показатели, которые могут дать нам представление о производительности модели и помочь в обучении модели.

Введите точность и отзыв.

Точность и отзыв

Прежде чем мы дадим простое определение точности и отзыва, полезно ввести некоторую терминологию.

Истинные положительные результаты: это те, которые были предсказаны моделью как принадлежащие к положительному классу (в нашем случае классу 1) и действительно принадлежат к этому классу.

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

Ложные срабатывания: это те, которые были предсказаны моделью как принадлежащие к положительному классу (в нашем случае к классу 1), но на самом деле принадлежат к классу 0.

Ложноотрицательные результаты: это те, которые были предсказаны моделью как принадлежащие к отрицательному классу (в нашем случае к классу 0), но на самом деле принадлежат к классу 1.

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

Точность = TP / (TP + FP)

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

Отзыв = TP / (TP + FN)

Напомним, также известен как True Positive Rate (TPR).

Итак, если мы вернемся к нашему примеру с фиктивным классификатором, то при точности 99% (давайте рассмотрим выборку из 100 точек) полнота будет равна 0/(0+1) = 0, а точность будет равна 0/(0). + 0), что является неопределенным и некорректным, поскольку модель по построению не может предсказать положительное.

Оценка F1

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

Вы можете узнать больше об этом здесь.

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

from sklearn.metrics import classification_report

Показатель ROC AUC

Другой очень полезной метрикой является площадь под кривой (AUC) кривой ROC. Кривая ROC (рабочая характеристика приемника, название, полученное от радиолокационных систем) в основном представляет собой график истинной положительной скорости (TPR) против ложноположительной скорости (FPR) для различных значений порога.

TPR (отзыв) был определен ранее:

TPR = TP / (TP + FN)

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

FPR = FP/N = FP/(FP+TN)

Интуитивно мы хотим, чтобы наша модель максимизировала TPR и в то же время минимизировала FPR. В идеале мы хотим коснуться верхнего левого угла, где TPR равен 1, а FPR равен 0.

Как следует из названия, AUC — это область под ROC. Максимальное значение равно 1 и чем выше балл, очевидно, тем лучше. Мы также видим, что случайная модель для каждого порога предсказывает одинаково истинные и ложные метки. Другими словами, порог не влияет на него, потому что модель никогда не смотрит на него, а просто назначает классы случайным образом!

Теперь какие пороги? Это просто точки, в которых наша модель учитывает разделение классов. Например, порог 0,6 означает, что если прогнозируемая вероятность примера выше 0,6, то он будет классифицирован как положительный, а если ниже этого значения, он будет классифицирован как отрицательный класс. Мы видим, что очень низкий порог (например, 0) будет иметь очень высокий TPR, поскольку все положительные примеры будут отнесены к положительному классу, но в то же время все отрицательные примеры также будут отнесены к положительному классу, таким образом, высокий FPR .

Модель

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

Давайте построим модель, просто вызвав:

from sklearn.linear_model import LogisticRegression

logreg = LogisticRegression(solver='liblinear',C=1.0,max_iter=1000)

а затем мы просто подгоняем модель под тренировочные данные

logreg.fit(X_train, y_train)

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

y_val_pred = logreg.predict_proba(X_val)[:,1]

Чтобы увидеть, какова производительность, мы можем рассчитать показатель ROC AUC. Мы делаем это со следующей строкой

from sklearn.metrics import roc_auc_score
print("AUC score: ",round(roc_auc_score(y_val, y_val_pred),3))

Оценка AUC: 0,995

Очень хороший показатель!

Отчет о классификации дает:

from sklearn.metrics import classification_report
y_pred = logreg.predict(X_val)
print(classification_report(y_val, y_pred))

Что включает в себя точность модели, оценку f1 и точность, напомню.

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

В нашем случае макроусреднение:

макро_точность = (1+0,88)/2 = 0,94

macro_recall = (0,98+0,97)/2 = 0,97 (округлено)

Заключение

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

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

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

Следите за обновлениями!

Подключаемся: https://www.linkedin.com/in/marios-kokmotos