[ЗАСТАВКА] На этом уроке мы научимся оценивать качество моделей классификации и регрессии с помощью метрик из модуля sklearn.metrics. Этот модуль предоставляет нам готовую реализацию большинства метрик, использующихся в задачах классификации и регрессии. По приведенной ссылке вы можете ознакомиться с полным набором доступных метрик. Я же продемонстрирую наиболее интересные из них. Для начала мы импортируем все необходимые модули. А теперь давайте сгенерируем данные. Так как мы будем решать сразу две задачи — классификация и регрессия, нам потребуются два набора данных. Для этого воспользуемся знакомыми нам функциями: make_classification и make_regression. Так, данные готовы. В обоих случаях мы сгенерировали датасеты, состоящие из двух признаков. Нам все еще хочется их визуализировать, поэтому нам это удобно. Однако когда мы решаем задачу классификации, мы будем строить датасет, в котором оба признака являются информативными, а для задачи регрессии мы будем использовать датасет, в котором информативным является только один признак. Итак, давайте отрисуем наши наборы данных. Начнем с данных для классификации. Вот мы видим: красным и синим цветом обозначены объекты двух разных классов. Довольно интересно они расположены. И теперь давайте отрисуем данные для задачи регрессии. В данном случае напоминаю, что мы строим объекты в координатах признак– целевая функция, то есть красным цветом у нас обозначены объекты, построенные в координатах — давайте посмотрим — первый признак–target, синим цветом объекты построены... те же самые объекты построены в координатах нулевой признак–target. Мы вот видим, что первый признак является информативным, нулевой — шумовой. Итак, теперь данные мы сгенерировали, нам остается разбить их на обучение и тест. Сделаем это с помощью функции train_test_split. И теперь можно обучать модели. Давайте в качестве модели классификаций будем использовать SGDClassifier — это линейная классификация, работающая на основе стохастического градиентого спуска. В качестве функции потерь будем использовать log loss — нам это нужно для того, чтобы наш классификатор получился вероятностным. Для некоторых метрик мы захотим использовать вероятности принадлежности объектов к нашим классам, поэтому нам нужен вероятностный классификатор. Итак, теперь обучим классификатор — это делается с помощью метода fit. И сначала сгенерируем предсказания в виде меток классов, для этого будем использовать метод predict. И сгенерируем предсказание в виде вероятности принадлежности объекта к нулевому и первому классу. Это делается с помощью метода predict_proba, и также на вход передаем наши тестовые данные. И теперь давайте выведем все это на экран, посмотрим, что у нас получилось. Для начала — правильные метки, теперь — предсказания в виде меток. Сразу видно, что мы немножечко ошибаемся в нескольких местах. И теперь — предсказания в виде вероятности принадлежности к обоим классам. Помните, что первое значение — это вероятность принадлежать к нулевому классу, второе значение — вероятность принадлежать к первому классу. Итак, вся подготовительная работа завершена, теперь можем непосредственно заняться расчетом метрик. Первая метрика, на которую мы посмотрим — это accuracy, мы с ней уже знакомы. Эта метрика соответствует доле правильно классифицированных объектов. Понятно, что метрика довольно простая, поэтому ее реализацию мы можем написать самостоятельно — достаточно просто сравнить метку... правильную метку и метку, которую мы предсказываем. Дальше посчитать, сколько, в скольких случаях мы предсказываем метку правильно, и поделить это на объем данных. Мы получаем вот такую оценку — 0,83. Ну а теперь давайте воспользуемся готовой реализацией метрики accuracy — функция называется accuracy_score. В качестве аргументов передаем ей предсказанные нашим классификатором метки и правильные метки. И теперь давайте смотреть. Да, мы видим, что наши оценки совпали. Следующий объект, про который хочется рассказать — это confusion matrix. Это матрица, размером количество классов на количество классов. В позиции i и j у нас стоит элемент, который характеризует количество объектов, которые изначально относились... имели метку i, но мы им поставили метку j. Таким образом, на диагонали у нас — элементы, характеризующие объекты, на которых мы ответили правильно, вне диагонали у нас — элементы, характеризующие количество объектов, на которых мы ошиблись. Давайте построим такую матрицу и выведем ее на экран. Она строится с помощью метода confusion_matrix. Также на вход мы передаем правильные метки классов и предсказанные метки. Вот мы с вами видим, что довольно неплохо мы отработали. На диагонали видим значения 12 и 13, то есть, ну, мы ошибаемся не так часто. Теперь давайте проверим, так ли это. Мы можем снова просуммировать объекты, на которых наша метка совпадает с предсказанной — это делается довольно просто. Получили 25 объектов. Теперь если мы сложим диагональные объекты на нашей матрице, мы тоже получили 25. Таким образом, понятно, что если сложить диагональные элементы, мы найдем количество объектов, на которых мы ответили правильно. confusion_matrix очень полезна тем, что на ее основе можно рассчитывать такие метрики, как точность, полнота и f-меры. Давайте и мы с вами это сделаем. Для начала давайте оценим точность классификации. Так как мы решаем задачу бинарной классификации, мы можем отдельно оценить точность при отнесении объектов к нулевому классу и точность при отнесении объектов к первому классу. Для того чтобы оценить точность классификации к нулевому классу, нам нужно вызвать функцию precision_score, передать ей правильные метки классов, передать предсказанные метки классов. И так как по умолчанию наш label равен 1, то нам нужно явно сказать, что в данном случае мы оцениваем точность классификации к нулевому классу. Для этого используем аргумент pos_label и говорим, что он равен 0. Итак, видим, что мы получили 0,8. Теперь давайте оценим точность классификации объектов к первому классу. Мы получили 0,87. Ну, по нашей матрице понятно, почему точность при классификации к первому классу получилась больше. Теперь давайте оценим полноту. Это делается с помощью метода recall_score, а аргументы такие же. Сначала оцениваем полноту для нулевого класса, получаем 0,86. И теперь давайте посмотрим на первый класс — 0,81. Имея оценки для precision и recall (для точности и полноты), легко получить оценки для f-меры. Давайте сначала оценим f-меру для нулевого класса, и теперь — для первого. Наши оценки готовы. Часто, когда мы решаем задачу классификации, нам интересно смотреть на все эти метрики: на precision, recall, f-меру. Причем нам интересны как значения в разрезе классов, так и значения в среднем. Для того чтобы получить такую мини-сводку по нашей модели, удобно использовать функцию под названием classification_report. Давайте ее вызовем. Для ее работы достаточно передать ей метки класса и предсказанные метки класса. Давайте посмотрим. Получили такую красивую табличку. Здесь мы видим качество модели в разрезе классов, видим precision, recall, f-score. Также видим, сколько изначально объектов было разных классов, и видим некоторые усреднения внизу — довольно удобно. А мы двигаемся дальше. Следующая метрика, про которую мы говорим — это ROC-curve и ROC — AUC. Из предыдущих уроков вы наверняка помните, что для построения ROC-curve мы сначала сортируем наши объекты по предсказанной величине, потом делим их на несколько групп по некоторым пороговым отсечениям и внутри каждой группы оцениваем True Positive Rate и False Positive Rate. Далее, когда мы таким образом получаем списки True Positive Rate и False Positive Rate, мы можем построить нашу ROC-кривую. Просто строим кривую в этих координатах. Итак, для того чтобы получить списки False Positive Rate, True Positive Rate и thresholds, нам нужно вызвать функцию roc_curve. Она принимает на вход правильные метки классов и наши ответы на этих классах. Нам интересней в данном случае воспользоваться вероятностными ответами, потому что здесь у нас задан более точный порядок. Поэтому давайте передадим в качестве второго аргумента probability_predictions — наши вероятностные предсказания. Мы с вами будем использовать вероятности отнесения объектов к первому классу, поэтому вот мы говорим, что берем все объекты, и так как, вы помните, там список из двух элементов, берем элемент с индексом 1 — это вероятность принадлежать к первому классу. Запускаем функцию, получили три аргумента. False Positive Rates и True Positive Rates нам нужны непосредственно для построения ROC-кривой, ну и понятно, что трешхолды нам для построения ROC-кривой не нужны, поэтому давайте будем здесь использовать нижнее подчеркивание, явно говоря о том, что это возвращаемое значение мы использовать не собираемся. Теперь у нас есть все данные для построения ROC-кривой. Построим ее с помощью метода plot. Передаем в качестве x-координат False Positive Rates, в качестве y-координат — True Positive Rate, и назовем нашу кривую linear model, линейная модель. Теперь давайте для сравнения построим ROC-кривую, соответствующую случайной классификации, — это просто диагональная прямая, назовем ее random. Создадим границы для оси x и оси y с помощью xlim и ylim. Далее, давайте зададим названия для наших осей и зададим имя графика. Также мы отрисуем легенду — подпись к каждой кривой, она будет находиться справа внизу. Строим график. Ну вот мы видим, что наша ROC-кривая выглядит таким образом. Теперь, для того чтобы количественно оценить качество модели, нам с вами нужно посчитать площадь под ROC-кривой. Такая метрика называется ROC — AUC, и строится она с помощью метода roc_auc_score. Понятно, что в данном случае мы снова можем передать в качестве аргументов как предсказания в виде меток, так и предсказания в виде вероятностей. Хочется понять, получатся ли они одинаковые или разные, но интуитивно кажется, что они должны быть близки — действительно, это же классификация с помощью одной и той же модели. Но понятно, что когда мы с вами имеем дело с метками, то в этом случае порядок следования объектов несколько более свободный, ну то есть те объекты, которые имеют одинаковую метку, могут идти в произвольном порядке. Случай, когда мы работаем с вероятностной классификацией, наш порядок задан более строго. Вот давайте сравним AUC в обоих случаях. Запускаем и видим, что, действительно, он у нас значительно отличается. Ну такое бывает из-за того, что в первом случае у нас действительно объекты могут в рамках группы идти в произвольном порядке. Это нормально. Еще одна метрика, на которую хочется посмотреть — это average_precision_score или presicion AUC. Для того чтобы ее посчитать, нужно вызвать функцию average_precision_score, и также передаем ей правильные метки и наши предсказания. И для оценки вероятностных классификаторов часто используется метрика log_loss, или логистические потери. В данном случае мы уже не можем передать ей метки класса, мы должны передать вероятности принадлежности к первому классу. Давайте запустим эту метрику и посмотрим. Видим, что log_loss довольно небольшой — 1,3 — очень неплохая оценка. Ну, вы помните, что log_loss — чем меньше эта метрика, тем лучше. В идеальном случае мы должны получить 0. Теперь давайте перейдем к решению задачи регрессии. Для этого нам нужно построить наш регрессор. Воспользуемся снова SGD-регрессором — это также метод регрессии, основанный на стохастическом градиентном спуске. Теперь давайте обучим модель и сгенерируем предсказания. Вот правильные значения нашей функции, вот приближенные значения. Мы видим, что да, действительно, они не везде совпадают. Теперь — как их можно оценивать. Первая метрика — это mean absolute error, средняя ошибка предсказаний, мы ей уже пользовались ранее, когда строили модель регрессии. Давайте ее посчитаем. Видим, что в среднем мы ошибаемся на 3,7. В качестве аргументов метрики передаем предсказанные значения, истинные значения, и считаем. Помимо абсолютных отклонений можно посчитать так называемую MSE-метрику, или mean squared error — это среднеквадратичное отклонение. Ну давайте запустим. Видим, что среднеквадратичное отклонение равно 24. Часто вместо среднеквадратичного отклонения используют корень из среднеквадратичного отклонения. Ну, его получить очень просто — достаточно посчитать среднеквадратичное отклонение с помощью той же самой функции и просто взять у него корень. Ну вот давайте посмотрим, как это выглядит. Получаем оценку 4,9. Последняя метрика, про которую хотелось бы сказать — это коэффициент детерминации, или r2 score. Для того чтобы ее посчитать, нужно вызвать функцию r2_score и передать ей на вход наши предсказания и правильные значения функции. Давайте запустим. И видим, что значение довольно высокое — 0,99. Итак, давайте подведем итог. Мы с вами рассмотрели целый ряд метрик для оценки моделей классификации и регрессии. На этом мы заканчиваем этот урок и заканчиваем знакомство с библиотекой sklearn. За модуль мы научились генерировать модельные данные, научились строить разбиение данных с помощью кросс-валидации. Также мы научились обучать линейные модели и оценивать их качество. Конечно, в библиотеке sklearn есть еще много интересных функциональностей, и мы обязательно вернемся к ее изучению чуть позже. А в следующем модуле вы продолжите изучать линейные модели.