Изменения

Перейти к: навигация, поиск
Precison-recall кривая
Поскольку с точки зрения логики задачи нам важнее правильно распознать некредитоспособного заёмщика с меткой <math>y = 1 </math>, чем ошибиться в распознавании кредитоспособного, будем называть соответствующий исход классификации положительным (заёмщик некредитоспособен), а противоположный - отрицательным (заемщик кредитоспособен <math>y = 0 </math>). Тогда возможны следующие исходы классификации:
* Некредитоспособный заёмщик классифицирован как некредитоспособный, т.е. положительный класс распознан как положительный. Наблюдения, для которых это имеет место называются '''истинно-положительными''' ('''true positiveTrue Positive''' {{---}} '''TP''').* Кредитоспособный заёмщик классифицирован как кредитоспособный, т.е. отрицательный класс распознан как отрицательный. Наблюдения, которых это имеет место, называются '''истинно отрицательными''' ('''true negativeTrue Negative''' {{---}} '''TN''').* Кредитоспособный заёмщик классифицирован как некредитоспособный, т.е. имела место ошибка, в результате которой отрицательный класс был распознан как положительный. Наблюдения, для которых был получен такой исход классификации, называются '''ложно-положительными''' ('''false positiveFalse Positive''' {{---}} '''FP'''), а ошибка классификации называется '''ошибкой I рода'''.* Некредитоспособный заёмщик распознан как кредитоспособный, т.е. имела место ошибка, в результате которой положительный класс был распознан как отрицательный. Наблюдения, для которых был получен такой исход классификации, называются '''ложно-отрицательными''' ('''false negativeFalse 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> — истинная метка класса на этом объекте.
<font color="green"># код для матрицы ошибок</font>
<font color="green">'''# Пример классификатора, способного проводить различие между всего лишь двумя</font> <font color="green">'''# классами, "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST</font>
'''import''' numpy '''as''' np
'''from''' sklearn.datasets '''import''' fetch_openml
sgd_clf = SGDClassifier(random_state=42) #классификатор на основе метода стохастического градиентного спуска (англ. Stochastic Gradient Descent SGD)
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(confusion_matrix(y_train_5, y_train_pred))
<font color="green"># array([[53892, 687], # [ 1891, 3530]])</font>
Безупречный классификатор имел бы только истинно-поло­жительные и истинно отрицательные классификации, так что его матрица ошибок содержала бы ненулевые значения только на своей главной диа­гонали (от левого верхнего до правого нижнего угла):
y_train_perfect_predictions = y_train_5 # притворись, что мы достигли совершенства
print(confusion_matrix(y_train_5, y_train_perfect_predictions))
<font color="green"># array([[54579, 0], # [ 0, 5421]])</font>
=== Аккуратность (англ. Accuracy) ===
<font color="green"># код для для подсчета аккуратности:</font>
<font color="green">'''# Пример классификатора, способного проводить различие между всего лишь двумя '''# классами, "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST</font>
'''import''' numpy '''as''' np
'''from''' sklearn.datasets '''import''' fetch_openml
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)) # == (53892 + 3530) / (53892 + 3530 + 1891 +687)
<font color="green"># 0.9570333333333333</font>
=== Точность (англ. Precision) ===
Результирующая точность классификатора рассчитывается как арифметическое среднее его точности по всем классам. То же самое с полнотой. Технически этот подход называется '''macro-averaging'''.
<font color="green"># код для для подсчета точности и полноты:</font>
'''# Пример классификатора, способного проводить различие между всего лишь двумя
'''# классами, "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST</font>
'''import''' numpy '''as''' np
'''from''' sklearn.datasets '''import''' fetch_openml
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(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>
=== F-мера (англ. F-score) ===
''F-мера'' является хорошим кандидатом на формальную метрику оценки качества классификатора. Она сводит к одному числу две других основополагающих метрики: точность и полноту. Имея "F-меру" гораздо проще ответить на вопрос: "поменялся алгоритм в лучшую сторону или нет?"
<font color="green"># код для подсчета метрики F-mera:</font>
'''# Пример классификатора, способного проводить различие между всего лишь двумя
'''# классами, "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST</font>
'''import''' numpy '''as''' np
'''from''' sklearn.datasets '''import''' fetch_openml
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-кривая ===
Один из способов сравнения классификаторов предусматривает измере­ние '''площади под кривой''' (англ. '''Area Under the Curve {{---}} AUC'''). Безупречный клас­сификатор будет иметь площадь под ROC-кривой ('''ROC-AUC'''), равную 1, тогда как чисто случайный классификатор - площадь 0.5.
<font color="green"># Код отрисовки ROC-кривой</font>
'''# На примере классификатора, способного проводить различие между всего лишь двумя классами
'''# "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST</font>
'''from''' sklearn.metrics '''import''' roc_curve
'''import''' matplotlib.pyplot '''as''' plt
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")
<font color="green"># Код отрисовки Precison-recall кривой</font>
'''# На примере классификатора, способного проводить различие между всего лишь двумя классами
'''# "пятерка" и "не пятерка" из набор данных набора рукописных цифр MNIST
'''from''' sklearn.metrics '''import''' precision_recall_curve
'''import''' matplotlib.pyplot '''as''' plt
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")
== Примечания ==
# [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 о метриках качества, 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 о метриках качества, примеры
== См. также ==
== Источники информации ==
# [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.svetunkov.ru/etextbook/forecasting_toolbox/models_quality/] - Оценка качества прогнозных моделей
# [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] - К.В.Воронцов, Скользящий контроль
187
правок

Навигация