ROC-анализ модели и выбор порога отсеченияВ качестве метода оценки прогностической способности модели используем ROC-анализ.
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
В данной статье мы продолжим освещать процесс построения скоринговой модели с помощью метода деревьев решений1. Речь пойдет о валидации модели посредством ROC-анализа и приме-нении полученной модели к новым данным. Особое внимание уделено процедуре выбора оптимального порога отсечения с исполь-зованием критерия Йодена. Отдельно рассмотрен вопрос сохра-нения и экспорта полученных результатов, которые могут быть прочитаны и использованы для анализа в других статистических пакетах.
1 См.: Груздев А.В. Разработка скоринговой модели с помощью метода деревьев решений // Риск-менеджмент в кредитной организации. 2013. № 2. С. 65–81.
Загрузим пакет pROC:> library(pROC)
Рассчитаем ROC-кривую для модели деревьев решений после прунинга:> roc.model <- roc(data$default, # данные из выборкиpredict(model2, type=“prob”)[,1], # прогноз модели, взять из столбца 1 ci=TRUE) # заказываем доверительные интервалыПостроим график ROC-кривой для модели:> plot.roc(roc.model)
Программа строит ROC-кривую (рис. 1) и вычисляет значение площади под кривой (Area Under Curve).
А.В. ГруздеВ,
исследовательская
компания «Гевисста»,
директор
34
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка
Кривая ROC содержит в себе все возможные пороговые значения. При этом она наглядно показывает для любого порога отсечения: 1) насколько велик риск отказать благонадежному заемщику и 2) одно-временно насколько велик риск выдать кредит проблемному заем-щику.
Рисунок 1
ROC-кривая
Рассчитаем чувствительность и специфичность модели для всех возможных порогов отсечения:> ci.thresholds(roc.model)
Протокол расчетов 1
Площадь под кривой
Протокол расчетов 2
Чувствительность и специфичность модели для различных порогов отсечения
Call:roc.default(response = data$default, predictor = predict(model2, type = “prob”)[, 1], ci = TRUE)
Data: predict(model2, type = “prob”)[, 1] in 517 controls (data$default 0) > 183 cases (data$default 1).Area under the curve: 0.869995% CI: 0.8374-0.9024 (DeLong)
Кривая ROC содержит
в себе все возможные
пороговые значения.
При этом она наглядно
показывает для любого
порога отсечения:
1) насколько велик риск
отказать благонадеж-
ному заемщику
и 2) одно вре менно
насколько велик риск
выдать кредит проблем-
ному заемщику.
thresholds sp.low sp.median sp.high se.low se.median se.high 0.9736842 0.005803 0.01547 0.02708 1.00000 1.00000 1.0000
1
0,8
0,6
0,4
0,2
0
Sen
siti
vity
Specificity1 0,8 0,6 0,4 0,2 0
35
www.reglament.net
критерий Йодена \ ROC-кривая \ вероятность дефолта
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
Например, рассмотрим медианы чувствительности и специфич-ности при пороге отсечения 0,93.
В нашем примере чувствительность — это способность модели правильно определять тех клиентов, у которых дефолт есть. Специ-фичность — это способность модели правильно определять, у кого нет дефолта.
При пороге отсечения 0,93 чувствительность равна 0,91. Это озна-чает, что 91% «плохих» заемщиков будет выявлен классификатором. Следовательно, 9% «плохих» заемщиков будут ошибочно отнесены к «хорошим» и получат кредит. Выше чувствительность — ниже кредитный риск. Специфичность равна 0,56. Это означает, что 56% «хороших» заемщиков будут выявлены классификатором. Следова-тельно, 44% «хороших» заемщиков будут ошибочно отнесены к «пло-хим» и получат отказ в предоставлении кредита. Выше специфич-ность — ниже риск упущенной выгоды.
Для расчета оптимального порога используем критерий Йодена (рис. 2). Согласно ему, оптимальный порог — тот, при котором рас-стояние до диагональной линии в 45 градусов (бесполезного клас-сификатора) максимально. Критерий Йодена (J) показывает макси-
0.9466009 0.092840 0.11990 0.14700 0.96170 0.98360 1.0000 0.9287990 0.516400 0.55900 0.60350 0.86890 0.91260 0.9508 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.1314655 0.986500 0.99420 1.00000 0.07650 0.12020 0.1694 0.1213235 0.990300 0.99610 1.00000 0.04372 0.08197 0.1204 -Inf 1.000000 1.00000 1.00000 0.00000 0.00000 0.0000
Рисунок 2
Критерий Йодена для расчета оптимального порога отсечения
С
J
1,0
0,80,9
0,60,5
0,7
0,4
0,20,1
0,3
0 10,90,80,70,60,50,40,30,10,1
SE
1 – SP
36
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка
мальное отличие ординат ROC-кривой и диагонали. Вычисляется по формуле:
J = max(sensitivities + specificities).
Дополнительно критерий поддерживает веса. Это сделано для случая, когда ошибки первого и второго рода не симметричны в выборке, где планируется использование полученного классифика-тора. Это аргумент ‘best.weights’, ему присваивают численный век-тор длиной 2. Элементы этого вектора определяют:
1. Относительную цену ложной негативной классификации по отношению к ложной позитивной классификации.
2. «Долю» или пропорцию случаев, которые должен распознать классификатор в генеральной совокупности.
Веса вводятся в формулу критерия по методике, предложенной Перкинсом и Шустерманом:
max(sensitivities + r × specificities),
где r = (1 – доля) / (относительная цена ложно негативной ошибки × доля).
По умолчанию «доля» равна 0,5, а относительная цена ошибки равна 1, следовательно, влияние весов на расчет критерия отсут-ствует.
Вычислим критерий Йодена применительно к ROC-кривой, которая построена для модели деревьев решений после прунинга:> coords(roc.model, # модель ROC“best”, # вид критерияbest.method=“youden”, # способ расчета критерияret=c(“threshold”, “spec”, “sens”)) # какие параметры возвращать
Протокол расчетов 3
Расчет критерия Йодена для ROC-кривой threshold specificity sensitivity 0.7388889 0.8878143 0.7377049
Однако реальная ситуация редко столь симметрична, более того, убыток при невозврате каждого кредита и прибыль от выдачи явля-ются в каждом конкретном случае вполне индивидуальными вели-чинами.
37
www.reglament.net
критерий Йодена \ ROC-кривая \ вероятность дефолта
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
В таком случае легко найти оптимальный порог, включив в кри-терий вес, с которым соотносятся убытки и прибыли конкретного рассматриваемого случая.
Рассчитаем критерий Йодена для симметричного случая, когда потери в случае отказа «хорошему» заемщику и пропуска «плохого» равны. > coords(roc.model, # модель ROC“best”, # вид критерияbest.method=“youden”, # способ расчета критерияbest.weights=c(1, 0.5), # первый параметр — стоимость пропущенного “плохого” заемщикаret=c(“threshold”, “spec”, “sens”)) # какие параметры возвращать
Рассчитаем критерий Йодена, когда стоимость пропуска «плохого» заемщика в два раза меньше симметричного случая. Проще говоря, рассмотрим ситуацию, когда стоимость ошибки, приведшей к выдаче кредита «плохому» заемщику, в два раза меньше дохода от возвращенного вовремя кредита такого же размера:> coords (roc.model,“best”,best.method=“youden”,best.weights=c(0.5, 0.5), # первый параметр уменьшен вдвоеret=c(“threshold”, “spec”, “sens”))
Рассчитаем критерий Йодена, когда стоимость пропуска «плохого» заемщика в два раза больше симметричного случая. Это ситуация, когда стоимость ошибки, приведшей к выдаче кредита будущему банкроту, в два раза больше дохода от возвращенного вовремя кредита такого же размера:
Протокол расчетов 4
Расчет критерия Йодена для симметричного случая
Протокол расчетов 5
Расчет критерия Йодена, когда стоимость пропущенного «плохого» заемщика в два раза меньше симметричного случая
threshold specificity sensitivity 0.7388889 0.8878143 0.7377049
threshold specificity sensitivity 0.5142857 0.9264990 0.6830601
38
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка
Что же означает на практике второй параметр в векторе весов? В нашем рассуждении за кадром остается ситуация, столь знако-
мая по формуле полной вероятности. Если случаи невозврата кре-дитов в основной популяции редки, то мы, неправильно выбрав порог отсечения, построим неверную модель, выявив огромное коли-чество ложно положительных случаев.
Вес, который позволяет компенсировать эту ситуацию, равен пропорции, с которой встречаются положительные случаи в гене-ральной совокупности.
Задаем частоту появления интересующего события в нашей выборке:> data.t <- table(data$default)
Назначаем вес для вычисленной частоты:> w <- as.numeric(data.t[2]/(data.t[1]+data.t[2]))
Рассчитываем критерий для ROC-кривой с учетом веса:> coords(roc.model, # модель ROC“best”, # вид критерияbest.method=“youden”, # способ расчета критерияbest.weights=c(1, w), # подставляем вычисленную долю невозвратов в популяцииret=c(“threshold”, “spec”, “sens”)) # какие параметры возвращать
Протокол расчетов 6
Расчет критерия Йодена, когда стоимость пропущенного «плохого» заемщика в два раза больше симметричного случая
Протокол расчетов 7
Расчет критерия Йодена с поправкой на реальную частоту дефолтов
threshold specificity sensitivity 0.8725490 0.6189555 0.8961749
threshold specificity sensitivity 0.5142857 0.9264990 0.6830601
> coords(roc.model,“best”, best.method=“youden”,best.weights=c(2, 0.5), # первый параметр увеличен вдвоеret=c(“threshold”, “spec”, “sens”))
Если случаи невозврата
кредитов в основной
популяции редки, то мы,
неправильно выбрав
порог отсечения,
построим неверную
модель, выявив огром-
ное количество ложно
положительных случаев.
39
www.reglament.net
критерий Йодена \ ROC-кривая \ вероятность дефолта
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
Выведем на ROC-кривой порог отсечения для симметричного случая:> plot(roc.model, # выводимая модель ROCprint.thres=“best”, # вид критерия для расчета оптимумаprint.thres.best.method=“youden”, # способ расчета критерияprint.thres.best.weights=c(1, 0.5), # веса способа расчетаcol=“green”) # цвет выводимой ROC
Дополнительно выведем на этой же ROC-кривой порог отсечения, когда стоимость пропущенного банкрота в два раза меньше симметричного случая:> plot(roc.model,print.thres=“best”,print.thres.best.method=“youden”,print.thres.best.weights=c(0.5, 0.5),col=“green”,add=TRUE) # график будет добавлен на предыдущий
Дополнительно выведем на этой же ROC-кривой порог отсечения, когда стоимость пропущенного банкрота в два раза больше симметричного случая:> plot(roc.model,print.thres=“best”,print.thres.best.method=“youden”,print.thres.best.weights=c(2, 0.5),col=“green”,add=TRUE) # график будет добавлен на предыдущий
Примечание: порог отсечения для симметричного случая — 0,739; порог отсечения, когда стои-
мость пропуска банкрота в два раза меньше симметричного случая, — 0,514; порог отсечения,
когда стоимость пропуска банкрота в два раза больше симметричного случая, — 0,873.
Рисунок 3
Пороги отсечения ROC-кривой
1,0
0,8
0,6
0,4
0,2
0
Sen
siti
vity
Specificity1 0,8 0,6 0,4 0,2 0
0,873 (0,6; 0,896)
0,739 (0,888; 0,738)0,514 (0,926; 0,683)
40
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка
Попробуем применить критерий Йодена, найденный для симмет-ричного случая и выбранный для реальной частоты обнаружения дефолтов в нашей выборке.
Строим таблицу классификации для реальной частоты дефолтов:> table(result[,1] < coords(roc.model,“best”,best.method=“youden”,best.weights=c(1, 0.5),ret=“threshold”),data[,9])
А теперь выведем на ROC-кривой порог отсечения, поправленный на частоту дефолтов, взятую из экспериментальной выборки:> plot(roc.model,print.thres=“best”,print.thres.best.method=“youden”,print.thres.best.weights=c(1, w),col=“green”)
Рисунок 4
ROC-кривая: порог отсечения, скорректированный на частоту дефолта (0,514)
Протокол расчетов 8
Таблица классификации для симметричного случая 0 1 FALSE 459 48 TRUE 58 135
1
0,8
0,6
0,4
0,2
0
Sen
siti
vity
Specificity1 0,8 0,6 0,4 0,2 0
0,514 (0,926, 0,683)
41
www.reglament.net
критерий Йодена \ ROC-кривая \ вероятность дефолта
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
Цифры 0 и 1 означают фактических «хороших» и «плохих» заем-щиков соответственно. FALSE и TRUE означают спрогнозированных «хороших» и «плохих» заемщиков соответственно.
Например, результаты классификации, приведенные в протоколе 8, интерпретируют следующим образом. Из 183 «плохих» заемщиков классификатор правильно выявил 135, а 48 «плохих» заемщиков оши-бочно отнесены к «хорошим». Поэтому чувствительность равна 135/183 = = 0,74, или 74%. Из 517 «хороших» заемщиков классификатор правильно выявил 459, а 58 «хороших» заемщиков ошибочно отнесены к «пло-хим». Поэтому специфичность равна 459/517 = 0,89, или 89%. Обратим внимание, что это соответствует значениям чувствительности и специфичности, рассчитанным для симметричного случая (протокол расчетов 4). Поэтому результаты классификации можно непосред-ственно выводить из значений чувствительности и специфичности.
Результаты классифика-
ции можно непосред-
ственно выводить из
значений чувствитель-
ности и специфичности.
Строим таблицу классификации для реальной частоты дефолтов:> table(result[,1] < coords(roc.model,“best”,best.method=“youden”,best.weights=c(1, w),ret=“threshold”),data[,9])
Как мы видим, первый вариант порога отсечения дает 106 убы-точных случаев (отказы «хорошим» заемщикам в выдаче кредитов и выдача кредитов «плохим» заемщикам). Второй вариант, учиты-вающий реальную частоту дефолтов в выборке, дает суммарно 96 случаев, принесших убыток. Воспользуемся вторым вариантом. Теперь нашу модель можно считать полностью рассмотренной.
Сохранение результатов прогнозаОсталось сохранить результаты прогноза в отдельный файл.
Полученный файл может быть прочитан и использован для анализа в других статистических пакетах. Например, для чтения файла в SPSS необходимо воспользоваться конструктором импорта текстовых фай-
Протокол расчетов 8
Таблица классификации для реальной частоты дефолтов 0 1 FALSE 479 58 TRUE 38 125
42
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка
лов. На шаге 1 необходимо выбрать параметры по умолчанию. На шаге 2 в поле «Переменные в файле» выбрать параметр «С разделителем». Также необходимо указать, что имена переменных находятся в пер-вой строке файла. На шаге 3 указываем, что первое наблюдение нахо-дится во 2-й строке (потому что ранее мы указали, что 1-я строка содержит имена переменных). На шаге 4 в поле «Разделитель» выби-раем параметры «Табуляция» и «Запятая». На шаге 5 задаем имена и корректный формат переменных. На шаге 6 записываем файл.
Расчет прогноза для новых клиентовДанные о 100 потенциальных заемщиках, по которым дефолт неиз-вестен, содержатся в учебном файле bankloan_new.csv1. Используя построенную модель, можно спрогнозировать риск дефолта по этим новым клиентам.
Зададим типы переменных для анализа:> prognoz$age <-as.numeric(prognoz$age)prognoz$ed <-as.factor(prognoz$ed)prognoz$employ <-as.numeric(prognoz$employ)prognoz$address <-as.numeric(prognoz$address)prognoz$income <-as.numeric(prognoz$income)prognoz$debtinc<-as.numeric(prognoz$debtinc)prognoz$creddebt<-as.numeric(prognoz$creddebt)prognoz$children<-as.numeric(prognoz$children)
Присвоим имя prognoz файлу bankloan_new.csv, чтобы начать работу с новыми данными в R:> prognoz <- read.csv2(“C:/data/bankloan_new.csv”)
Необходимо задать имя набора данных, содержащего результаты прогноза:> newdata<-data.frame(data, result=result)
Затем нужно записать результаты в отдельный файл, например, с расширением *.csv:> write.csv(newdata, “result.csv”)
1 http://www.sendspace.com/file/trxyg7.
Теперь необходимо указать тип переменных, которые будут исполь-зованы для анализа. Для количественных переменных нужно вос-пользоваться функцией as.numeric, а для категориальных перемен-ных — функцией as.factor.
43
www.reglament.net
критерий Йодена \ ROC-кривая \ вероятность дефолта
Оценка качества скоринговой модели, построенной с помощью метода деревьев решений
Теперь, используя построенную модель, получим прогноз по 100 по тен циальным клиентам.
Необходимо задать имя набора данных, содержащего результаты прогноза по новым клиентам:> newclients_prognoz<-data.frame(prognoz, result2=result2)
Затем нужно записать результаты по новым клиентам в отдельный файл, например, с расширением *.csv:> write.csv(newclients_prognoz, “newclients_prognoz.csv”)
Выведем прогноз модели по 100 новым клиентам:> predict(model2, prognoz)
Результату операции присвоим имя result2, чтобы можно было работать с вычисленными вероятностями по новым клиентам:> result2 <- predict(model2,prognoz)
Теперь осталось сохранить результаты прогноза по новым кли-ентам в отдельный файл.
ВыводыТаким образом, прогностическая способность модели оценивалась нами с помощью ROC-анализа. Для определения оптимального порога отсечения был использован критерий Йодена. Преимущество дан-ного критерия заключается в его гибкости. Он поддерживает веса, что позволяет задать различную стоимость неверной классификации «плохих» и «хороших» заемщиков и выбрать оптимальный баланс между чувствительностью модели — способностью определять «пло-хих» заемщиков и специфичностью модели — способностью опреде-лять «хороших» заемщиков.
44
Риск-менеджмент в кредитной организации № 3 (11) \ 2013
Анализ и оценка