Изменения

Перейти к: навигация, поиск

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

20 662 байта добавлено, 19:06, 4 сентября 2022
м
rollbackEdits.php mass rollback
== Оценки качества классификации ==
=== Матрица ошибок (англ. Сonfusion matrix (матрица ошибок) ===
Перед переходом к самим метрикам необходимо ввести важную концепцию для описания этих метрик в терминах ошибок классификации — [[матрица ошибок|confusion matrix]] (матрица ошибок).
Допустим, что у нас есть два класса <math>y = \{ 0, 1 \}</math> и алгоритм, предсказывающий принадлежность каждого объекта одному из классов.
Рассмотрим пример. Пусть банк использует систему классификации заёмщиков на кредитоспособных и некредитоспособных. При этом первым кредит выдаётся, а вторые получат отказ. Таким образом, обнаружение некредитоспособного заёмщика (<math>y = 1 </math>) можно рассматривать как "сигнал тревоги", сообщающий о возможных рисках.
Поскольку с точки зрения логики задачи нам важнее правильно распознать некредитоспособного заёмщика с меткой <math>y = 1 </math>, чем ошибиться в распознавании кредитоспособного, будем называть соответствующий исход классификации положительным (заёмщик некредитоспособен), а противоположный - отрицательным (заемщик кредитоспособен <math>y = 0 </math>). Тогда возможны следующие исходы классификации:
* Некредитоспособный заёмщик классифицирован как некредитоспособный, т.е. положительный класс распознан как положительный. Наблюдения, для которых это имеет место называются '''истинно-положительными ''' ([[true positive]] '''True Positive''' {{- --}} '''TP''').* Кредитоспособный заёмщик классифицирован как кредитоспособный, т.е. отрицательный класс распознан как отрицательный. Наблюдения, которых это имеет место, называются '''истинно отрицательными ''' ([[true negative]] '''True Negative''' {{--- }} '''TN''').* Кредитоспособный заёмщик классифицирован как некредитоспособный, т.е. имела место ошибка, в результате которой отрицательный класс был распознан как положительный. Наблюдения, для которых был получен такой исход классификации, называются '''ложно-положительными ''' ([[false positive]] '''False Positive''' {{--- }} '''FP'''), а ошибка классификации называется '''ошибкой I рода'''.* Некредитоспособный заёмщик распознан как кредитоспособный, т.е. имела место ошибка, в результате которой положительный класс был распознан как отрицательный. Наблюдения, для которых был получен такой исход классификации, называются '''ложно-отрицательными ''' ([[false negative]] '''False Negative''' {{--- }} '''FN'''), а ошибка классификации называется '''ошибкой II рода'''.
Таким образом, ошибка I рода, или ложно-положительный исход классификации, имеет место, когда отрицательное наблюдение распознано моделью как положительное. Ошибкой II рода, или ложно-отрицательным исходом классификации, называют случай, когда положительное наблюдение распознано как отрицательное. Поясним это с помощью матрицы ошибок классификации:
[[Файл:Confusion_matrix.png{|500px]]class="wikitable" style="text-align: center"||<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''' {{---}} неправильно). Каждая строка в матрице ошибок представляет фактический спрогнозированный класс, а каждый столбец {{- спрогнозированный --}} фактический класс.
<font color="green"># код для матрицы ошибок</font>
<font color="green">'''# Пример классификатора, способного проводить различие между всего лишь двумя</font>
<font color="green">'''# классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font>
'''import''' numpy '''as''' np
'''from''' sklearn.datasets '''import''' fetch_openml
'''from''' sklearn.model_selection '''import''' cross_val_predict
'''from''' sklearn.metrics '''import''' confusion_matrix
'''importfrom''' pandas sklearn.linear_model '''asimport''' pdSGDClassifier mnist = fetch_openml('mnist_784''n , version=1) X, y = mnist["data"], mnist["target"] y = confusion_matrixy.astype(np.uint8) X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], ay[60000:] y_train_5 = (y_train == 5) <font color="green"># 1-й способTrue для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font> y_test_5 = (y_test == 5) '''n sgd_clf = SGDClassifier(random_state=42)<font color= pd"green"> # классификатор на основе метода стохастического градиентного спуска (англ.crosstabStochastic Gradient Descent SGD)</font> sgd_clf.fit(yX_train, ay_train_5) <font color="green"># 2-й способобучаем классификатор распозновать пятерки на целом обучающем наборе</font> '''<font color="green"># Вычисление TN, FP, FNДля расчета матрицы ошибок сначала понадобится иметь набор прогнозов, TP чтобы их можно было сравнивать с фактическими целями</font> '''TNy_train_pred = cross_val_predict(sgd_clf, FPX_train, FNy_train_5, TP cv= 3) print(confusion_matrix(yy_train_5, ay_train_pred).ravel) <font color="green"># array([[53892, 687], # [ 1891, 3530]])</font>
Безупречный классификатор имел бы только истинно-поло­жительные и истинно отрицательные классификации, так что его матрица ошибок содержала бы ненулевые значения только на своей главной диа­гонали (от левого верхнего до правого нижнего угла):
'''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 = Accuracy 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) <font color="green"># True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font> y_test_5 = (y_test == 5) y_train_perfect_predictions = y_train_5 <font color="green"># притворись, что мы достигли совершенства</font> print(confusion_matrix(y_train_5, y_train_perfect_predictions)) <font color="green"># array([[54579, 0], # [ 0, 5421]])</font>
Интуитивно понятной, очевидной и почти неиспользуемой метрикой является [[accuracy]] — доля правильных ответов алгоритма:=== Аккуратность (англ. Accuracy) ===
[[ФайлИнтуитивно понятной, очевидной и почти неиспользуемой метрикой является ''accuracy'' — доля правильных ответов алгоритма:acc.png|300px]]
: <math>accuracy = \dfrac{TP+TN}{TP+TN+FP+FN}</math> Эта метрика бесполезна в задачах с неравными классами, что как вариант можно исправить с помощью [[алгоритмы сэмплирования|алгоритмов сэмплирования]] и это легко показать на примере.
Допустим, мы хотим оценить работу спам-фильтра почты. У нас есть 100 не-спам писем, 90 из которых наш классификатор определил верно (True Negative = 90, False Positive = 10), и 10 спам-писем, 5 из которых классификатор также определил верно (True Positive = 5, False Negative = 5).
Тогда accuracy:
[[Файл:acc1.png|300px]]<math>accuracy = \dfrac{5+90}{5+90+10+5} = 86,4</math>
Однако если мы просто будем предсказывать все письма как не-спам, то получим более высокую accuracy''аккуратность'':
[[Файл:acc2.png|300px]]<math>accuracy = \dfrac{0+100}{0+100+0+10} = 90,9</math>
При этом, наша модель совершенно не обладает никакой предсказательной силой, так как изначально мы хотели определять письма со спамом. Преодолеть это нам поможет переход с общей для всех классов метрики к отдельным показателям качества классов.
<font color="green"># код для для подсчета аккуратности:</font> <font color="green">'''# Пример классификатора, способного проводить различие между всего лишь двумя '''# классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font> '''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)<font color="green"> # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font> y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42) <font color="green"># классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD)</font> sgd_clf.fit(X_train, y_train_5) <font color="green"># обучаем классификатор распозновать пятерки на целом обучающем наборе</font> y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) <font color="green"># print(confusion_matrix(y_train_5, y_train_pred)) # array([[53892, 687] # [ 1891, 3530]])</font> print(accuracy_score(y_train_5, y_train_pred))<font color="green"> # == (53892 + 3530) / (53892 + 3530 + 1891 +687)</font> <font color="green"># 0.9570333333333333</font> === Точность (англ. Precision) === Точностью (''precision'') называется доля правильных ответов модели в пределах класса {{---}} это доля объектов действительно принадлежащих данному классу относительно всех объектов которые система отнесла к этому классу. : <math>Precision = \dfrac{TP}{TP+FP}</math> Именно введение ''precision'' не позволяет нам записывать все объекты в один класс, так как в этом случае мы получаем рост уровня ''False Positive''. === Полнота (англ. Recall) ===
Precision (точностью) называется доля правильных ответов модели в пределах класса – Полнота {{---}} это доля истинно положительных классификаций. Полнота показывает, какую долю объектов действительно принадлежащих данному классу относительно всех объектов которые система отнесла , реально относящихся к этому положительному классу, мы предсказали верно.
[[Файл:prec.png|250px]]<math>Recall = \dfrac{TP}{TP+FN}</math>
Именно введение precision не позволяет нам записывать все объекты в один Полнота (''recall'') демонстрирует способность алгоритма обнаруживать данный класс, так как в этом случае мы получаем рост уровня False Positiveвообще.
=== Recall ===Имея матрицу ошибок, очень просто можно вычислить точность и полноту для каждого класса. Точность (''precision'') равняется отношению соответствующего диагонального элемента матрицы и суммы всей строки класса. Полнота (''recall'') {{---}} отношению диагонального элемента матрицы и суммы всего столбца класса. Формально:
Recall (Полнота системы) – это доля найденных классфикатором объектов принадлежащих классу относительно всех документов этого класса в тестовой выборке.: <math>Precision_c = \dfrac{A_{c,c}}{\sum \limits_{i=1}^{n} A_{c,i}}</math>
[[Файл:rec.png|250px]]<math>Recall_c = \dfrac{A_{c,c}}{\sum \limits_{i=1}^{n} A_{i,c}}</math>
Recall демонстрирует способность алгоритма обнаруживать данный класс вообщеРезультирующая точность классификатора рассчитывается как арифметическое среднее его точности по всем классам. То же самое с полнотой. Технически этот подход называется '''macro-averaging'''.
Имея матрицу ошибок точность <font color="green"># код для для подсчета точности и полнота полноты: '''# Пример классификатора, способного проводить различие между всего лишь двумя '''# классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font> '''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) <font color="green"># True для каждого класса рассчитывается очень простовсех пятерок, False для в сех остальных цифр. Precision Задача опознать пятерки</font> y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(точностьrandom_state=42) равняется отношению соответствующего диагонального элемента матрицы и суммы всей строки класса<font color="green"> # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD)</font> sgd_clf. Recall fit(X_train, y_train_5) <font color="green"># обучаем классификатор распозновать пятерки на целом обучающем наборе</font> y_train_pred = cross_val_predict(полнотаsgd_clf, X_train, y_train_5, cv=3) – отношению диагонального элемента матрицы и суммы всего столбца класса <font color="green"># print(confusion_matrix(y_train_5, y_train_pred)) # array([[53892, 687] # [ 1891, 3530]])</font> print(precision_score(y_train_5, y_train_pred)) <font color="green"># == 3530 / (3530 + 687)</font> print(recall_score(y_train_5, y_train_pred)) <font color="green"># == 3530 / (3530 + 1891)</font> <font color="green"># 0.8370879772350012 # 0. Формально:6511713705958311</font>
[[Файл:macro=== F-eмера (англ.png|200px]]F-score) ===
Результирующая ''Precision'' и ''recall'' не зависят, в отличие от ''accuracy'', от соотношения классов и потому применимы в условиях несбалансированных выборок.Часто в реальной практике стоит задача найти оптимальный (для заказчика) баланс между этими двумя метриками. Понятно что чем выше точность классификатора рассчитывается как арифметическое среднее его и полнота, тем лучше. Но в реальной жизни максимальная точность и полнота не достижимы одновременно и приходится искать некий баланс. Поэтому, хотелось бы иметь некую метрику которая объединяла бы в себе информацию о точности по всем классами полноте нашего алгоритма. То же самое с полнотойВ этом случае нам будет проще принимать решение о том какую реализацию запускать в производство (у кого больше тот и круче). Технически этот подход называется macroИменно такой метрикой является ''F-averagingмера''.
=== F-mera ===мера представляет собой [https://ru.wikipedia.org/wiki/%D0%A1%D1%80%D0%B5%D0%B4%D0%BD%D0%B5%D0%B5_%D0%B3%D0%B0%D1%80%D0%BC%D0%BE%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5 гармоническое среднее] между точностью и полнотой. Она стремится к нулю, если точность или полнота стремится к нулю.
Precision и : <math> F = \dfrac{ 2 \times precision \times recall не зависят, в отличие от accuracy, от соотношения классов и потому применимы в условиях несбалансированных выборок.Часто в реальной практике стоит задача найти оптимальный (для заказчика) баланс между этими двумя метриками. Понятно что чем выше точность и полнота, тем лучше. Но в реальной жизни максимальная точность и полнота не достижимы одновременно и приходится искать некий баланс. Поэтому, хотелось бы иметь некую метрику которая объединяла бы в себе информацию о точности и полноте нашего алгоритма. В этом случае нам будет проще принимать решение о том какую реализацию запускать в production (у кого больше тот и круче). Именно такой метрикой является F-мера.}{ precision + recall }</math>
Данная формула придает одинаковый вес точности и полноте, поэтому F-мера представляет собой [[гармоническое среднее]] между точностью будет падать одинаково при уменьшении и точности и полнотойполноты. Она стремится к нулюВозможно рассчитать ''F-меру'' придав различный вес точности и полноте, если точность или полнота стремится к нулю.вы осознанно отдаете приоритет одной из этих метрик при разработке алгоритма:
[[Файл:f1.png|250px]]<math>F_β = \dfrac{(1+β^2) \times precision \times recall }{ (β^2 \times precision) + recall }</math>
Данная формула придает одинаковый вес где <math>β</math> принимает значения в диапазоне <math>0<β<1</math> если вы хотите отдать приоритет точности и полноте, поэтому F-мера будет падать одинаково а при уменьшении <math>β>1</math> приоритет отдается полноте. При <math>β=1</math> формула сводится к предыдущей и точности и полноты. Возможно рассчитать вы получаете сбалансированную F-меру придав различный вес точности и полноте, если вы осознанно отдаете приоритет одной из этих метрик при разработке алгоритма(также ее называют <math>F_1</math>).
[[Файл:f-mera.png|350px]]
где β принимает значения в диапазоне 0<βdiv><ul> <li style="display: inline-block;"> [[Файл:F_balanc.jpg|thumb|none|450px|Рис.1 если вы хотите отдать приоритет точностиСбалансированная F-мера, а при <math>β=1</math>]] </li><li style="display: inline-block;">1 приоритет отдается полноте[[Файл:F_prior_Prec.jpg|thumb|none|450px|Рис. При 2 F-мера c приоритетом точности, <math>β^2=\dfrac{ 1 формула сводится к предыдущей и вы получаете сбалансированную F}{ 4 }</math>]] </li><li style="display: inline-меру (также ее называют F1)block;"> [[Файл:F_prior_Recal.jpg|thumb|none|450px|Рис.3 F-мера достигает максимума при максимальной полноте и точностиc приоритетом полноты, и близка к нулю, если один из аргументов близок к нулю.<math>β^2=2</math>]] </li></ul></div>
[[Файл:fmb''F-мера'' достигает максимума при максимальной полноте и точности, и близка к нулю, если один из аргументов близок к нулю.png]]
''F-мера '' является хорошим кандидатом на формальную метрику оценки качества классификатора. Она сводит к одному числу две других основополагающих метрики: точность и полноту. Имея в своем распоряжении подобный механизм оценки вам будет "F-меру" гораздо проще принять решение о том являются ли изменения в алгоритме ответить на вопрос: "поменялся алгоритм в лучшую сторону или нет?"   <font color="green"># код для подсчета метрики F-mera: '''# Пример классификатора, способного проводить различие между всего лишь двумя '''# классами, "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font> '''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)<font color="green"> # True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font> y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42)<font color="green"> # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD)</font> sgd_clf.fit(X_train, y_train_5) <font color="green"># обучаем классификатор распознавать пятерки на целом обучающем наборе</font> y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) print(f1_score(y_train_5, y_train_pred)) <font color="green"># 0.7325171197343846</font>
=== ROC-кривая ===
'''Кривая рабочих характеристик''' (англ. '''Receiver Operating Characteristics curve (кривая рабочих характеристик''').
Используется для анализа поведения классификаторов при различных пороговых значениях.
Позволяет рассмотреть все пороговые значения для данного классификатора.
Показывает долю ложно положительных примеров ( FPR, англ. '''false positive rate , FPR''') в сравнении с долей истинно положительных примеров ( TPR, англ. '''true positive rate, TPR'''). [[Файл:ROC_2.png]] : <math> TPR = \dfrac{TP}{TP+FN} = Recall</math> : <math> FPR = \dfrac{FP}{FP+TN} </math> Доля '''FPR''' {{---}} это пропорция отрицательных образцов, которые были некорректно классифицированы как положительные. : <math> FPR = 1 - TNR</math>,  где '''TNR''' {{---}} доля истинно отрицательных классификаций (англ. '''Тrие Negative Rate'''), пред­ставляющая собой пропорцию отрицательных образцов, которые были кор­ректно классифицированы как отрицательные. Доля '''TNR''' также называется '''специфичностью''' (англ. '''specificity'''). Следовательно, ROC-кривая изображает '''чувствительность''' (англ. '''seпsitivity'''), т.е. полноту, в срав­нении с разностью '''1 - specificity'''.
[[Файл:RoccurvesПрямая линия по диагонали представляет ROC-кривую чисто случайного классификатора.png|600px]]Хороший классификатор держится от указанной линии настолько далеко, насколько это[[Файл:2fвозможно (стремясь к левому верхнему углу).png|250px]]
<font color="green"># Код отрисовки ROC-Один из способов сравнения классификаторов предусматривает измере­ние '''площади под кривой</font> '''sns.set(font_scale=1англ.5) '''sns.set_color_codes("muted") Area Under the Curve {{---}} AUC'''plt.figure(figsize=(10, 8)) '''fpr, tpr, thresholds = roc_curve(y_test, lr.predict_probaБезупречный клас­сификатор будет иметь площадь под ROC-кривой (X_test)[:,1], pos_label=1) '''lw = 2 ROC-AUC'''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, 15.05]) '''plt.xlabel('False Positive Rate') '''plt.ylabel('True Positive Rate') '''plt.title('ROC curve') '''plt.savefig("ROC.png") '''plt.show()
<font color="green"># Код отрисовки ROC-кривой
'''# На примере классификатора, способного проводить различие между всего лишь двумя классами
'''# "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font>
'''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) <font color="green"># True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font>
y_test_5 = (y_test == 5)
sgd_clf = SGDClassifier(random_state=42) <font color="green"># классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD)</font>
sgd_clf.fit(X_train, y_train_5) <font color="green"># обучаем классификатор распозновать пятерки на целом обучающем наборе</font>
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''')
'''Precison-recall кривая[[Файл:PR_curve.''' Избавиться от указанной проблемы с несбалансированными классами можно, перейдя от ROC-кривой к Precision-Recall кривой. Она определяется аналогично ROC-кривой, только по осям откладываются не FPR и TPR, а полнота (по оси абсцисс) и точность (по оси ординат). Критерием качества семейства алгоритмов выступает площадь под PR-кривой (AUC-PR)png]]
<font color="green"># Код отрисовки Precison-recall кривой '''# На примере классификатора, способного проводить различие между всего лишь двумя классами '''# "пятерка" и "не пятерка" из набора рукописных цифр MNIST</font> '''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) <font color="green"># True для всех пятерок, False для в сех остальных цифр. Задача опознать пятерки</font> y_test_5 = (y_test == 5) sgd_clf = SGDClassifier(random_state=42)<font color="green"> # классификатор на основе метода стохастического градиентного спуска (Stochastic Gradient Descent SGD)</font> sgd_clf.fit(X_train, y_train_5) <font color="green"># обучаем классификатор распозновать пятерки на целом обучающем наборе</font> 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):pr plt.plot(recalls, precisions, linewidth=2) plt.xlabel('Recall') plt.ylabel('Precision') plt.title('Precision-recRecall curve') plt.savefig("Precision_Recall_curve.png|600px]]") plot_precision_recall_vs_threshold(precisions, recalls, thresholds) plt.show()
== Оценки качества регрессии ==
Наиболее типичными мерами качества в задачах регрессии являются
=== MSE, Средняя квадратичная ошибка (англ. Mean Squared Error (средняя квадратичная ошибка, MSE) ===
[[Файл:mse1''MSE'' применяется в ситуациях, когда нам надо подчеркнуть большие ошибки и выбрать модель, которая дает меньше больших ошибок прогноза. Грубые ошибки становятся заметнее за счет того, что ошибку прогноза мы возводим в квадрат. И модель, которая дает нам меньшее значение среднеквадратической ошибки, можно сказать, что что у этой модели меньше грубых ошибок.png]] и
: <math>MSE =\dfrac{1}{n}\sum \limits_{i== MAE, Mean Absolute Error 1}^{n}(a(средняя абсолютная ошибкаx_i) - y_i) === ^2</math> и
[[Файл=== Cредняя абсолютная ошибка (англ. Mean Absolute Error, MAE) ===  :mae2.png]]<math>MAE = \dfrac{1}{n}\sum \limits_{i=1}^{n}|a(x_i) - y_i|</math>
Среднеквадратичный функционал сильнее штрафует за большие отклонения по сравнению со среднеабсолютным, и поэтому более чувствителен к выбросам. При использовании любого из этих двух функционалов может быть полезно проанализировать, какие объекты вносят наибольший вклад в общую ошибку — не исключено, что на этих объектах была допущена ошибка при вычислении признаков или целевой величины.
Среднеквадратичная ошибка подходит для сравнения двух моделей или для контроля качества во время обучения, но не позволяет сделать выводов о том, на сколько хорошо данная модель решает задачу. Например, MSE = 10 является очень плохим показателем, если целевая переменная принимает значения от 0 до 1, и очень хорошим, если целевая переменная лежит в интервале (10000, 100000). В таких ситуациях вместо среднеквадратичной ошибки полезно использовать коэффициент детерминации, или коэффициент {{---}} <math>R ^2</math>
=== Коэффициент детерминации ===
[[Файл:determ.png]]<math>R^2 = 1 - \dfrac{\sum \limits_{i=1}^{n}(a(x_i) - y_i)^2}{\sum \limits_{i=1}^{n}(y_i - \overline{y})^2}</math>
Коэффициент детерминации измеряет долю дисперсии, объясненную моделью, в общей дисперсии целевой переменной. Фактически, данная мера качества — это нормированная среднеквадратичная ошибка. Если она близка к единице, то модель хорошо объясняет данные, если же она близка к нулю, то прогнозы сопоставимы по качеству с константным предсказанием.
=== MAPE, Средняя абсолютная процентная ошибка (англ. Mean Absolute Percentage Error (средняя абсолютная процентная ошибка, MAPE) ===
[[Файл:mape1.png]]<math>MAPE = 100\% \times \dfrac{1}{n}\sum \limits_{i=1}^{n} \dfrac{|y_i - a(x_i)|}{|y_i|}</math>
Это коэффициент, не имеющий размерности, с очень простой интерпретацией. Его можно измерять в долях или процентах. Если у вас получилось, например, что MAPE=11.4%, то это говорит о том, что ошибка составила 11,4% от фактических значений.
Основная проблема данной ошибки — нестабильность.
=== RMSE, Корень из средней квадратичной ошибки (англ. Root Mean Squared Error , RMSE) === : <math>RMSE = \sqrt{\dfrac{1}{n}\sum \limits_{i=1}^{n}(a(корень x_i) - y_i)^2}</math>  Примерно такая же проблема, как и в MAPE: так как каждое отклонение возводится в квадрат, любое небольшое отклонение может значительно повлиять на показатель ошибки. Стоит отметить, что существует также ошибка MSE, из средней квадратичной ошибкикоторой RMSE как раз и получается путем извлечения корня. === Cимметричная MAPE (англ. Symmetric MAPE, SMAPE) === : <math>SMAPE = \dfrac{1}{n}\sum \limits_{i=1}^{n} \dfrac{2 \times |y_i - a(x_i)|}{|y_i| + |a(x_i)|}</math> === Средняя абсолютная масштабированная ошибка (англ. Mean absolute scaled error, MASE) === : <math> MASE = \dfrac{\sum \limits_{i=1}^n |Y_i - e_i|}{\frac{n}{n-1}\sum \limits_{i=2}^n | Y_i-Y_{i-1}|} </math> ''MASE'' является очень хорошим вариантом для расчета точности, так как сама ошибка не зависит от масштабов данных и является симметричной: то есть положительные и отрицательные отклонения от факта рассматриваются в равной степени.Обратите внимание, что в ''MASE'' мы имеем дело с двумя суммами: та, что в числителе, соответствует тестовой выборке, та, что в знаменателе - обучающей. Вторая фактически представляет собой среднюю абсолютную ошибку прогноза. Она же соответствует среднему абсолютному отклонению ряда в первых разностях. Эта величина, по сути, показывает, насколько обучающая выборка предсказуема. Она может быть равна нулю только в том случае, когда все значения в обучающей выборке равны друг другу, что соответствует отсутствию каких-либо изменений в ряде данных, ситуации на практике почти невозможной. Кроме того, если ряд имеет тенденцию к росту либо снижению, его первые разности будут колебаться около некоторого фиксированного уровня. В результате этого по разным рядам с разной структурой, знаменатели будут более-менее сопоставимыми. Всё это, конечно же, является очевидными плюсами ''MASE'', так как позволяет складывать разные значения по разным рядам и получать несмещённые оценки.
[[Файл:rmseНедостаток ''MASE'' в том, что её тяжело интерпретировать. Например, ''MASE''=1.21 ни о чём, по сути, не говорит. Это просто означает, что ошибка прогноза оказалась в 1.21 раза выше среднего абсолютного отклонения ряда в первых разностях, и ничего более.jpeg|300px]]
Примерно такая же проблема, как и в MAPE: так как каждое отклонение возводится в квадрат, любое небольшое отклонение может значительно повлиять на показатель ошибки. Стоит отметить, что существует также ошибка MSE, из которой RMSE как раз и получается путем извлечения корня. Но так как MSE дает расчетные единицы измерения в квадрате, то использовать данную ошибку будет немного неправильно.== Кросс-валидация ==
=== SMAPE, Symmetric MAPE Хороший способ оценки модели предусматривает применение [[Кросс-валидация|кросс-валидации]] (симметричная MAPEcкользящего контроля или перекрестной проверки) ===.
[[ФайлВ этом случае фиксируется некоторое множество разбиений исходной выборки на две подвыборки:smape1обучающую и контрольную. Для каждого разбиения выполняется настройка алгоритма по обучающей подвыборке, затем оценивается его средняя ошибка на объектах контрольной подвыборки. Оценкой скользящего контроля называется средняя по всем разбиениям величина ошибки на контрольных подвыборках.png|300px]]
==Примечания = MASE=# [https://www.coursera.org/lecture/vvedenie-mashinnoe-obuchenie/otsienivaniie-kachiestva-xCdqN] Лекция "Оценивание качества" на www.coursera.org# [https://stepik.org/lesson/209691/step/8?unit=183195] Лекция на www.stepik.org о кросвалидации# [https://stepik.org/lesson/209692/step/5?unit=183196] Лекция на www.stepik.org о метриках качества, Mean absolute scaled error (cредняя абсолютная масштабированная ошибка) =Precison и Recall# [https://stepik.org/lesson/209692/step/7?unit=183196] Лекция на www.stepik.org о метриках качества, F-мера# [https://stepik.org/lesson/209692/step/8?unit=183196] Лекция на www.stepik.org о метриках качества, примеры
== См. также ==* [[Оценка качества в задаче кластеризации]]* [[Файл:mase.png|300pxКросс-валидация]]
Согласно Википедии, является очень хорошим вариантом для расчета точности, так как сама ошибка не зависит от масштабов данных и является симметричной== Источники информации ==# [https: то есть положительные и отрицательные отклонения от факта рассматриваются в равной степени//compscicenter.ru/media/courses/2018-autumn/spb-recommendation/materials/lecture02-linregr_1.pdf] Соколов Е.А.Лекция линейная регрессияОбратите внимание, что в мы имеем дело с двумя суммами# [http: та, что в числителе, соответствует тестовой выборке, та, что в знаменателе //www.machinelearning.ru/wiki/images/5/59/PZAD2016_04_errors.pdf] - обучающейДьяконов А. Функции ошибки / функционалы качества# [https://forecasting. Вторая фактически представляет собой среднюю абсолютную ошибку прогноза по методу Naivesvetunkov. Она же соответствует среднему абсолютному отклонению ряда в первых разностяхru/etextbook/forecasting_toolbox/models_quality/] - Оценка качества прогнозных моделей# [https://shtem. Эта величинаru/%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B0-%D0%BF%D1%80%D0%BE%D0%B3%D0%BD%D0%BE%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D1%84%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D0%B0/] - HeinzBr Ошибка прогнозирования: виды, по сутиформулы, показывает, насколько обучающая выборка предсказуемапримеры# [https://habr. Она может быть равна нулю только com/ru/company/ods/blog/328372/] - egor_labintcev Метрики в том случае, когда все значения в обучающей выборке равны друг другу, что соответствует отсутствию какихзадачах машинного обучения# [https://habr.com/ru/post/19657/] -либо изменений в ряде данных, ситуации на практике почти невозможнойgrossu Методы оценки качества прогноза# [http://www.machinelearning.ru/wiki/index. Кроме того, если ряд имеет тендецию к росту либо снижению, его первые разности будут колебаться около некоторого фиксированного уровняphp?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F] - К. В результате этого по разным рядам с разной структурой.Воронцов, знаменатели будут болееКлассификация# [http://www.machinelearning.ru/wiki/index.php?title=CV] -менее сопоставимымиК.В. Всё это, конечно же, является очевидными плюсами MASEВоронцов, так как позволяет складывать разные значения по разным рядам и получать несмещённые оценки.Скользящий контроль
Но, конечно же, без минусов нельзя. Проблема MASE в том, что её тяжело интерпретировать. Например, MASE=1.21 ни о чём, по сути, не говорит. Это просто означает, что ошибка прогноза оказалась в 1.21 раза выше среднего абсолютного отклонения ряда в первых разностях, и ничего более.[[Категория:Машинное обучение]][[Категория:Классификация]][[Категория:Регрессия]]
1632
правки

Навигация