Сравнение вероятности значения по умолчанию Используя модели и момента времени через цикл

В этом примере показано, как работать с данными о панели потребительского кредита, чтобы создать через цикл (TTC) и модели момента времени (PIT) и сравнить их соответствующие вероятности значения по умолчанию (PD).

PD должника является основным параметром риска в анализе кредитного риска. PD должника зависит от факторов риска для конкретного заказчика, а также макроэкономических факторов риска. Поскольку они включают макроэкономические условия по-другому, модели TTC и PIT производят различные оценки PD.

Мера по кредитному риску TTC, в основном, отражает тренд кредитного риска клиента за длительный срок. Сглаживаются переходные, краткосрочные изменения в кредитном риске, которые, вероятно, будут обращены с течением времени. Преобладающими функциями мер по кредитному риску TTC является своя высокая степень устойчивости по циклу кредита и гладкости изменения в зависимости от времени.

Мера по кредитному риску в области ЯМЫ использует всю доступную и уместную информацию с данной даты, чтобы оценить PD клиента за данный период времени. Информационный набор включает не только ожидания о тренде кредитного риска клиента за длительный срок, но также и географический, макроэкономический, и трендах макрокредита.

Ранее согласно Базелю II правил, регуляторы призвали к использованию ФУНТОВ TTC, потери, данные значение по умолчанию (LGDs) и воздействия в значении по умолчанию (ИДЗ). Однако с к новому IFRS9 и предложенным стандартам бухгалтерского учета CECL, регуляторы теперь требуют, чтобы учреждения использовали проекции PIT ФУНТОВ, LGDs и ИДЗА. Путем составления текущего состояния цикла кредита меры PIT тесно отслеживают изменения значения по умолчанию и уровней потерь в зависимости от времени.

Загрузите данные о панели

Основной набор данных в этом примере (data) содержит следующие переменные:

  • ID — Идентификатор ссуды.

  • ScoreGroup — Кредитный рейтинг в начале ссуды, дискретизированной в три группы: High Risk, Medium Risk, и Low Risk.

  • YOB — Годы на книгах.

  • Default — Индикатор по умолчанию. Это - переменная отклика.

  • Year — Календарный год.

Данные также включают небольшой набор данных (dataMacro) с макроэкономическими данными в течение соответствующих календарных лет:

  • Year — Календарный год.

  • GDP — Рост валового внутреннего продукта (год за год).

  • Market — Рынок возвращается (год за год).

Переменные YOBгод, GDP, и Market наблюдаются в конце соответствующего календарного года. ScoreGroup дискретизация исходного кредитного рейтинга когда запущенная ссуда. Значение 1 для Default средние значения, что ссуда приняла значение по умолчанию в соответствующий календарный год.

Этот пример использует симулированные данные, но можно применить тот же подход к действительным наборам данных.

Загрузите данные и просмотрите первые 10 строк таблицы. Данные о панели сложены, и наблюдения для того же ID хранятся в непрерывных строках, составляя высокую, тонкую таблицу. Панель является несбалансированной, потому что не все идентификаторы имеют то же количество наблюдений.

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
nRows = height(data);
UniqueIDs = unique(data.ID);
nIDs = length(UniqueIDs);
fprintf('Total number of IDs: %d\n',nIDs)
Total number of IDs: 96820
fprintf('Total number of rows: %d\n',nRows)
Total number of rows: 646724

Уровни по умолчанию к году

Используйте Year как сгруппированная переменная, чтобы вычислить наблюдаемый уровень по умолчанию в течение каждого года. Используйте groupsummary функция, чтобы вычислить среднее значение Default переменная, группирующаяся Year переменная. Постройте результаты на графике рассеивания, который показывает, что уровень по умолчанию понижается, когда годы увеличиваются.

DefaultPerYear = groupsummary(data,'Year','mean','Default');
NumYears = height(DefaultPerYear);
disp(DefaultPerYear)
    Year    GroupCount    mean_Default
    ____    __________    ____________

    1997      35214         0.018629  
    1998      66716         0.013355  
    1999      94639         0.012733  
    2000      92891         0.011379  
    2001      91140         0.010742  
    2002      89847         0.010295  
    2003      88449        0.0056417  
    2004      87828        0.0032905  
subplot(2,1,1)
scatter(DefaultPerYear.Year, DefaultPerYear.mean_Default*100,'*');
grid on
xlabel('Year')
ylabel('Default Rate (%)')
title('Default Rate per Year')
% Get IDs of the 1997, 1998, and 1999 cohorts
IDs1997 = data.ID(data.YOB==1&data.Year==1997);
IDs1998 = data.ID(data.YOB==1&data.Year==1998);
IDs1999 = data.ID(data.YOB==1&data.Year==1999);
% Get default rates for each cohort separately
ObsDefRate1997 = groupsummary(data(ismember(data.ID,IDs1997),:),...
    'YOB','mean','Default');

ObsDefRate1998 = groupsummary(data(ismember(data.ID,IDs1998),:),...
    'YOB','mean','Default');

ObsDefRate1999 = groupsummary(data(ismember(data.ID,IDs1999),:),...
    'YOB','mean','Default');
% Plot against the calendar year
Year = unique(data.Year);
subplot(2,1,2)
plot(Year,ObsDefRate1997.mean_Default*100,'-*')
hold on
plot(Year(2:end),ObsDefRate1998.mean_Default*100,'-*')
plot(Year(3:end),ObsDefRate1999.mean_Default*100,'-*')
hold off
title('Default Rate vs. Calendar Year')
xlabel('Calendar Year')
ylabel('Default Rate (%)')
legend('Cohort 97','Cohort 98','Cohort 99')
grid on

График показывает, что уровень по умолчанию уменьшается в зависимости от времени. Заметьте в графике что кредиты, запускающиеся в годах 1997, 1998, и 1 999 форм три когорты. Никакая ссуда в данных о панели не запускается после 1999. Это изображено более подробно в разделе "Years on Books Versus Calendar Years" примера на Стресс-тестировании Вероятностей Значения по умолчанию Потребительского кредита Используя Данные о Панели. Уменьшающийся тренд в этом графике объяснен тем, что существует только три когорты в данных и что шаблон для каждой когорты уменьшается.

Модель TTC Используя ScoreGroup и годы на книгах

Модели TTC в основном незатронуты экономическими условиями. Первая модель TTC в этом примере использует только ScoreGroup и YOB как предикторы уровня по умолчанию.

Сгенерируйте обучение и тестирующий наборы данных путем разделения существующих данных в обучение и тестирования наборов данных, которые используются в создании модели и валидации, соответственно.

NumTraining = floor(0.6*nIDs);

rng('default');
TrainIDInd = randsample(nIDs,NumTraining);
TrainDataInd = ismember(data.ID,UniqueIDs(TrainIDInd));
TestDataInd = ~TrainDataInd;

Используйте fitglm функция, чтобы подбирать логистическую модель.

TTCModel = fitglm(data(TrainDataInd,:),...
    'Default ~ 1 + ScoreGroup + YOB',...
    'Distribution','binomial');
disp(TTCModel)
Generalized linear regression model:
    logit(Default) ~ 1 + ScoreGroup + YOB
    Distribution = Binomial

Estimated Coefficients:
                              Estimate       SE        tStat       pValue   
                              ________    ________    _______    ___________

    (Intercept)                -3.2453    0.033768    -96.106              0
    ScoreGroup_Medium Risk     -0.7058    0.037103    -19.023     1.1014e-80
    ScoreGroup_Low Risk        -1.2893    0.045635    -28.253    1.3076e-175
    YOB                       -0.22693    0.008437    -26.897    2.3578e-159


388018 observations, 388014 error degrees of freedom
Dispersion: 1
Chi^2-statistic vs. constant model: 1.83e+03, p-value = 0

Предскажите PD для обучения и тестирующий наборы данных с помощью predict.

data.TTCPD = zeros(height(data),1);

% Predict in-sample
data.TTCPD(TrainDataInd) = predict(TTCModel,data(TrainDataInd,:));
% Predict out-of-sample
data.TTCPD(TestDataInd) = predict(TTCModel,data(TestDataInd,:));

Визуализируйте подходящую и подгонку из выборки в выборке.

PredTTCPDTrainYear = groupsummary(data(TrainDataInd,:),'Year','mean',...
    {'Default','TTCPD'});
f = figure;
subplot(2,1,1)
scatter(PredTTCPDTrainYear.Year,PredTTCPDTrainYear.mean_Default*100,'*');
hold on
plot(PredTTCPDTrainYear.Year,PredTTCPDTrainYear.mean_TTCPD*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Training Data)')
grid on
PredTTCPDTestYear = groupsummary(data(TestDataInd,:),'Year','mean',...
    {'Default','TTCPD'});

subplot(2,1,2)
scatter(PredTTCPDTestYear.Year,PredTTCPDTestYear.mean_Default*100,'*');
hold on
plot(PredTTCPDTestYear.Year,PredTTCPDTestYear.mean_TTCPD*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Testing Data)')
grid on

Модель PIT Используя ScoreGroup, Годы на книгах, GDP и рынке возвращаются

Модели PIT меняются в зависимости от экономического цикла. Модель PIT в этом примере использует ScoreGroup, YOB, GDP, и Market как предикторы уровня по умолчанию. Используйте fitglm функция, чтобы подбирать логистическую модель.

% Add the GDP and Market returns columns to the original data

data = join(data, dataMacro);
disp(head(data,10))
    ID    ScoreGroup     YOB    Default    Year      TTCPD       GDP     Market
    __    ___________    ___    _______    ____    _________    _____    ______

    1     Low Risk        1        0       1997    0.0084797     2.72      7.61
    1     Low Risk        2        0       1998    0.0067697     3.57     26.24
    1     Low Risk        3        0       1999    0.0054027     2.86      18.1
    1     Low Risk        4        0       2000    0.0043105     2.43      3.19
    1     Low Risk        5        0       2001    0.0034384     1.26    -10.51
    1     Low Risk        6        0       2002    0.0027422    -0.59    -22.95
    1     Low Risk        7        0       2003    0.0021867     0.63      2.78
    1     Low Risk        8        0       2004    0.0017435     1.85      9.48
    2     Medium Risk     1        0       1997     0.015097     2.72      7.61
    2     Medium Risk     2        0       1998     0.012069     3.57     26.24
PITModel = fitglm(data(TrainDataInd,:),...
   'Default ~ 1 + ScoreGroup + YOB + GDP + Market',...
   'Distribution','binomial');
disp(PITModel)
Generalized linear regression model:
    logit(Default) ~ 1 + ScoreGroup + YOB + GDP + Market
    Distribution = Binomial

Estimated Coefficients:
                               Estimate        SE         tStat       pValue   
                              __________    _________    _______    ___________

    (Intercept)                   -2.667      0.10146    -26.287    2.6919e-152
    ScoreGroup_Medium Risk      -0.70751     0.037108    -19.066     4.8223e-81
    ScoreGroup_Low Risk          -1.2895     0.045639    -28.253    1.2892e-175
    YOB                         -0.32082     0.013636    -23.528    2.0867e-122
    GDP                         -0.12295     0.039725     -3.095      0.0019681
    Market                    -0.0071812    0.0028298    -2.5377       0.011159


388018 observations, 388012 error degrees of freedom
Dispersion: 1
Chi^2-statistic vs. constant model: 1.97e+03, p-value = 0

Предскажите PD для обучения и тестирующий наборы данных с помощью predict.

data.PITPD = zeros(height(data),1);

% Predict in-sample
data.PITPD(TrainDataInd) = predict(PITModel,data(TrainDataInd,:));
% Predict out-of-sample
data.PITPD(TestDataInd) = predict(PITModel,data(TestDataInd,:));

Визуализируйте подходящую и подгонку из выборки в выборке.

PredPITPDTrainYear = groupsummary(data(TrainDataInd,:),'Year','mean',...
    {'Default','PITPD'});

figure;
subplot(2,1,1)
scatter(PredPITPDTrainYear.Year,PredPITPDTrainYear.mean_Default*100,'*');
hold on
plot(PredPITPDTrainYear.Year,PredPITPDTrainYear.mean_PITPD*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Training Data)')
grid on
PredPITPDTestYear = groupsummary(data(TestDataInd,:),'Year','mean',...
    {'Default','PITPD'});

subplot(2,1,2)
scatter(PredPITPDTestYear.Year,PredPITPDTestYear.mean_Default*100,'*');
hold on
plot(PredPITPDTestYear.Year,PredPITPDTestYear.mean_PITPD*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Testing Data)')
grid on

В модели PIT, как ожидалось, предсказания совпадают с наблюдаемыми уровнями по умолчанию более тесно, чем в модели TTC. Несмотря на то, что этот пример использует симулированные данные, качественно, тот же тип улучшения модели ожидается при перемещении от TTC до моделей PIT для данных о реальном мире, несмотря на то, что полная ошибка может быть больше, чем в этом примере. Подгонка модели PIT обычно лучше, чем подгонка модели TTC и предсказания обычно совпадают с наблюдаемыми уровнями.

Вычислите PD TTC Используя модель PIT

Другой подход для вычисления ФУНТОВ TTC должен использовать модель PIT и затем заменить GDP и Market возвращается с соответствующими средними значениями. В этом подходе вы используете средние значения по целому экономическому циклу (или еще более длинный период) так, чтобы только базовые экономические условия влияли на модель, и любая изменчивость в уровнях по умолчанию происходит из-за других факторов риска. Можно также ввести предсказанные базовые значения для экономики, которые отличаются от среднего значения, наблюдаемого для нового экономического цикла. Например, использование медианы вместо среднего значения уменьшает ошибку.

Можно также использовать этот подход вычисления ФУНТОВ TTC при помощи модели PIT как инструмент для анализа сценариев, однако; это не может быть сделано в первой версии модели TTC. Добавленное преимущество этого подхода состоит в том, что можно использовать одну модель и в TTC и в предсказаниях PIT. Это означает, что необходимо подтвердить и обеспечить только одну модель.

% Modify the data to replace the GDP and Market returns with the corresponding average values
data.GDP(:) = median(data.GDP);
data.Market = repmat(mean(data.Market), height(data), 1);
disp(head(data,10));
    ID    ScoreGroup     YOB    Default    Year      TTCPD      GDP     Market      PITPD  
    __    ___________    ___    _______    ____    _________    ____    ______    _________

    1     Low Risk        1        0       1997    0.0084797    1.85    3.2263    0.0093187
    1     Low Risk        2        0       1998    0.0067697    1.85    3.2263     0.005349
    1     Low Risk        3        0       1999    0.0054027    1.85    3.2263    0.0044938
    1     Low Risk        4        0       2000    0.0043105    1.85    3.2263    0.0038285
    1     Low Risk        5        0       2001    0.0034384    1.85    3.2263    0.0035402
    1     Low Risk        6        0       2002    0.0027422    1.85    3.2263    0.0035259
    1     Low Risk        7        0       2003    0.0021867    1.85    3.2263    0.0018336
    1     Low Risk        8        0       2004    0.0017435    1.85    3.2263    0.0010921
    2     Medium Risk     1        0       1997     0.015097    1.85    3.2263     0.016554
    2     Medium Risk     2        0       1998     0.012069    1.85    3.2263    0.0095319

Предскажите PD для обучения и тестирующий наборы данных с помощью predict.

data.TTCPD2 = zeros(height(data),1);

% Predict in-sample
data.TTCPD2(TrainDataInd) = predict(PITModel,data(TrainDataInd,:));
% Predict out-of-sample
data.TTCPD2(TestDataInd) = predict(PITModel,data(TestDataInd,:));

Визуализируйте подходящую и подгонку из выборки в выборке.

PredTTCPD2TrainYear = groupsummary(data(TrainDataInd,:),'Year','mean',...
    {'Default','TTCPD2'});

figure;
subplot(2,1,1)
scatter(PredTTCPD2TrainYear.Year,PredTTCPD2TrainYear.mean_Default*100,'*');
hold on
plot(PredTTCPD2TrainYear.Year,PredTTCPD2TrainYear.mean_TTCPD2*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Training Data)')
grid on
PredTTCPD2TestYear = groupsummary(data(TestDataInd,:),'Year','mean',...
    {'Default','TTCPD2'});

subplot(2,1,2)
scatter(PredTTCPD2TestYear.Year,PredTTCPD2TestYear.mean_Default*100,'*');
hold on
plot(PredTTCPD2TestYear.Year,PredTTCPD2TestYear.mean_TTCPD2*100);
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('Observed','Predicted')
title('Model Fit (Testing Data)')
grid on

Сравните модели

Создайте итоговый график сравнить эти три модели и их ФУНТЫ.

figure
scatter(PredPITPDTestYear.Year,PredPITPDTestYear.mean_Default*100, '*')
hold on
plot(PredTTCPDTestYear.Year,PredTTCPDTestYear.mean_TTCPD*100, 'Marker','o')
plot(PredPITPDTestYear.Year,PredPITPDTestYear.mean_PITPD*100, 'Marker','square')
plot(PredTTCPD2TestYear.Year,PredTTCPD2TestYear.mean_TTCPD2*100, 'Marker','diamond')
hold off
xlabel('Year')
ylabel('Default Rate (%)')
legend('default time','PD TTC','PD PIT','PD TTC 2')
title('PIT PDs vs. TTC PDs')
grid on

Этот график иллюстрирует, что модель PD PIT имеет лучшую подгонку, модель PD TTC имеет почти лучшую подгонку, и модель PD TTC 2 имеет третью лучшую подгонку.

Как мера качества, сравните среднеквадратическую ошибку ФУНТОВ модели PIT и TTC к наблюдаемым временам по умолчанию.

TTCRMSError = sqrt(mean((PredPITPDTestYear.mean_Default - PredTTCPDTestYear.mean_TTCPD).^2));
PITRMSError = sqrt(mean((PredPITPDTestYear.mean_Default - PredPITPDTestYear.mean_PITPD).^2));
TTC2RMSError = sqrt(mean((PredPITPDTestYear.mean_Default - PredTTCPD2TestYear.mean_TTCPD2).^2));
TTCMaxError = max(abs(PredPITPDTestYear.mean_Default - PredTTCPDTestYear.mean_TTCPD));
PITMaxError = max(abs(PredPITPDTestYear.mean_Default - PredPITPDTestYear.mean_PITPD));
TTC2MaxError = max(abs(PredPITPDTestYear.mean_Default - PredTTCPD2TestYear.mean_TTCPD2));

T = array2table([TTCRMSError, TTCMaxError; PITRMSError, PITMaxError; TTC2RMSError, TTC2MaxError]);
T.Properties.RowNames = {'TTC Model'; 'PIT Model'; 'TTC with PIT Model'};
T.Properties.VariableNames = {'Root Mean Squared Error', 'Maximum Error'};
disp(T);
                          Root Mean Squared Error    Maximum Error
                          _______________________    _____________

    TTC Model                     0.001964             0.0035249  
    PIT Model                   0.00078292             0.0017776  
    TTC with PIT Model           0.0036801             0.0066774  

Ссылки

  1. Обобщенная линейная документация Моделей: https://www.mathworks.com/help/stats/generalized-linear-regression.html

  2. Baesens, B., Д. Рош и Х. Шеул. Аналитика кредитного риска. Вайли, 2016.

Для просмотра документации необходимо авторизоваться на сайте