В этом примере показано, как сравнить три пожизненных модели PD с помощью перекрестной проверки.
Загрузите данные о портфеле, которые включают загрузку и макро-информацию. Это - симулированный набор данных, используемый для целей рисунка.
load RetailCreditPanelData.mat
data = join(data,dataMacro);
disp(head(data))
ID ScoreGroup YOB Default Year GDP Market __ __________ ___ _______ ____ _____ ______ 1 Low Risk 1 0 1997 2.72 7.61 1 Low Risk 2 0 1998 3.57 26.24 1 Low Risk 3 0 1999 2.86 18.1 1 Low Risk 4 0 2000 2.43 3.19 1 Low Risk 5 0 2001 1.26 -10.51 1 Low Risk 6 0 2002 -0.59 -22.95 1 Low Risk 7 0 2003 0.63 2.78 1 Low Risk 8 0 2004 1.85 9.48
Поскольку данные являются данными о панели, существует несколько строк для каждого клиента. Вы настраиваете разделы перекрестной проверки по идентификаторам клиентов, не по строкам набора данных. Таким образом клиент может быть или в наборе обучающих данных или в наборе тестов, но строки, соответствующие тому же клиенту, не разделены между обучением и тестированием.
nIDs = max(data.ID); uniqueIDs = unique(data.ID); NumFolds = 5; rng('default'); % for reproducibility c = cvpartition(nIDs,'KFold',NumFolds);
Сравните Logistic
, Probit
, Cox
пожизненные модели PD с помощью тех же переменных.
CVModels = ["logistic";"probit";"cox"]; NumModels = length(CVModels); AUROC = zeros(NumFolds,NumModels); RMSE = zeros(NumFolds,NumModels); for ii=1:NumFolds fprintf('Fitting models, fold %d\n',ii); % Get indices for ID partition TrainIDInd = training(c,ii); TestIDInd = test(c,ii); % Convert to row indices TrainDataInd = ismember(data.ID,uniqueIDs(TrainIDInd)); TestDataInd = ismember(data.ID,uniqueIDs(TestIDInd)); % For each model, fit with training data, measure with test data for jj=1:NumModels % Fit model with training data pdModel = fitLifetimePDModel(data(TrainDataInd,:),CVModels(jj),... 'IDVar','ID','AgeVar','YOB','LoanVars','ScoreGroup',... 'MacroVars',{'GDP','Market'},'ResponseVar','Default'); % Measure discrimination on test data DiscMeasure = modelDiscrimination(pdModel,data(TestDataInd,:)); AUROC(ii,jj) = DiscMeasure.AUROC; % Measure accuracy on test data, grouping by YOB (age) and score group AccMeasure = modelAccuracy(pdModel,data(TestDataInd,:),["YOB" "ScoreGroup"]); RMSE(ii,jj) = AccMeasure.RMSE; end end
Fitting models, fold 1 Fitting models, fold 2 Fitting models, fold 3 Fitting models, fold 4 Fitting models, fold 5
Используя дискриминацию и меры по точности для различных сгибов, можно сравнить модели. В этом примере отображены метрики. Можно также сравнить средний AUROC или средний RMSE путем сравнения пропорции времен, модель выше относительно дискриминации или точности. Эти три модели в этом примере очень сопоставимы.
AUROCTable = array2table(AUROC,"RowNames",strcat("Fold ",string(1:NumFolds)),"VariableNames",strcat("AUROC_",CVModels))
AUROCTable=5×3 table
AUROC_logistic AUROC_probit AUROC_cox
______________ ____________ _________
Fold 1 0.69558 0.6957 0.69565
Fold 2 0.70265 0.70335 0.70366
Fold 3 0.69055 0.69037 0.69008
Fold 4 0.70268 0.70232 0.70296
Fold 5 0.68784 0.68781 0.68811
RMSETable = array2table(RMSE,"RowNames",strcat("Fold ",string(1:NumFolds)),"VariableNames",strcat("RMSE_",CVModels))
RMSETable=5×3 table
RMSE_logistic RMSE_probit RMSE_cox
_____________ ___________ __________
Fold 1 0.0019412 0.0020972 0.0020048
Fold 2 0.0011167 0.0011644 0.0011612
Fold 3 0.0011536 0.0011802 0.0012766
Fold 4 0.0010269 0.00097877 0.00099473
Fold 5 0.0015965 0.001485 0.0015829
fitLifetimePDModel
| predict
| predictLifetime
| modelDiscrimination
| modelAccuracy
| Logistic
| Probit
| Cox