В этом примере показано, как работать с данными потребительской (розничной) кредитной панели для визуализации наблюдаемых вероятностей дефолта (PD) на разных уровнях. Это также показывает аппроксимацию модели пропорциональных рисков Кокса (PH), также известной как регрессия Кокса, для предсказания PD. В сложение показано, как выполнить анализ стресс-тестирования и как смоделировать PD в течение жизни и значение ожидаемого кредитного убытка (ECL) в течение жизни.
Аналогичный пример, Стресс- Проверка вероятностей дефолта потребительского кредита с использованием Панели данных, следует тому же рабочему процессу, но использует логистическую регрессию вместо Cox PH. Основные различия в этих двух подходах заключаются в следующем:
Модель подгонки: Модель Cox PH имеет непараметрическую базовую скорость опасности, которая может совпадать с шаблонами в PDs гораздо более тесно, чем полностью параметрическая логистическая модель.
Экстраполяция после наблюдаемых возрастов в данных: Модель Cox PH, потому что она основана на верхней части непараметрической базовой ставки опасности, не может экстраполироваться на возраст кредита, который не наблюдается в наборе данных. Логистическая модель рассматривает возраст кредита как непрерывную переменную, и, следовательно, она может экстраполироваться, чтобы предсказать PD для возрастов, не наблюдаемых в наборе данных.
Ситуации с низкой вероятностью: Если для конкретного возраста PD является маленьким и в данных нет наблюдаемых значений по умолчанию, модель Cox PH предсказывает PD как нуль. Напротив, логистическая модель всегда дает ненулевые вероятности.
Начиная с некоторых визуализаций данных, в основном визуализация PD как функции возраста, которая в этом наборе данных является такой же, как и Years-on-Books (YOB). Поскольку Cox PH является моделью анализа выживания, в этом примере обсуждаются некоторые инструменты и концепции анализа выживания и используется эмпирическая совокупная функция распределения (ecdf
) функциональность для некоторых из этих расчетов и визуализаций.
Основной набор данных (data
) содержит следующие переменные:
ID
: Идентификатор кредита.
ScoreGroup
: Кредитный счет в начале кредита, дискретизированный в три группы: High Risk
, Medium Risk
, и Low Risk
.
YOB
: Годы по книгам.
Default
: Индикатор по умолчанию. Это переменная отклика.
Year
: Календарный год.
Существует также небольшой набор данных (dataMacro
) с макроэкономическими данными за соответствующие календарные годы:
Year
: Календарный год.
GDP
:: Рост валового внутреннего продукта (год за годом).
Market
: Возврат рынка (год за годом).
Переменные YOB
, Year
, GDP
, и Market
наблюдаются в конце соответствующего календарного года. Группа баллов является дискретизацией исходного кредитного счета, когда кредит начался. Значение 1
для Default
означает, что кредит по дефолту в соответствующем календарном году.
Существует также третий набор данных (dataMacroStress
) с исходным, неблагоприятным и серьезно неблагоприятным сценариями для макроэкономических переменных. Эта таблица используется для анализа стресс-тестирования.
Загрузите моделируемые данные.
load RetailCreditPanelData.mat
disp(head(data,10))
ID ScoreGroup YOB Default Year __ ___________ ___ _______ ____ 1 Low Risk 1 0 1997 1 Low Risk 2 0 1998 1 Low Risk 3 0 1999 1 Low Risk 4 0 2000 1 Low Risk 5 0 2001 1 Low Risk 6 0 2002 1 Low Risk 7 0 2003 1 Low Risk 8 0 2004 2 Medium Risk 1 0 1997 2 Medium Risk 2 0 1998
Предварительно обработайте данные панели, чтобы поместить ее в формат, ожидаемый некоторыми из инструментов анализа выживания.
% Use groupsummary to reduce data to one ID per row, and keep track of whether the loan defaulted or not dataSurvival = groupsummary(data,'ID','sum','Default'); disp(head(dataSurvival,10))
ID GroupCount sum_Default __ __________ ___________ 1 8 0 2 8 0 3 8 0 4 6 0 5 7 0 6 7 0 7 8 0 8 6 0 9 7 0 10 8 0
% Could also get years observed from YOB, though here we know YOB always % starts from 1 in the data, so the GroupCount equals the final YOB dataSurvival.Properties.VariableNames{2} = 'YearsObserved'; dataSurvival.Properties.VariableNames{3} = 'Default'; % If there is no default, it's a censored observation dataSurvival.Censored = ~dataSurvival.Default; disp(head(dataSurvival,10))
ID YearsObserved Default Censored __ _____________ _______ ________ 1 8 0 true 2 8 0 true 3 8 0 true 4 6 0 true 5 7 0 true 6 7 0 true 7 8 0 true 8 6 0 true 9 7 0 true 10 8 0 true
Основной переменной является количество времени, в течение которого каждый кредит наблюдался (YearsObserved
), которая является конечным значением Года по книгам (YOB
) переменная. Это количество лет до дефолта, или до конца периода наблюдения (восемь лет), или до тех пор, пока кредит не будет удален из выборки, например, из-за предоплаты. В этом наборе данных информация YOB совпадает с возрастом кредита, потому что все кредиты начинаются с YOB 1
. Для других наборов данных это может быть не так. В торговом портфеле YOB и возраст могут быть другими, потому что кредит, приобретенный на третьем году жизни, будет иметь возраст 3
, но значение YOB 1
.
Второй необходимой переменной является переменная цензуры (Censored
). Событие интереса является дефолтом в этом анализе. Если кредит наблюдается до дефолта, у нас есть полная информация о времени до дефолта, поэтому информация о жизни не цензурирована или завершена. В качестве альтернативы информация считается цензурированной или неполной, если в конце периода наблюдения кредит не имеет дефолта. Это может быть из-за того, что кредит был предоплачен, или из-за того, что кредит не был погашен к концу восьмилетнего периода наблюдения в выборке.
Добавьте к данным группу счета и информацию о винтаже. Значение этих переменных остается постоянным на протяжении всего срока действия кредита. Счет, заданная при возникновении, определяет группу счета, а год происхождения определяет винтаж или когорту.
% Can get ScoreGroup from YOB==1, since we know in this data set % YOB always starts at 1 and the ID's order is the same in data and dataSurvival dataSurvival.ScoreGroup = data.ScoreGroup(data.YOB==1); % Define vintages based on the year the loan started, we know all loans % in this data set start in year 1 of their life dataSurvival.Vintage = data.Year(data.YOB==1); disp(head(dataSurvival,10))
ID YearsObserved Default Censored ScoreGroup Vintage __ _____________ _______ ________ ___________ _______ 1 8 0 true Low Risk 1997 2 8 0 true Medium Risk 1997 3 8 0 true Medium Risk 1997 4 6 0 true Medium Risk 1999 5 7 0 true Medium Risk 1998 6 7 0 true Medium Risk 1998 7 8 0 true Medium Risk 1997 8 6 0 true Medium Risk 1999 9 7 0 true Low Risk 1998 10 8 0 true Low Risk 1997
Наконец, сравните количество строк в исходном наборе данных, в формате данных панели и агрегированном наборе данных в более традиционном формате выживания.
fprintf('Number of rows original data: %d\n',height(data));
Number of rows original data: 646724
fprintf('Number of rows survival data: %d\n',height(dataSurvival));
Number of rows survival data: 96820
Постройте график совокупной вероятности по умолчанию относительно YOB для всего портфеля (все группы счетов и винтажи) с помощью эмпирической совокупной функции распределения (ecdf
) функциональность.
ecdf(dataSurvival.YearsObserved,'Censoring',dataSurvival.Censored,'Bounds','on') title('Cumulative Default Probability, All Score Groups') xlabel('Years on Books')
Построение графика условных годичных ПД по YOB. Например, условный годичный PD для YOB из 3 является условным годичным PD для кредитов, которые находятся на третьем году жизни. В анализе выживания это называется дискретной частотой опасности, обозначаемой h. Чтобы вычислить h, получите выход совокупной функции опасности, обозначенный H, и преобразуйте его в функцию опасности h.
[H,x] = ecdf(dataSurvival.YearsObserved,'Censoring',dataSurvival.Censored,... 'Function','cumulative hazard'); % Because it is discrete time, simply take the diff of H to get the hazard h h = diff(H); x(1) = []; % In this example, the times observed (stored in variable x) do not change for % different score groups, or for training vs. test sets. For other data sets, % the x and h variables may need to be checked after every call to the ecdf function before % plotting or concatenating results (for example, if there are no defaults in a % particular year for the test data). plot(x,h,'*') grid on title('Conditional 1-Year PDs') ylabel('PD') xlabel('Years on Books')
Можно также вычислить эти вероятности непосредственно с помощью groupsummary
использование исходного формата данных панели. Для получения дополнительной информации смотрите сопутствующий пример Стресс-тестирование вероятностей дефолта потребительского кредита с использованием панельных данных. Или можно вычислить эти вероятности с помощью grpstats
использование исходного формата данных панели. Эти подходы дают одинаковые условные годичные ДП.
PDvsYOBByGroupsummary = groupsummary(data,'YOB','mean','Default'); PDvsYOBByGrpstats = grpstats(data.Default,data.YOB); PDvsYOB = table((1:8)',h,PDvsYOBByGroupsummary.mean_Default,PDvsYOBByGrpstats,... 'VariableNames',{'YOB','ECDF','Groupsummary','Grpstats'}); disp(PDvsYOB)
YOB ECDF Groupsummary Grpstats ___ _________ ____________ _________ 1 0.017507 0.017507 0.017507 2 0.012704 0.012704 0.012704 3 0.011168 0.011168 0.011168 4 0.010728 0.010728 0.010728 5 0.0085949 0.0085949 0.0085949 6 0.006413 0.006413 0.006413 7 0.0033231 0.0033231 0.0033231 8 0.0016272 0.0016272 0.0016272
Сегментируйте данные по счету группе, чтобы получить PD дезагрегированные по счету группам.
ScoreGroupLabels = categories(dataSurvival.ScoreGroup); NumScoreGroups = length(ScoreGroupLabels); hSG = zeros(length(h),NumScoreGroups); for ii=1:NumScoreGroups Ind = dataSurvival.ScoreGroup==ScoreGroupLabels{ii}; H = ecdf(dataSurvival.YearsObserved(Ind),'Censoring',dataSurvival.Censored(Ind)); hSG(:,ii) = diff(H); end plot(x,hSG,'*') grid on title('Conditional 1-Year PDs, By Score Group') xlabel('Years on Books') ylabel('PD') legend(ScoreGroupLabels)
Можно дезагрегировать ПД по винтажу и сегментировать данные аналогичным образом. Можно построить график этих ПД по YOB или по календарному году. Чтобы увидеть эти визуализации, смотрите Стресс- Проверку вероятностей дефолта потребительского кредита с использованием Панели Данных.
В этом разделе показано, как подогнать модель Cox PH без макроинформации. Для этого используется формат данных о выживании, и модель включает только независимые от времени предикторы, то есть информацию, которая остается постоянной в течение всего срока действия кредита. Только группа счета при возникновении кредитов используется как независимый от времени предиктор, но другие такие предикторы могут быть добавлены к модели (для примера, винтажная информация).
Регрессия пропорциональных рисков Кокса является семипараметрическим методом для корректировки оценок выживаемости, чтобы количественно определить эффект переменных. Метод представляет эффекты объясняющих переменных как умножитель общей функции исходной опасности, . Функция опасности является непараметрической частью функции регрессии пропорциональных рисков Кокса, в то время как влияние переменных предиктора является логлинейной регрессией. Эта модель Cox PH является
где:
являются переменными предиктора для i-го субъекта.
- коэффициент j-й переменной предиктора.
- скорость опасности в момент t для .
- функция базового уровня опасности.
Для получения дополнительной информации смотрите coxphfit
или модель пропорциональных рисков Кокса и содержащиеся в ней ссылки.
Базовая модель Cox PH принимает, что значения предиктора не изменяются в течение срока службы кредитов. В нашем примере это случай для группы баллов, потому что это счет, отданный заемщикам в начале кредита. Винтаж также является постоянным на протяжении всего срока действия кредита.
Модель может использовать зависящие от времени счета, например, если информация о кредитном счете обновлялась каждый год. В этом случае вы моделируете зависящий от времени предиктор в модели Cox PH, подобный тому, как макро-переменные добавляются к модели позже в разделе «Cox PH Model with Macro Эффектов».
Чтобы оценить подгонку модели, визуализируйте подгонку модели в выборке и вне выборки. Во-первых, разделите данные на подмножества обучения и проверки и подбирайте модель с помощью обучающих данных.
nIDs = height(dataSurvival); NumTraining = floor(0.6*nIDs); % Use 60% of data for training rng('default'); % Reset rng state, for reproducibility TrainIDInd = randsample(nIDs,NumTraining); TrainDataInd = ismember(dataSurvival.ID,TrainIDInd); TestDataInd = ~TrainDataInd; % ScoreGroup is categorical, convert to binary columns with dummyvar X = dummyvar(dataSurvival.ScoreGroup(TrainDataInd)); % Drop first column to avoid linear dependencies, % also known as the "dummy variable trap" X(:,1) = []; % Fit the Cox PH model [bCox,~,HCox] = coxphfit(X,... dataSurvival.YearsObserved(TrainDataInd),... 'Censoring',dataSurvival.Censored(TrainDataInd),... 'Baseline',0);
Третий выход coxphfit
функция является базовым совокупным коэффициентом опасности H. Этот совокупный коэффициент опасности может быть преобразован в коэффициент опасности h, как и прежде, за исключением дополнительного шага. Модель Cox PH принимает, что время наблюдения измеряется как непрерывная переменная. Здесь время измеряется дискретным способом, потому что время всегда является целым числом между 1
и 8
. The coxphfit
функция поддерживает способы обработки связей во временной переменной (см. 'Ties'
необязательный вход в coxphfit
). Из-за связей выход H имеет несколько строк с теми же значениями YOB, но его можно обработать, чтобы иметь только столько строк, сколько уникальных значений YOB, как показано здесь.
% Process baseline HCox to account for discrete time (remove time ties) HCoxDiscreteT = unique(HCox(:,1)); HCoxDiscreteH = grpstats(HCox(:,2),HCox(:,1),'max'); HCox = [HCoxDiscreteT HCoxDiscreteH]; % Convert baseline to h xCox = HCox(:,1); hCox = diff([0;HCox(:,2)]);
Прогнозируйте PD, то есть уровни опасности на основе модели подгонки. Потому что эта модель использует только начальную информацию о группе счетов, которая остается постоянной в течение всего срока действия кредита. Все ссуды с одной и той же начальной группой счетов имеют одинаковые прогнозируемые PD в течение жизни. Чтобы получить агрегированный прогнозируемый PD для портфеля, вычислите коэффициент опасности для каждой группы счетов. Затем возьмите взвешенные средние значения этих групп счета на основе доли кредитов в каждой группе счета в данных обучения.
Предсказанные PD сравниваются с наблюдаемыми PD в обучающих данных.
% Compute proportion of loans in each score group ScoreGroupFraction = countcats(dataSurvival.ScoreGroup(TrainDataInd)); ScoreGroupFraction = ScoreGroupFraction/sum(ScoreGroupFraction); % Baseline h is the hazard rate for 'High Risk', in the first column % Columns 2 and 3 have the 'Medium' and 'Low' risk respectively, % which are adjusted by their corresponding parametric term of the Cox model hPredictedByScore = zeros(length(hCox),NumScoreGroups); hPredictedByScore(:,1) = hCox; for ii=2:NumScoreGroups hPredictedByScore(:,ii) = hCox*exp(bCox(ii-1)); end hPredicted = hPredictedByScore*ScoreGroupFraction; % Get the ecdf of the training data HTrain = ecdf(dataSurvival.YearsObserved(TrainDataInd),... 'Censoring',dataSurvival.Censored(TrainDataInd),... 'Function','cumulative hazard'); hTrain = diff(HTrain); plot(x,hPredicted,'-o',x,hTrain,'*') xlabel('Years on Books') ylabel('PD') legend('Model','Training') title('Model Fit (Training Data)') grid on
Сравните предсказанные и наблюдаемые PD в тестовых данных.
ScoreGroupFraction = countcats(dataSurvival.ScoreGroup(TestDataInd)); ScoreGroupFraction = ScoreGroupFraction/sum(ScoreGroupFraction); hPredicted = hPredictedByScore*ScoreGroupFraction; % Get the ecdf of the training data HTest = ecdf(dataSurvival.YearsObserved(TestDataInd),... 'Censoring',dataSurvival.Censored(TestDataInd),... 'Function','cumulative hazard'); hTest = diff(HTest); plot(x,hPredicted,'-o',x,hTest,'*') xlabel('Years on Books') ylabel('PD') legend('Model','Test') title('Model Fit (Test Data)') grid on
Непараметрическая часть модели Cox PH позволяет ей тесно совпадать с шаблоном обучающих данных, даже используя только информацию о группе оценки в этой модели. Ошибки вне выборки (модель по сравнению с тестовыми данными) также малы.
Сложение макроинформации все еще важна, потому что и стресс- проверка, и прогнозы PD во время жизни требуют явной зависимости от макроинформации.
В этом разделе показано, как соответствовать модели Cox PH, включая макроинформацию, в частности, рост валового внутреннего продукта (ВВП) и рост фондового рынка. Значение переменных макроса изменяется каждый год, поэтому это зависящие от времени предикторы. Входные данные для функциональности Cox PH с зависящими от времени предикторами используют исходные данные панели с сложением макроинформации и временного интервала для каждой строки.
Расширение модели пропорциональных рисков Кокса для учета зависящих от времени переменных
где:
является значением переменных предиктора для i-го субъекта и j-го независимого от времени предиктора.
является значением переменных предиктора для i-го субъекта и k-го зависящего от времени предиктора в момент t.
- коэффициент j-й независимой от времени переменной предиктора.
- коэффициент k-й зависящей от времени переменной предиктора.
- скорость опасности в момент t для
- функция базового уровня опасности.
Для получения дополнительной информации смотрите coxphfit
или модель пропорциональных рисков Кокса и содержащиеся в ней ссылки.
Переменные макроса рассматриваются как зависящие от времени переменные. Если независимая от времени информация, такая как исходная группа счета, обеспечивает базовый уровень риска в течение срока действия кредита, разумно ожидать, что изменение макро- условия может увеличить или уменьшить риск вокруг этого базового уровня, и это изменение будет отличаться от одного года к следующему, если макро условия измениться. Например, годы с низким экономическим ростом должны сделать все кредиты более рискованными, независимо от их первоначального счета.
Для зависящего от времени анализа Cox PH используйте расширение исходного набора данных в качестве входных данных для зависящего от времени анализа.
Инструменты ожидают спецификации временных интервалов с соответствующими значениями предикторов. Для первого года временной интервал составляет от 0 до 1, для второго года временной интервал переходит от 1 до 2 и так далее. Поэтому область значений временных интервалов для каждой строки YOB-1 к YOB.
Независимые от времени переменные имеют постоянные значения на протяжении всей истории ссуд, как и информация о счете в исходных данных. Не нужно ничего менять для независимых от времени переменных.
Для зависящих от времени переменных значения изменяются с одного интервала на следующий. Мы добавляем переменные GDP и Market как зависящие от времени предикторы.
Инструментам также нужен флаг цензуры, который является отрицанием информации по умолчанию.
data.TimeInterval = [data.YOB-1 data.YOB]; data.GDP = dataMacro.GDP(data.Year-min(data.Year)+1); data.Market = dataMacro.Market(data.Year-min(data.Year)+1); data.Censored = ~data.Default; disp(head(data,10))
ID ScoreGroup YOB Default Year TimeInterval GDP Market Censored __ ___________ ___ _______ ____ ____________ _____ ______ ________ 1 Low Risk 1 0 1997 0 1 2.72 7.61 true 1 Low Risk 2 0 1998 1 2 3.57 26.24 true 1 Low Risk 3 0 1999 2 3 2.86 18.1 true 1 Low Risk 4 0 2000 3 4 2.43 3.19 true 1 Low Risk 5 0 2001 4 5 1.26 -10.51 true 1 Low Risk 6 0 2002 5 6 -0.59 -22.95 true 1 Low Risk 7 0 2003 6 7 0.63 2.78 true 1 Low Risk 8 0 2004 7 8 1.85 9.48 true 2 Medium Risk 1 0 1997 0 1 2.72 7.61 true 2 Medium Risk 2 0 1998 1 2 3.57 26.24 true
Подгонка зависящей от времени модели. Те же идентификаторы, что и прежде, относятся к подмножествам обучения или проверки, однако индексация отличается из-за различных форматов в данных.
TrainDataIndTD = ismember(data.ID,TrainIDInd); TestDataIndTD = ~TrainDataIndTD; XTD = dummyvar(data.ScoreGroup(TrainDataIndTD)); XTD(:,1) = []; [bCoxTD,~,HCoxTD] = ... coxphfit([XTD data.GDP(TrainDataIndTD) data.Market(TrainDataIndTD)],... data.TimeInterval(TrainDataIndTD,:),... 'Censoring',data.Censored(TrainDataIndTD),... 'Baseline',0); % Process baseline HCoxTD to account for discrete time (remove time ties) HCoxTDDiscreteT = unique(HCoxTD(:,1)); HCoxTDDiscreteH = grpstats(HCoxTD(:,2),HCoxTD(:,1),'max'); HCoxTD = [HCoxTDDiscreteT HCoxTDDiscreteH]; % Convert cumulative baseline to hCoxTD xCoxTD = HCoxTD(:,1); hCoxTD = diff([0;HCoxTD(:,2)]);
Чтобы визуализировать подгонку в выборке, вычислите предсказанную строку PDs по строкам. Настройте матрицу предиктора, как при подгонке модели, и затем примените формулу Cox PH.
Макрокоманда эффектов помочь модели соответствовать наблюдаемым скоростям по умолчанию еще ближе, а соответствие обучающим данным почти похоже на интерполяцию для макромодели.
% Set up predictor matrix XPredict = [dummyvar(data.ScoreGroup(TrainDataIndTD)), data.GDP(TrainDataIndTD), data.Market(TrainDataIndTD)]; XPredict(:,1) = []; % Predict at row level hPredictedTD = hCoxTD(data.YOB(TrainDataIndTD)).*exp(XPredict*bCoxTD); % Take the average of the predicted hazard rates at each time point (YOB) hPredictedTD = grpstats(hPredictedTD,data.YOB(TrainDataIndTD)); plot(x,hPredictedTD,'-o',x,hTrain,'*') xlabel('Years on Books') ylabel('PD') legend('Model','Training') title('Macro Model Fit (Training Data)') grid on
Визуализируйте выходную подгонку.
% Set up predictor matrix XPredict = [dummyvar(data.ScoreGroup(TestDataIndTD)), data.GDP(TestDataIndTD), data.Market(TestDataIndTD)]; XPredict(:,1) = []; % Predict at row level hPredictedTD = hCoxTD(data.YOB(TestDataIndTD)).*exp(XPredict*bCoxTD); % Take the average of the predicted hazard rates at each time point (YOB) hPredictedTD = grpstats(hPredictedTD,data.YOB(TestDataIndTD)); plot(x,hPredictedTD,'-o',x,hTest,'*') xlabel('Years on Books') ylabel('PD') legend('Model','Test') title('Macro Model Fit (Test Data)') grid on
Чтобы визуализировать в выборке и вне выборки на уровне группы счетов, выполните те же операции после сегментации данных по группе счетов.
В этом разделе показов, как выполнить анализ проверки напряжения PD с помощью макро- модель Cox PH.
Предположим, что следующие сценарии стресса для макроэкономических переменных, предоставленных, например, регулятором.
disp(dataMacroStress)
GDP Market _____ ______ Baseline 2.27 15.02 Adverse 1.31 4.56 Severe -0.22 -5.64
Коэффициент опасности, который задает PD по YOB, прогнозируется для каждой группы и каждого сценария макроса. Этот код предсказывает PD для каждой группы счетов и каждого сценария макроса.
Для визуализации каждого сценария макроса возьмите среднее значение по группам счетов, чтобы агрегировать в один PD по YOB. Рисунок показывает предсказанный эффект неблагоприятного и сильно неблагоприятного макро- условия на среднем PD для каждого YOB.
ScenarioLabels = dataMacroStress.Properties.RowNames; NumScenarios = length(ScenarioLabels); PDScenarios = zeros(length(x),NumScenarios); for ii=1:NumScoreGroups Score = ScoreGroupLabels{ii}; XPredictScore = ismember(ScoreGroupLabels(2:end)',Score); PDScenariosGroup = zeros(length(x),length(ScenarioLabels)); for jj=1:NumScenarios Scenario = ScenarioLabels{jj}; XPredictST = [XPredictScore dataMacroStress.GDP(Scenario) dataMacroStress.Market(Scenario)]; hPredictedST = hCoxTD*exp(XPredictST*bCoxTD); PDScenariosGroup(:,jj) = hPredictedST; end PDScenarios = PDScenarios + PDScenariosGroup/NumScoreGroups; end figure; bar(x,PDScenarios) title('Stress Test, Probability of Default') xlabel('Years on Books') ylabel('PD') legend('Baseline','Adverse','Severe') grid on
В этом разделе показов, как вычислить PD в течение срока службы с помощью макроса Cox PH модели и как вычислить ожидаемые кредитные потери (ECL) в течение срока службы.
Для пожизненного моделирования модель PD одинаковая, но она используется по-разному. Вам нужны предсказанные PD не только на один период вперед, но и на каждый год в течение всего срока действия каждого конкретного кредита. Это означает, что вам также нужны макросценарии на протяжении всего срока действия ссуд. Этот раздел настраивает альтернативные долгосрочные сценарии макросов, вычисляет PD в течение жизни в каждом сценарии и соответствующие 1-летние PD, предельные PD и вероятности выживания. Жизненный и предельный PD визуализируются для каждого года в каждом сценарии макроса. Затем ECL вычисляется для каждого сценария и взвешенного среднего значения срока службы ECL.
Для конкретизации в этом разделе рассматривается восьмилетний кредит в начале третьего года и прогнозируется 1-летний ПД от 3 до 8 лет жизни этого кредита. В этом разделе также вычисляется вероятность выживания за оставшийся срок кредита. Связь между вероятностью выживания и 1-летние ПД или показатели опасности , иногда также называемые прямыми PD, это:
Для примера смотрите метод Каплана-Мейера.
Lifetime PD (LPD) является совокупным PD за время действия кредита, заданным дополнением вероятности выживания:
Наконец, другое количество интереса является Маргинальным PD (MPD), которое является увеличением PD во время жизни между двумя последовательными периодами:
Из этого следует, что маргинальная БП также является снижением вероятности выживания между последовательными периодами, а также частотой опасности, умноженной на вероятность выживания:
Укажите три макроэкономических сценария, один базовый прогноз и два простых сдвига на 20% выше, или на 20% ниже значения для базового роста, которые называются «более быстрый рост» и «более медленный рост», соответственно. Сценарии в этом примере и соответствующие вероятности являются простыми сценариями только для рисунка целей. Более тщательный набор сценариев может быть построен с более мощными моделями с помощью Econometrics Toolbox™ или Statistics and Machine Learning Toolbox™; см., например, Моделирование экономики США (Econometrics Toolbox). Автоматизированные методы обычно могут моделировать большое количество сценариев. На практике требуется лишь небольшое количество сценариев. Эти сценарии и соответствующие вероятности выбираются в сочетании с количественными инструментами и экспертной оценкой.
CurrentAge = 3; % currently starting third year of loan Maturity = 8; % loan ends at end of year 8 ScoreGroup = 'High Risk'; % High risk YOBLifetime = (CurrentAge:Maturity)'; NumYearsRemaining = length(YOBLifetime); tLifetime = (dataMacro.Year(end)+1:dataMacro.Year(end)+NumYearsRemaining)'; tLifetime0 = (dataMacro.Year(end):dataMacro.Year(end)+NumYearsRemaining)'; XPredictScore = ismember(ScoreGroupLabels(2:end)',ScoreGroup); XPredictScore = repmat(XPredictScore,NumYearsRemaining,1); GDPPredict = [2.3; 2.2; 2.1; 2.0; 1.9; 1.8]; GDPPredict = [0.8*GDPPredict GDPPredict 1.2*GDPPredict]; MarketPredict = [15; 13; 11; 9; 7; 5]; MarketPredict = [0.8*MarketPredict MarketPredict 1.2*MarketPredict]; ScenLabels = ["Slower growth" "Baseline" "Faster growth"]; NumMacroScen = size(GDPPredict,2); % Scenario probabilities, used for the computation of lifetime ECL PScenario = [0.2; 0.5; 0.3]; hPredict = zeros(size(GDPPredict)); for ii = 1:NumMacroScen XPredictLifetime = [XPredictScore GDPPredict(:,ii) MarketPredict(:,ii)]; hPredict(:,ii) = hCoxTD(YOBLifetime).*exp(XPredictLifetime*bCoxTD); end survivalLifetime = [ones(1,NumMacroScen); cumprod(1-hPredict)]; PDLifetime = 1-survivalLifetime; PDMarginal = diff(PDLifetime); figure; subplot(2,1,1) plot(tLifetime0,PDLifetime) xticks(tLifetime0) grid on xlabel('Year') ylabel('Lifetime PD') title('Lifetime PD By Scenario') legend(ScenLabels,'Location','best') subplot(2,1,2) bar(tLifetime,PDMarginal) grid on xlabel('Year') ylabel('Marginal PD') title('Marginal PD By Scenario') legend(ScenLabels)
Эти PD продолжительности жизни по сценарию являются одним из входов для расчета ожидаемых кредитных потерь (ECL) в течение срока службы, который также требует значений срока службы для дефолта по потерям (LGD) и риска по дефолту (EAD) для каждого сценария и вероятностей сценария. Для простоты в этом примере приняты постоянные значения LGD и EAD, но эти параметры могут варьироваться в зависимости от сценария и периода времени, когда используются модели LGD и EAD.
Для расчета пожизненной ECL также требуется Эффективная процентная ставка (EIR) для целей дисконтирования. В этом примере коэффициенты дисконтирования вычисляются в конце периодов времени, но могут использоваться другие периоды дисконтирования, например, средняя точка между периодами времени (то есть, суммы дисконтирования первого года с 6-месячным коэффициентом дисконтирования; дисконтировать суммы второго года с 1,5-летним дисконтным коэффициентом и так далее).
С этими входами Ожидаемый кредитный убыток на момент t для сценария s определяется как:
где t обозначает временной период, s обозначает сценарий, и .
Для каждого сценария ECL в течение жизни вычисляется путем добавления ECL по времени от первого периода времени в анализе до ожидаемого срока службы продукта, обозначенного T, который в этом примере составляет пять лет (простой кредит с пятью годами до погашения):
Наконец, вычислите взвешенное среднее значение из этих ожидаемых кредитных убытков во всех сценариях, чтобы получить одно значение ECL в течение жизни, где обозначает вероятности сценария:
LGD = 0.55; % Loss Given Default EAD = 100; % Exposure at Default EIR = 0.045; % Effective Interest Rate DiscTimes = tLifetime-tLifetime0(1); DiscFactors = 1./(1+EIR).^DiscTimes; ECL_t_s = (PDMarginal*LGD*EAD).*DiscFactors; % ECL by year and scenario ECL_s = sum(ECL_t_s); % ECL total by scenario ECL = ECL_s*PScenario; % ECL weighted average over all scenarios % Arrange yearly ECL's for display in table format % Append ECL total per scenario, and scenario probabilities ECL_Disp = array2table([ECL_t_s; ECL_s; PScenario']); ECL_Disp.Properties.VariableNames = strcat("Scenario_",string(1:NumMacroScen)'); ECL_Disp.Properties.RowNames = [strcat("ECL_",string(tLifetime),"_s"); "ECL_total_s"; "Probability_s"]; disp(ECL_Disp)
Scenario_1 Scenario_2 Scenario_3 __________ __________ __________ ECL_2005_s 0.94549 0.8921 0.84173 ECL_2006_s 0.71543 0.6789 0.64419 ECL_2007_s 0.53884 0.51412 0.49048 ECL_2008_s 0.40169 0.38527 0.36947 ECL_2009_s 0.20849 0.20098 0.19372 ECL_2010_s 0.12339 0.11952 0.11576 ECL_total_s 2.9333 2.7909 2.6554 Probability_s 0.2 0.5 0.3
fprintf('Lifetime ECL: %g\n',ECL)
Lifetime ECL: 2.77872
Когда LGD и EAD не зависят от сценариев (даже если они изменяются со временем), средневзвешенное среднее значение кривых PD во время жизни может быть принято, чтобы получить одну, среднюю кривую PD во время жизни.
PDLifetimeWeightedAvg = PDLifetime*PScenario; ECLByWeightedPD = sum(diff(PDLifetimeWeightedAvg)*LGD*EAD.*DiscFactors); fprintf('Lifetime ECL, using weighted lifetime PD: %g, same result because of constant LGD and EAD.\n',... ECLByWeightedPD)
Lifetime ECL, using weighted lifetime PD: 2.77872, same result because of constant LGD and EAD.
Однако, когда значения LGD и EAD изменяются вместе со сценариями, необходимо сначала вычислить значения ECL на уровне сценария, а затем найти взвешенные средние значения значений ECL.
В этом примере показано, как подогнать модель Cox PH для PD, как выполнить проверку напряжений PD и как вычислить PD и ECL во время жизни.
Аналогичный пример, Стресс- Проверка вероятностей дефолта потребительского кредита с использованием Панели данных, следует тому же рабочему процессу, но использует логистическую регрессию, вместо регрессии Кокса. Расчеты PD и ECL в конце этого примера могут быть выполнены также с логистической моделью с некоторыми адаптациями к коду.
Можно изменить рабочий процесс, представленный в этих двух примерах, чтобы использовать другие формулировки модели. Например, можно подогнать логистическую модель, которая рассматривает возраст как категориальную (дискретную временную) переменную. В этом случае модели PD будут более тесно соответствовать наблюдаемым PD, но можно будет потерять экстраполяционные возможности модели. Более того, вместо логистической регрессии другие обобщенные линейные модели (GLM), поддерживаемые fitglm
могут также использоваться с незначительными изменениями в коде, например, пробитные модели или дополнительные логарифмические модели. Поскольку все эти модели явно включают возраст кредита и макроинформацию в модель, они могут использоваться для стресс- проверки и пожизненного анализа PD и ECL.
confidenceBands
| creditDefaultCopula
| getScenarios
| portfolioRisk
| riskContribution
| simulate