На этом шаге мы рассмотрим особенности анализа таких наборов данных.
Типы ошибок играют важную роль, когда один из двух классов встречается гораздо чаще, чем другой. Это очень распространенная ситуация на практике. Хорошим примером является прогноз рейтинга кликов, где каждая точка данных представляет собой "показ" - элемент, предъявленный пользователю. Этим элементом может быть объявление, рассказ, пользователь социальной сети. Цель состоит в том, чтобы предсказать, будет ли пользователь при показе данного элемента кликать по нему (что указывает на его интерес). Большинство из того, что видит пользователь в Интернете (в частности, рекламные объявления), не вызывает у него особого интереса. Вам потребуется показать пользователю 100 объявлений или статей, прежде чем он найдет что-то достаточно интересное для себя, чтобы кликнуть. Это позволяет получить набор данных, в котором 99 точек данных соответствуют ситуации "не кликнул" и 1 точка данных - "кликнул". Другими словами, 99% примеров относятся к классу "отсутствие клика". Наборы данных, в которых один класс встречается гораздо чаще, чем остальные, часто называют несбалансированными наборами данных (imbalanced datasets) или наборами данных с несбалансированными классами (datasets with imbalanced classes). В реальности несбалансированные данные являются нормой и редко бывает, что интересующий класс встречался в данных с одинаковой или почти такой же частотой, что и остальные классы.
Теперь предположим, что вы строите классификатор, который при решении задачи прогнозирования кликов имеет правильность 99%. О чем это говорит? Правильность 99% звучит впечатляюще, но она не принимает во внимание дисбаланс классов. Вы можете достичь 99%-ной правильности и без построения модели машинного обучения, всегда прогнозируя "отсутствие клика" С другой стороны, даже для несбалансированных данных модель с 99%-ной правильностью могла бы быть вполне пригодной. Однако в данном случае правильность не позволяет нам отличить модель "постоянно прогнозируем отсутствие клика" от потенциально хорошей модели.
Чтобы проиллюстрировать это, мы на основе набора данных digits создадим несбалансированный набор данных с пропорциями 9:1, создав два класса "не-девятка" и "девятка":
[In 39]: from sklearn.datasets import load_digits digits = load_digits() y = digits.target == 9 X_train, X_test, y_train, y_test = train_test_split( digits.data, y, random_state=0)
Мы можем воспользоваться DummyClassifier, который всегда предсказывает мажоритарный класс (в данном случае класс "недевятка"), чтобы проиллюстрировать, насколько малоинформативной может быть правильность:
[In 40]: from sklearn.dummy import DummyClassifier dummy_majority = DummyClassifier(strategy='most_frequent').fit(X_train, y_train) pred_most_frequent = dummy_majority.predict(X_test) print("Уникальные спрогнозированные метки: {}".format(np.unique(pred_most_frequent))) print("Правильность на тестовом наборе: {:.2f}".format(dummy_majority.score(X_test, y_test))) Уникальные спрогнозированные метки: [False] Правильность на тестовом наборе: 0.90
Мы получили 90%-ную правильностью без какого-либо обучения Это может показаться поразительным, но задумайтесь об этом на минуту. Представьте себе, кто-то говорит вам, что его модель имеет 90%-ную правильность. Можно сделать вывод, что он проделал очень хорошую работу. Но это вполне возможно, лишь правильно прогнозируя один класс! Давайте сравним этот результат с результатом, полученным с помощью реальной модели:
[In 41]: from sklearn.tree import DecisionTreeClassifier tree = DecisionTreeClassifier(max_depth=2).fit(X_train, y_train) pred_tree = tree.predict(X_test) print("Правильность на тестовом наборе: {:.2f}".format(tree.score(X_test, y_test))) Правильность на тестовом наборе: 0.92
С точки зрения правильности DecisionTreeClassifier оказался чуть лучше, чем DummyClassifier, постоянно предсказывающего мажоритарный класс. Это может означать, что либо мы неправильно использовали DecisionTreeClassifier, либо правильность на самом деле не является в данном случае адекватной метрикой.
Для сравнения давайте оценим качество еще двух классификаторов, LogisticRegression и обычный DummyClassifier, который выдает случайные прогнозы:
[In 42]: from sklearn.linear_model import LogisticRegression dummy = DummyClassifier().fit(X_train, y_train) pred_dummy = dummy.predict(X_test) print("правильность dummy: {:.2f}".format(dummy.score(X_test, y_test))) logreg = LogisticRegression(C=0.1).fit(X_train, y_train) pred_logreg = logreg.predict(X_test) print("правильность logreg: {:.2f}".format(logreg.score(X_test, y_test))) правильность dummy: 0.90 правильность logreg: 0.98
Дамми-классификатор, который генерирует случайные прогнозы, имеет намного худшее качество (с точки зрения правильности), в то время как логистическая регрессия дает очень хорошие результаты. Однако даже случайный классификатор дает 90%-ную правильность. Поэтому очень трудно судить, какой из этих результатов является действительно полезным. Проблема здесь заключается в том, что для несбалансированных наборов данных правильность не является адекватной метрикой, позволяющей количественно оценить прогностическую способность модели. В следующих шагах мы рассмотрим альтернативные метрики, которые дают более четкие ориентиры при выборе модели. В частности, нам нужны такие метрики, которые позволяют сравнить правильность модели машинного обучения с правильностью классификатора, всегда предсказывающего "наиболее часто встречающийся класс", или случайного классификатора (в данном случае такие классификаторы были вычислены с помощью pred_most_frequent и pred_dummy). Если мы используем какую-то метрику для оценки модели, она должна уметь отсекать эти бессмысленные прогнозы.
На следующем шаге мы рассмотрим матрицу ошибок.