Как оценивается качество модели машинного обучения
Перейти к содержимому

Как оценивается качество модели машинного обучения

  • автор:

Урок 5. Оценка результатов машинного обучения

Урок 5. Оценка результатов машинного обучения

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

Цель урока: познакомиться с процессом оценки результатов машинного обучения и понять, как она осуществляется.

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

Содержание:

  • Разделение выборки на обучающую и тестовую
  • Метрики качества
  • Кросс-валидация и подбор гиперпараметров
  • Задание на взаимопроверку
  • Интерпретация результатов машинного обучения
  • Проверочный тест

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

Разделение выборки на обучающую и тестовую

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

Как правило, выборка разделяется на обучающую и тестовую в пропорции 70/30 или 80/20. Например, мы можем использовать 70% данных для обучения модели, а оставшиеся 30% оставить для тестирования.

Процесс разделения выборки на обучающую и тестовую состоит из нескольких шагов:

  1. Сначала необходимо перемешать данные, чтобы избежать возможной сортировки по какому-то признаку и сохранить случайность.
  2. Далее мы отделяем часть данных для тестирования и сохраняем ее в отдельную переменную. Например, мы можем использовать функцию train_test_split из библиотеки sklearn на языке Python (где X – это матрица признаков, y – это вектор целевых переменных, test_size – это доля данных, которую мы отделяем для тестирования, а random_state – это значение для генерации случайных чисел):

Функция

  1. Мы используем X_train и y_train для обучения модели и X_test и y_test для оценки ее качества. После того, как модель обучена на обучающей выборке, мы применяем ее к тестовой выборке и оцениваем ее качество, например, используя метрику точности или среднеквадратичную ошибку.
  2. После оценки качества модели мы можем вернуться к шагу 2 и изменить параметры разделения, если это необходимо, например, увеличивая или уменьшая долю тестовой выборки. Также мы можем изменять параметры модели и использовать методы кросс-валидации и подбора гиперпараметров для получения более точных результатов (об этом мы поговорим ниже).

Дополнительно есть несколько важных соображений, которые следует учитывать при разделении выборки на обучающую и тестовую:

Разделение выборки должно быть выполнено случайным образом, чтобы исключить возможность включения более представительных или необычных данных в одну из выборок. Это помогает обеспечить более точную оценку качества модели на новых данных.
Если у вас маленькая выборка, лучше использовать метод перекрестной проверки (cross-validation), который позволяет более эффективно использовать имеющиеся данные. В этом случае выборка разделяется на несколько частей (например, 5 или 10), и модель обучается на каждой части и тестируется на оставшейся части. Каждая часть выступает как тестовая выборка один раз. В результате мы получаем несколько оценок качества модели, которые могут быть усреднены для получения более точной оценки.
Некоторые данные могут содержать несбалансированные классы, т.е. один из классов может быть представлен значительно меньшим количеством данных, чем другой. В этом случае важно сохранить балансировку классов при разделении выборки на обучающую и тестовую. Для этого можно использовать параметр stratify при вызове функции train_test_split.
Необходимо помнить, что выборка может содержать выбросы, которые способны исказить оценку качества модели на тестовой выборке. Для этого можно использовать методы обнаружения выбросов (например, метод межквартильного размаха) и удалить выбросы из обучающей выборки.
Важно не использовать тестовую выборку для настройки параметров модели, т.к. это может привести к переобучению. Настройку параметров следует производить только на обучающей выборке, а тестовую выборку использовать только для оценки качества модели. Если нужно настроить параметры, можно использовать метод перекрестной проверки, о котором упоминалось выше.

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

Процесс использования выборки для проверки состоит из следующих шагов:

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

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

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

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

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

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

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

Метрики качества

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

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

Для задач классификации:

  • Accuracy (Точность) – доля правильных ответов модели среди всех предсказаний.
  • Precision (Точность) – доля истинно положительных ответов среди всех положительных ответов модели.
  • Recall (Полнота) – доля истинно положительных ответов среди всех правильных ответов.
  • F1-мера – гармоническое среднее между точностью и полнотой.

Для задач регрессии:

  • Mean Squared Error (MSE) – среднее значение квадрата разности между предсказанными и правильными значениями.
  • Root Mean Squared Error (RMSE) – квадратный корень из среднего значения квадратов разности между предсказанными и правильными значениями.
  • Mean Absolute Error (MAE) – среднее значение абсолютной разности между предсказанными и правильными значениями.
  • R2-коэффициент детерминации – мера, которая показывает, насколько хорошо модель подходит для данных. R2-коэффициент может принимать значения от 0 до 1, где 1 означает идеальное соответствие.

Для задач кластеризации:

  • Silhouette score (Коэффициент силуэта) – мера, которая показывает, насколько точно каждый объект соответствует своему кластеру и насколько он отличается от других кластеров. Значение коэффициента силуэта может варьироваться от -1 до 1, где 1 означает, что объекты внутри кластера находятся ближе друг к другу, чем к объектам других кластеров.

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

Выбор наиболее подходящей метрики зависит от конкретной задачи и целей машинного обучения. Например, если наша цель – максимизировать количество истинно положительных ответов, то метрика Precision будет более важна, чем Recall. Если же наша задача состоит в том, чтобы избежать ложно отрицательных ответов, то Recall будет более актуальной.

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

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

Кросс-валидация и подбор гиперпараметров

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

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

Существует несколько типов кросс-валидации, в частности:

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

Существует несколько методов подбора гиперпараметров, среди которых:

  • Grid Search – метод, который перебирает все возможные комбинации гиперпараметров и выбирает ту, которая дает наилучшие результаты.
  • Random Search – метод, который выбирает случайные значения гиперпараметров и оценивает производительность модели для каждой комбинации.
  • Bayesian Optimization – метод, который использует вероятностные модели для определения оптимальных значений гиперпараметров.

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

Некоторые методы, такие как Grid Search, могут быть очень затратными, особенно при большом количестве гиперпараметров и больших объемах данных. В таких случаях можно использовать более эффективные методы, например, Random Search или Bayesian Optimization.

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

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

Задание на взаимную проверку

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

Найдите открытый набор данных, который относится к интересующей вас области, например, к здравоохранению или финансовым рынкам. Разбейте выбранный набор данных на обучающую и тестовую выборки. Используйте простой метод разбиения на обучение и тестирование, например, случайное разбиение на 70% обучающей выборки и 30% тестовой выборки.

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

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

Интерпретация результатов машинного обучения

Интерпретация результатов машинного обучения – это процесс понимания того, как модель принимает решения и как работает в целом. Он очень важен для принятия решений на основе модели и обеспечения ее прозрачности и объяснимости.

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

Для интерпретации результатов машинного обучения можно использовать различные методы, включая методы, основанные на теории игр, такие как SHAP (SHapley Additive exPlanations), и методы, основанные на интерпретации локальных моделей, такие как LIME (Local Interpretable Model-agnostic Explanations).

Коротко о каждом из них:

1 Метод SHAP использует теорию игр, чтобы определить вклад каждого признака в принятие решений моделью. Он представляет каждый объект входных данных как комбинацию признаков и определяет, какой вклад каждый признак вносит в принятие решений моделью для данного объекта. Результаты SHAP показывают, какие признаки наиболее важны для принятия решений моделью на уровне отдельных объектов.
2 Метод LIME использует локальную модель для интерпретации результатов машинного обучения. Он представляет объекты входных данных в виде набора признаков и оценивает вклад каждого признака в принятие решений моделью для данного объекта. LIME использует локальную модель, чтобы приблизить поведение исходной модели в окрестности данного объекта и показать, какие признаки наиболее важны для принятия решений для данного объекта.

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

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

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

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

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

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

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

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

Проверьте свои знания

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

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

Оценка качества работы алгоритма машинного обучения

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

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

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

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

Ниже представлен псевдокод, демонстрирущий процесс кроссвалидации.

trait Model

def predict (obj: Object): Answer

def learn (sample: Map [Object, Answer]): Unit

trait Answer

def crossvalidation (model: Model, learningSample:

Map [Object, Answer]) =(

val n =10 // разделим на 10 частей

val parts =learningSample.grouped (learningSample.

val testAndLearningParts = parts.map (p =>p -> (learningSample — p) ) // получим пары

// 1/n — тестовый сэмпл // (n-1) /п — обучающий

val estimations = testAndLearningParts map < case (testingSample, learningSample) => model.learn (learningSample)

val answersOnTestSample: Map [Object, Answer] = testingSample.keys.map (obj =>obj -> model, predict (obj)).toMap estimate (model, testingSample)

val m =mean (estimations)

val std =Math.sqrt (mean (estimations.map

(estimation => (estimation — m) * (estimation — m) ) ) )

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

Истинно-положительное значение (TP — true-positive) — для бинарной классификации означает наличие положительного решения классификатора и что истинное значение ответа в оценочной выборке также положительное.

Ложно-ноложительное значение (FPfalse-positive) говорит соответственно о наличии положительного ответа классификатора и отрицательного в оценочной выборке.

Аналогичные случаи есть и для отрицательных примеров — истинно-отрицательное значение (TN — true-negative) и ложноотрицательное значение (FN — false-negative).

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

  • ТР — письмо было классифицировано как спам, и в оценочной выборке оно действительно является спамом;
  • FP — письмо было классифицировано как спам, однако в выборке это не так;
  • TN — письмо было классифицировано как не-спам, и это действительно так согласно выборке;
  • FN — письмо было принято как не-спам, однако согласно выборке это спам.

Так как оценка метрик производится по всей выборке, то значения TP, FP, TN, FN будут означать общее число соотвествующих случаев.

Точность

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

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

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

При этом коэффициент р позволяет отдать предпочтение полноте или точности. При значениях р

Оценка качества в задачах классификации и регрессии

В машинном обучении различают оценки качества для задачи классификации и регрессии. Причем оценка задачи классификации часто значительно сложнее, чем оценка регрессии.

Оценки качества классификации

Матрица ошибок (англ. Сonfusion matrix)

Перед переходом к самим метрикам необходимо ввести важную концепцию для описания этих метрик в терминах ошибок классификации — confusion matrix (матрица ошибок). Допустим, что у нас есть два класса [math]y = \< 0, 1 \>[/math] и алгоритм, предсказывающий принадлежность каждого объекта одному из классов. Рассмотрим пример. Пусть банк использует систему классификации заёмщиков на кредитоспособных и некредитоспособных. При этом первым кредит выдаётся, а вторые получат отказ. Таким образом, обнаружение некредитоспособного заёмщика ( [math]y = 1 [/math] ) можно рассматривать как «сигнал тревоги», сообщающий о возможных рисках.

Любой реальный классификатор совершает ошибки. В нашем случае таких ошибок может быть две:

  • Кредитоспособный заёмщик распознается моделью как некредитоспособный и ему отказывается в кредите. Данный случай можно трактовать как «ложную тревогу».
  • Некредитоспособный заёмщик распознаётся как кредитоспособный и ему ошибочно выдаётся кредит. Данный случай можно рассматривать как «пропуск цели».

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

Поскольку с точки зрения логики задачи нам важнее правильно распознать некредитоспособного заёмщика с меткой [math]y = 1 [/math] , чем ошибиться в распознавании кредитоспособного, будем называть соответствующий исход классификации положительным (заёмщик некредитоспособен), а противоположный — отрицательным (заемщик кредитоспособен [math]y = 0 [/math] ). Тогда возможны следующие исходы классификации:

  • Некредитоспособный заёмщик классифицирован как некредитоспособный, т.е. положительный класс распознан как положительный. Наблюдения, для которых это имеет место называются истинно-положительными (True PositiveTP).
  • Кредитоспособный заёмщик классифицирован как кредитоспособный, т.е. отрицательный класс распознан как отрицательный. Наблюдения, которых это имеет место, называются истинно отрицательными (True NegativeTN).
  • Кредитоспособный заёмщик классифицирован как некредитоспособный, т.е. имела место ошибка, в результате которой отрицательный класс был распознан как положительный. Наблюдения, для которых был получен такой исход классификации, называются ложно-положительными (False PositiveFP), а ошибка классификации называется ошибкой I рода.
  • Некредитоспособный заёмщик распознан как кредитоспособный, т.е. имела место ошибка, в результате которой положительный класс был распознан как отрицательный. Наблюдения, для которых был получен такой исход классификации, называются ложно-отрицательными (False NegativeFN), а ошибка классификации называется ошибкой II рода.

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

[math]y = 1[/math] [math]y = 0[/math]
[math]a ( x ) = 1[/math] Истинно-положительный (True Positive — TP) Ложно-положительный (False Positive — FP)
[math]a ( x ) = 0[/math] Ложно-отрицательный (False Negative — FN) Истинно-отрицательный (True Negative — TN)

Здесь [math]a ( x )[/math] — это ответ алгоритма на объекте, а [math]y [/math] — истинная метка класса на этом объекте. Таким образом, ошибки классификации бывают двух видов: False Negative (FN) и False Positive (FP). P означает что классификатор определяет класс объекта как положительный (N — отрицательный). T значит что класс предсказан правильно (соответственно F — неправильно). Каждая строка в матрице ошибок представляет спрогнозированный класс, а каждый столбец — фактический класс.

# код для матрицы ошибок # Пример классификатора, способного проводить различие между всего лишь двумя # классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.metrics import confusion_matrix from sklearn.linear_model import SGDClassifier mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (англ. Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распозновать пятерки на целом обучающем наборе # Для расчета матрицы ошибок сначала понадобится иметь набор прогнозов, чтобы их можно было сравнивать с фактическими целями y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) print(confusion_matrix(y_train_5, y_train_pred)) # array([[53892, 687], # [ 1891, 3530]]) 

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

import numpy as np from sklearn.datasets import fetch_openml from sklearn.metrics import confusion_matrix mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) y_train_perfect_predictions = y_train_5 # притворись, что мы достигли совершенства print(confusion_matrix(y_train_5, y_train_perfect_predictions)) # array([[54579, 0], # [ 0, 5421]]) 

Аккуратность (англ. Accuracy)

Интуитивно понятной, очевидной и почти неиспользуемой метрикой является accuracy — доля правильных ответов алгоритма:

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

Допустим, мы хотим оценить работу спам-фильтра почты. У нас есть 100 не-спам писем, 90 из которых наш классификатор определил верно (True Negative = 90, False Positive = 10), и 10 спам-писем, 5 из которых классификатор также определил верно (True Positive = 5, False Negative = 5). Тогда accuracy:

[math] accuracy = \dfrac = 86,4 [/math]

Однако если мы просто будем предсказывать все письма как не-спам, то получим более высокую аккуратность:

[math] accuracy = \dfrac = 90,9 [/math]

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

# код для для подсчета аккуратности: # Пример классификатора, способного проводить различие между всего лишь двумя # классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.metrics import accuracy_score from sklearn.linear_model import SGDClassifier mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распозновать пятерки на целом обучающем наборе y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) # print(confusion_matrix(y_train_5, y_train_pred)) # array([[53892, 687] # [ 1891, 3530]]) print(accuracy_score(y_train_5, y_train_pred)) # == (53892 + 3530) / (53892 + 3530 + 1891 +687) # 0.9570333333333333 

Точность (англ. Precision)

Точностью (precision) называется доля правильных ответов модели в пределах класса — это доля объектов действительно принадлежащих данному классу относительно всех объектов которые система отнесла к этому классу.

[math] Precision = \dfrac [/math]

Именно введение precision не позволяет нам записывать все объекты в один класс, так как в этом случае мы получаем рост уровня False Positive.

Полнота (англ. Recall)

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

[math] Recall = \dfrac [/math]

Полнота (recall) демонстрирует способность алгоритма обнаруживать данный класс вообще.

Имея матрицу ошибок, очень просто можно вычислить точность и полноту для каждого класса. Точность (precision) равняется отношению соответствующего диагонального элемента матрицы и суммы всей строки класса. Полнота (recall) — отношению диагонального элемента матрицы и суммы всего столбца класса. Формально:

Результирующая точность классификатора рассчитывается как арифметическое среднее его точности по всем классам. То же самое с полнотой. Технически этот подход называется macro-averaging.

# код для для подсчета точности и полноты: # Пример классификатора, способного проводить различие между всего лишь двумя # классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.metrics import precision_score, recall_score from sklearn.linear_model import SGDClassifier mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распозновать пятерки на целом обучающем наборе y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) # print(confusion_matrix(y_train_5, y_train_pred)) # array([[53892, 687] # [ 1891, 3530]]) print(precision_score(y_train_5, y_train_pred)) # == 3530 / (3530 + 687) print(recall_score(y_train_5, y_train_pred)) # == 3530 / (3530 + 1891) # 0.8370879772350012 # 0.6511713705958311 

F-мера (англ. F-score)

Precision и recall не зависят, в отличие от accuracy, от соотношения классов и потому применимы в условиях несбалансированных выборок. Часто в реальной практике стоит задача найти оптимальный (для заказчика) баланс между этими двумя метриками. Понятно что чем выше точность и полнота, тем лучше. Но в реальной жизни максимальная точность и полнота не достижимы одновременно и приходится искать некий баланс. Поэтому, хотелось бы иметь некую метрику которая объединяла бы в себе информацию о точности и полноте нашего алгоритма. В этом случае нам будет проще принимать решение о том какую реализацию запускать в производство (у кого больше тот и круче). Именно такой метрикой является F-мера.

F-мера представляет собой гармоническое среднее между точностью и полнотой. Она стремится к нулю, если точность или полнота стремится к нулю.

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

где [math]β[/math] принимает значения в диапазоне [math]0\lt β\lt 1[/math] если вы хотите отдать приоритет точности, а при [math]β\gt 1[/math] приоритет отдается полноте. При [math]β=1[/math] формула сводится к предыдущей и вы получаете сбалансированную F-меру (также ее называют [math]F_1[/math] ).

Рис.1 Сбалансированная F-мера, [math]β=1[/math]

Рис.2 F-мера c приоритетом точности, [math]β^2=\dfrac< 1 >< 4 >[/math]

Рис.3 F-мера c приоритетом полноты, [math]β^2=2[/math]

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

F-мера является хорошим кандидатом на формальную метрику оценки качества классификатора. Она сводит к одному числу две других основополагающих метрики: точность и полноту. Имея «F-меру» гораздо проще ответить на вопрос: «поменялся алгоритм в лучшую сторону или нет?»

# код для подсчета метрики F-mera: # Пример классификатора, способного проводить различие между всего лишь двумя # классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.linear_model import SGDClassifier from sklearn.metrics import f1_score mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распознавать пятерки на целом обучающем наборе y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) print(f1_score(y_train_5, y_train_pred)) # 0.7325171197343846 

ROC-кривая

Кривая рабочих характеристик (англ. Receiver Operating Characteristics curve). Используется для анализа поведения классификаторов при различных пороговых значениях. Позволяет рассмотреть все пороговые значения для данного классификатора. Показывает долю ложно положительных примеров (англ. false positive rate, FPR) в сравнении с долей истинно положительных примеров (англ. true positive rate, TPR).

ROC 2.png

[math] TPR = \dfrac = Recall[/math] [math] FPR = \dfrac [/math]

Доля FPR — это пропорция отрицательных образцов, которые были некорректно классифицированы как положительные.

[math] FPR = 1 — TNR[/math] ,

где TNR — доля истинно отрицательных классификаций (англ. Тrие Negative Rate), пред­ставляющая собой пропорцию отрицательных образцов, которые были кор­ректно классифицированы как отрицательные.

Доля TNR также называется специфичностью (англ. specificity). Следовательно, ROC-кривая изображает чувствительность (англ. seпsitivity), т.е. полноту, в срав­нении с разностью 1 — specificity.

Прямая линия по диагонали представляет ROC-кривую чисто случайного классификатора. Хороший классификатор держится от указанной линии настолько далеко, насколько это возможно (стремясь к левому верхнему углу).

Один из способов сравнения классификаторов предусматривает измере­ние площади под кривой (англ. Area Under the Curve — AUC). Безупречный клас­сификатор будет иметь площадь под ROC-кривой (ROC-AUC), равную 1, тогда как чисто случайный классификатор — площадь 0.5.

# Код отрисовки ROC-кривой # На примере классификатора, способного проводить различие между всего лишь двумя классами # "пятерка" и "не пятерка" из набора рукописных цифр MNIST from sklearn.metrics import roc_curve import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.linear_model import SGDClassifier mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распозновать пятерки на целом обучающем наборе y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method="decision_function") fpr, tpr, thresholds = roc_curve(y_train_5, y_scores) def plot_roc_curve(fpr, tpr, label=None): plt.plot(fpr, tpr, linewidth=2, label=label) plt.plot([0, 1], [0, 1], 'k--') # dashed diagonal plt.xlabel('False Positive Rate, FPR (1 - specificity)') plt.ylabel('True Positive Rate, TPR (Recall)') plt.title('ROC curve') plt.savefig("ROC.png") plot_roc_curve(fpr, tpr) plt.show()

Precison-recall кривая

Чувствительность к соотношению классов. Рассмотрим задачу выделения математических статей из множества научных статей. Допустим, что всего имеется 1.000.100 статей, из которых лишь 100 относятся к математике. Если нам удастся построить алгоритм [math]a(x)[/math] , идеально решающий задачу, то его TPR будет равен единице, а FPR — нулю. Рассмотрим теперь плохой алгоритм, дающий положительный ответ на 95 математических и 50.000 нематематических статьях. Такой алгоритм совершенно бесполезен, но при этом имеет TPR = 0.95 и FPR = 0.05, что крайне близко к показателям идеального алгоритма. Таким образом, если положительный класс существенно меньше по размеру, то AUC-ROC может давать неадекватную оценку качества работы алгоритма, поскольку измеряет долю неверно принятых объектов относительно общего числа отрицательных. Так, алгоритм [math]b(x)[/math] , помещающий 100 релевантных документов на позиции с 50.001-й по 50.101-ю, будет иметь AUC-ROC 0.95.

Precison-recall (PR) кривая. Избавиться от указанной проблемы с несбалансированными классами можно, перейдя от ROC-кривой к PR-кривой. Она определяется аналогично ROC-кривой, только по осям откладываются не FPR и TPR, а полнота (по оси абсцисс) и точность (по оси ординат). Критерием качества семейства алгоритмов выступает площадь под PR-кривой (англ. Area Under the Curve — AUC-PR)

PR curve.png

# Код отрисовки Precison-recall кривой # На примере классификатора, способного проводить различие между всего лишь двумя классами # "пятерка" и "не пятерка" из набора рукописных цифр MNIST from sklearn.metrics import precision_recall_curve import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import cross_val_predict from sklearn.linear_model import SGDClassifier mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"] y = y.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] y_train_5 = (y_train == 5) # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD) sgd_clf.fit(X_train, y_train_5) # обучаем классификатор распозновать пятерки на целом обучающем наборе y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method="decision_function") precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores) def plot_precision_recall_vs_threshold(precisions, recalls, thresholds): plt.plot(recalls, precisions, linewidth=2) plt.xlabel('Recall') plt.ylabel('Precision') plt.title('Precision-Recall curve') plt.savefig("Precision_Recall_curve.png") plot_precision_recall_vs_threshold(precisions, recalls, thresholds) plt.show()

Оценки качества регрессии

Наиболее типичными мерами качества в задачах регрессии являются

Средняя квадратичная ошибка (англ. Mean Squared Error, MSE)

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

[math] MSE = \dfrac\sum \limits_^(a(x_i) — y_i)^2 [/math] и

Cредняя абсолютная ошибка (англ. Mean Absolute Error, MAE)

[math] MAE = \dfrac<1>\sum \limits_^|a(x_i) — y_i| [/math]

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

Среднеквадратичная ошибка подходит для сравнения двух моделей или для контроля качества во время обучения, но не позволяет сделать выводов о том, на сколько хорошо данная модель решает задачу. Например, MSE = 10 является очень плохим показателем, если целевая переменная принимает значения от 0 до 1, и очень хорошим, если целевая переменная лежит в интервале (10000, 100000). В таких ситуациях вместо среднеквадратичной ошибки полезно использовать коэффициент детерминации — [math]R^2[/math]

Коэффициент детерминации

[math] R^2 = 1 — \dfrac^(a(x_i) — y_i)^2>^(y_i — \overline)^2> [/math]

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

Средняя абсолютная процентная ошибка (англ. Mean Absolute Percentage Error, MAPE)

[math] MAPE = 100\% \times \dfrac<1>\sum \limits_^ \dfrac<|y_i - a(x_i)|> <|y_i|>[/math]

Это коэффициент, не имеющий размерности, с очень простой интерпретацией. Его можно измерять в долях или процентах. Если у вас получилось, например, что MAPE=11.4%, то это говорит о том, что ошибка составила 11,4% от фактических значений. Основная проблема данной ошибки — нестабильность.

Корень из средней квадратичной ошибки (англ. Root Mean Squared Error, RMSE)

[math] RMSE = \sqrt\sum \limits_^(a(x_i) — y_i)^2> [/math]Примерно такая же проблема, как и в MAPE: так как каждое отклонение возводится в квадрат, любое небольшое отклонение может значительно повлиять на показатель ошибки. Стоит отметить, что существует также ошибка MSE, из которой RMSE как раз и получается путем извлечения корня.

Cимметричная MAPE (англ. Symmetric MAPE, SMAPE)

[math] SMAPE = \dfrac<1>\sum \limits_^ \dfrac <|y_i| + |a(x_i)|>[/math]

Средняя абсолютная масштабированная ошибка (англ. Mean absolute scaled error, MASE)

[math] MASE = \dfrac^n |Y_i — e_i|>\sum \limits_^n | Y_i-Y_|> [/math]

MASE является очень хорошим вариантом для расчета точности, так как сама ошибка не зависит от масштабов данных и является симметричной: то есть положительные и отрицательные отклонения от факта рассматриваются в равной степени. Обратите внимание, что в MASE мы имеем дело с двумя суммами: та, что в числителе, соответствует тестовой выборке, та, что в знаменателе — обучающей. Вторая фактически представляет собой среднюю абсолютную ошибку прогноза. Она же соответствует среднему абсолютному отклонению ряда в первых разностях. Эта величина, по сути, показывает, насколько обучающая выборка предсказуема. Она может быть равна нулю только в том случае, когда все значения в обучающей выборке равны друг другу, что соответствует отсутствию каких-либо изменений в ряде данных, ситуации на практике почти невозможной. Кроме того, если ряд имеет тенденцию к росту либо снижению, его первые разности будут колебаться около некоторого фиксированного уровня. В результате этого по разным рядам с разной структурой, знаменатели будут более-менее сопоставимыми. Всё это, конечно же, является очевидными плюсами MASE, так как позволяет складывать разные значения по разным рядам и получать несмещённые оценки.

Недостаток MASE в том, что её тяжело интерпретировать. Например, MASE=1.21 ни о чём, по сути, не говорит. Это просто означает, что ошибка прогноза оказалась в 1.21 раза выше среднего абсолютного отклонения ряда в первых разностях, и ничего более.

Кросс-валидация

Хороший способ оценки модели предусматривает применение кросс-валидации (cкользящего контроля или перекрестной проверки).

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

Примечания

  1. [1] Лекция «Оценивание качества» на www.coursera.org
  2. [2] Лекция на www.stepik.org о кросвалидации
  3. [3] Лекция на www.stepik.org о метриках качества, Precison и Recall
  4. [4] Лекция на www.stepik.org о метриках качества, F-мера
  5. [5] Лекция на www.stepik.org о метриках качества, примеры

См. также

  • Оценка качества в задаче кластеризации
  • Кросс-валидация

Источники информации

  1. [6] Соколов Е.А. Лекция линейная регрессия
  2. [7] — Дьяконов А. Функции ошибки / функционалы качества
  3. [8] — Оценка качества прогнозных моделей
  4. [9] — HeinzBr Ошибка прогнозирования: виды, формулы, примеры
  5. [10] — egor_labintcev Метрики в задачах машинного обучения
  6. [11] — grossu Методы оценки качества прогноза
  7. [12] — К.В.Воронцов, Классификация
  8. [13] — К.В.Воронцов, Скользящий контроль

Метрики в задачах машинного обучения

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

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

Метрики в задачах классификации

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

Загрузим необходимые библиотеки и посмотрим на данные

import pandas as pd import matplotlib.pyplot as plt from matplotlib.pylab import rc, plot import seaborn as sns from sklearn.preprocessing import LabelEncoder, OneHotEncoder from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier from sklearn.metrics import precision_recall_curve, classification_report from sklearn.model_selection import train_test_split df = pd.read_csv('../../data/telecom_churn.csv') 
df.head(5)

Предобработка данных

# Сделаем маппинг бинарных колонок # и закодируем dummy-кодированием штат (для простоты, лучше не делать так для деревянных моделей) d = df['International plan'] = df['International plan'].map(d) df['Voice mail plan'] = df['Voice mail plan'].map(d) df['Churn'] = df['Churn'].astype('int64') le = LabelEncoder() df['State'] = le.fit_transform(df['State']) ohe = OneHotEncoder(sparse=False) encoded_state = ohe.fit_transform(df['State'].values.reshape(-1, 1)) tmp = pd.DataFrame(encoded_state, columns=['state ' + str(i) for i in range(encoded_state.shape[1])]) df = pd.concat([df, tmp], axis=1)

Accuracy, precision и recall

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

True Positive (TP) False Positive (FP)
False Negative (FN) True Negative (TN)

Здесь — это ответ алгоритма на объекте, а — истинная метка класса на этом объекте.
Таким образом, ошибки классификации бывают двух видов: False Negative (FN) и False Positive (FP).

Обучение алгоритма и построение матрицы ошибок

X = df.drop('Churn', axis=1) y = df['Churn'] # Делим выборку на train и test, все метрики будем оценивать на тестовом датасете X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.33, random_state=42) # Обучаем ставшую родной логистическую регрессию lr = LogisticRegression(random_state=42) lr.fit(X_train, y_train) # Воспользуемся функцией построения матрицы ошибок из документации sklearn def plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues): """ This function prints and plots the confusion matrix. Normalization can be applied by setting `normalize=True`. """ plt.imshow(cm, interpolation='nearest', cmap=cmap) plt.title(title) plt.colorbar() tick_marks = np.arange(len(classes)) plt.xticks(tick_marks, classes, rotation=45) plt.yticks(tick_marks, classes) if normalize: cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis] print("Normalized confusion matrix") else: print('Confusion matrix, without normalization') print(cm) thresh = cm.max() / 2. for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])): plt.text(j, i, cm[i, j], horizontalalignment="center", color="white" if cm[i, j] > thresh else "black") plt.tight_layout() plt.ylabel('True label') plt.xlabel('Predicted label') font = plt.rc('font', **font) cnf_matrix = confusion_matrix(y_test, lr.predict(X_test)) plt.figure(figsize=(10, 8)) plot_confusion_matrix(cnf_matrix, classes=['Non-churned', 'Churned'], title='Confusion matrix') plt.savefig("conf_matrix.png") plt.show() 

Accuracy

Интуитивно понятной, очевидной и почти неиспользуемой метрикой является accuracy — доля правильных ответов алгоритма:

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

Допустим, мы хотим оценить работу спам-фильтра почты. У нас есть 100 не-спам писем, 90 из которых наш классификатор определил верно (True Negative = 90, False Positive = 10), и 10 спам-писем, 5 из которых классификатор также определил верно (True Positive = 5, False Negative = 5).
Тогда accuracy:

Однако если мы просто будем предсказывать все письма как не-спам, то получим более высокую accuracy:

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

Precision, recall и F-мера

Для оценки качества работы алгоритма на каждом из классов по отдельности введем метрики precision (точность) и recall (полнота).

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

Именно введение precision не позволяет нам записывать все объекты в один класс, так как в этом случае мы получаем рост уровня False Positive. Recall демонстрирует способность алгоритма обнаруживать данный класс вообще, а precision — способность отличать этот класс от других классов.

Как мы отмечали ранее, ошибки классификации бывают двух видов: False Positive и False Negative. В статистике первый вид ошибок называют ошибкой I-го рода, а второй — ошибкой II-го рода. В нашей задаче по определению оттока абонентов, ошибкой первого рода будет принятие лояльного абонента за уходящего, так как наша нулевая гипотеза состоит в том, что никто из абонентов не уходит, а мы эту гипотезу отвергаем. Соответственно, ошибкой второго рода будет являться «пропуск» уходящего абонента и ошибочное принятие нулевой гипотезы.

Precision и recall не зависят, в отличие от accuracy, от соотношения классов и потому применимы в условиях несбалансированных выборок.
Часто в реальной практике стоит задача найти оптимальный (для заказчика) баланс между этими двумя метриками. Классическим примером является задача определения оттока клиентов.
Очевидно, что мы не можем находить всех уходящих в отток клиентов и только их. Но, определив стратегию и ресурс для удержания клиентов, мы можем подобрать нужные пороги по precision и recall. Например, можно сосредоточиться на удержании только высокодоходных клиентов или тех, кто уйдет с большей вероятностью, так как мы ограничены в ресурсах колл-центра.

Обычно при оптимизации гиперпараметров алгоритма (например, в случае перебора по сетке GridSearchCV ) используется одна метрика, улучшение которой мы и ожидаем увидеть на тестовой выборке.
Существует несколько различных способов объединить precision и recall в агрегированный критерий качества. F-мера (в общем случае ) — среднее гармоническое precision и recall :

в данном случае определяет вес точности в метрике, и при это среднее гармоническое (с множителем 2, чтобы в случае precision = 1 и recall = 1 иметь )
F-мера достигает максимума при полноте и точности, равными единице, и близка к нулю, если один из аргументов близок к нулю.
В sklearn есть удобная функция _metrics.classificationreport, возвращающая recall, precision и F-меру для каждого из классов, а также количество экземпляров каждого класса.

report = classification_report(y_test, lr.predict(X_test), target_names=['Non-churned', 'Churned']) print(report) 

class precision recall f1-score support
Non-churned 0.88 0.97 0.93 941
Churned 0.60 0.25 0.35 159
avg / total 0.84 0.87 0.84 1100

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

AUC-ROC и AUC-PR

При конвертации вещественного ответа алгоритма (как правило, вероятности принадлежности к классу, отдельно см. SVM) в бинарную метку, мы должны выбрать какой-либо порог, при котором 0 становится 1. Естественным и близким кажется порог, равный 0.5, но он не всегда оказывается оптимальным, например, при вышеупомянутом отсутствии баланса классов.

Одним из способов оценить модель в целом, не привязываясь к конкретному порогу, является AUC-ROC (или ROC AUC) — площадь (Area Under Curve) под кривой ошибок (Receiver Operating Characteristic curve ). Данная кривая представляет из себя линию от (0,0) до (1,1) в координатах True Positive Rate (TPR) и False Positive Rate (FPR):

TPR нам уже известна, это полнота, а FPR показывает, какую долю из объектов negative класса алгоритм предсказал неверно. В идеальном случае, когда классификатор не делает ошибок (FPR = 0, TPR = 1) мы получим площадь под кривой, равную единице; в противном случае, когда классификатор случайно выдает вероятности классов, AUC-ROC будет стремиться к 0.5, так как классификатор будет выдавать одинаковое количество TP и FP.
Каждая точка на графике соответствует выбору некоторого порога. Площадь под кривой в данном случае показывает качество алгоритма (больше — лучше), кроме этого, важной является крутизна самой кривой — мы хотим максимизировать TPR, минимизируя FPR, а значит, наша кривая в идеале должна стремиться к точке (0,1).

Код отрисовки ROC-кривой

sns.set(font_scale=1.5) sns.set_color_codes("muted") plt.figure(figsize=(10, 8)) fpr, tpr, thresholds = roc_curve(y_test, lr.predict_proba(X_test)[:,1], pos_label=1) lw = 2 plt.plot(fpr, tpr, lw=lw, label='ROC curve ') plt.plot([0, 1], [0, 1]) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC curve') plt.savefig("ROC.png") plt.show() 

Критерий AUC-ROC устойчив к несбалансированным классам (спойлер: увы, не всё так однозначно) и может быть интерпретирован как вероятность того, что случайно выбранный positive объект будет проранжирован классификатором выше (будет иметь более высокую вероятность быть positive), чем случайно выбранный negative объект.

Рассмотрим следующую задачу: нам необходимо выбрать 100 релевантных документов из 1 миллиона документов. Мы намашинлернили два алгоритма:

  • Алгоритм 1 возвращает 100 документов, 90 из которых релевантны. Таким образом,
  • Алгоритм 2 возвращает 2000 документов, 90 из которых релевантны. Таким образом,

Скорее всего, мы бы выбрали первый алгоритм, который выдает очень мало False Positive на фоне своего конкурента. Но разница в False Positive Rate между этими двумя алгоритмами крайне мала — всего 0.0019. Это является следствием того, что AUC-ROC измеряет долю False Positive относительно True Negative и в задачах, где нам не так важен второй (больший) класс, может давать не совсем адекватную картину при сравнении алгоритмов.

Для того чтобы поправить положение, вернемся к полноте и точности :

Здесь уже заметна существенная разница между двумя алгоритмами — 0.855 в точности!

Precision и recall также используют для построения кривой и, аналогично AUC-ROC, находят площадь под ней.

Здесь можно отметить, что на маленьких датасетах площадь под PR-кривой может быть чересчур оптимистична, потому как вычисляется по методу трапеций, но обычно в таких задачах данных достаточно. За подробностями о взаимоотношениях AUC-ROC и AUC-PR можно обратиться сюда.

Logistic Loss

Особняком стоит логистическая функция потерь, определяемая как:

здесь — это ответ алгоритма на -ом объекте, — истинная метка класса на -ом объекте, а размер выборки.

Подробно про математическую интерпретацию логистической функции потерь уже написано в рамках поста про линейные модели.
Данная метрика нечасто выступает в бизнес-требованиях, но часто — в задачах на kaggle.
Интуитивно можно представить минимизацию logloss как задачу максимизации accuracy путем штрафа за неверные предсказания. Однако необходимо отметить, что logloss крайне сильно штрафует за уверенность классификатора в неверном ответе.

def logloss_crutch(y_true, y_pred, eps=1e-15): return - (y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) print('Logloss при неуверенной классификации %f' % logloss_crutch(1, 0.5)) >> Logloss при неуверенной классификации 0.693147 print('Logloss при уверенной классификации и верном ответе %f' % logloss_crutch(1, 0.9)) >> Logloss при уверенной классификации и верном ответе 0.105361 print('Logloss при уверенной классификации и НЕверном ответе %f' % logloss_crutch(1, 0.1)) >> Logloss при уверенной классификации и НЕверном ответе 2.302585

Отметим, как драматически выросла logloss при неверном ответе и уверенной классификации!
Следовательно, ошибка на одном объекте может дать существенное ухудшение общей ошибки на выборке. Такие объекты часто бывают выбросами, которые нужно не забывать фильтровать или рассматривать отдельно.
Всё становится на свои места, если нарисовать график logloss:

Видно, что чем ближе к нулю ответ алгоритма при ground truth = 1, тем выше значение ошибки и круче растёт кривая.

Подытожим:

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

Полезные ссылки

  1. Курс Евгения Соколова: Семинар по выбору моделей (там есть информация по метрикам задач регрессии)
  2. Задачки на AUC-ROC от А.Г. Дьяконова
  3. Дополнительно о других метриках можно почитать на kaggle. К описанию каждой метрики добавлена ссылка на соревнования, где она использовалась
  4. Презентация Богдана Мельника aka ld86 про обучение на несбалансированных выборках

Благодарности

Спасибо mephistopheies и madrugado за помощь в подготовке статьи.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *