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

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

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

Этот пример требует Deep Learning Toolbox™ и Risk Management Toolbox™.

В этом примере вы создаете и обучаете три модели предсказанию значения по умолчанию кредита:

  • Сеть логистической регрессии (также известный как одноуровневый perceptron)

  • Многоуровневый perceptron (MLP)

  • Остаточная сеть (ResNet)

Можно описать каждую из этих моделей как нейронная сеть различной сложности и глубины.

Загрузите данные о значении по умолчанию кредита

Загрузите розничный набор данных панели кредита. Эти данные включают следующие переменные:

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

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

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

  • Default — Индикатор по умолчанию. Значение 1 для Default средние значения, что ссуда приняла значение по умолчанию в соответствующий календарный год.

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

filename = fullfile(toolboxdir('risk'),'riskdata','RetailCreditPanelData.mat');
tbl = load(filename).data;

Закодируйте категориальные переменные

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

Просмотрите порядок ScoreGroup категории.

categories(tbl.ScoreGroup)'
ans = 1×3 cell
    {'High Risk'}    {'Medium Risk'}    {'Low Risk'}

Преобразуйте категориальный ScoreGroup переменная к одногорячим закодированным векторам с помощью onehotencode функция.

riskGroup = onehotencode(tbl.ScoreGroup,2);

Добавьте одногорячие векторы в таблицу.

tbl.HighRisk = riskGroup(:,1);
tbl.MediumRisk = riskGroup(:,2);
tbl.LowRisk = riskGroup(:,3);

Удалите исходный ScoreGroup переменная из таблицы с помощью removevars.

tbl = removevars(tbl,{'ScoreGroup'});

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

tbl = movevars(tbl,'Default','After','LowRisk');

Просмотрите первые несколько строк таблицы. Заметьте, что ScoreGroup переменная была разделена в несколько столбцов с категориальными значениями как имена переменных.

head(tbl)
ans=8×7 table
    ID    YOB    Year    HighRisk    MediumRisk    LowRisk    Default
    __    ___    ____    ________    __________    _______    _______

    1      1     1997       0            0            1          0   
    1      2     1998       0            0            1          0   
    1      3     1999       0            0            1          0   
    1      4     2000       0            0            1          0   
    1      5     2001       0            0            1          0   
    1      6     2002       0            0            1          0   
    1      7     2003       0            0            1          0   
    1      8     2004       0            0            1          0   

Разделение данных

Разделите набор данных в обучение, валидацию, и протестируйте разделы с помощью уникальных идентификационных номеров ссуды. Отложите 60% данных для обучения, 20% для валидации и 20% для тестирования.

Найдите уникальные идентификаторы ссуды.

idx = unique(tbl.ID);
numObservations = length(idx);

Определите количество наблюдений для каждого раздела.

numObservationsTrain = floor(0.6*numObservations);
numObservationsValidation = floor(0.2*numObservations);
numObservationsTest = numObservations - numObservationsTrain - numObservationsValidation;

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

rng('default')
idxShuffle = idx(randperm(numObservations));

idxTrain = idxShuffle(1:numObservationsTrain);
idxValidation = idxShuffle(numObservationsTrain+1:numObservationsTrain+numObservationsValidation);
idxTest = idxShuffle(numObservationsTrain+numObservationsValidation+1:end);

Найдите записи таблицы, соответствующие разделам набора данных.

idxTrainTbl = ismember(tbl.ID,idxTrain);
idxValidationTbl = ismember(tbl.ID,idxValidation);
idxTestTbl = ismember(tbl.ID,idxTest);

Сохраните представляющие интерес переменные для задачи (YOB, HighRisk, MediumRisk, LowRisk, и Default) и удалите все другие переменные из таблицы.

tbl = removevars(tbl,{'ID','Year'});
head(tbl)
ans=8×5 table
    YOB    HighRisk    MediumRisk    LowRisk    Default
    ___    ________    __________    _______    _______

     1        0            0            1          0   
     2        0            0            1          0   
     3        0            0            1          0   
     4        0            0            1          0   
     5        0            0            1          0   
     6        0            0            1          0   
     7        0            0            1          0   
     8        0            0            1          0   

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

tblTrain = tbl(idxTrainTbl,:);
tblValidation = tbl(idxValidationTbl,:);
tblTest = tbl(idxTestTbl,:);

Архитектуры сети Define

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

Сеть логистической регрессии

Первая сеть является простой нейронной сетью, содержащей четыре слоя.

Начните с входного слоя функции, который передает табличные данные (данные о панели кредита) к сети. В этом примере существует четыре входных функции: YOB, HighRisk, MediumRisk, и LowRisk. Сконфигурируйте входной слой, чтобы нормировать данные с помощью нормализации z-счета. Нормализация данных важна для задач, где шкала и область значений входных переменных очень отличаются.

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

logisticLayers = [
    featureInputLayer(4,'Normalization','zscore')
    fullyConnectedLayer(1)
    sigmoidLayer
    BinaryCrossEntropyLossLayer('output')];

Эта сеть называется одноуровневым perceptron. Можно визуализировать сеть с помощью Deep Network Designer или analyzeNetwork функция.

deepNetworkDesigner(logisticLayers)

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

Wxi+b=W1xi,1+W2xi,2+W3xi,3+W4xi,4+b.

Выход полносвязного слоя обеспечивает вход для сигмоидального слоя. Сигмоидальный слой затем выходные параметры

S(Wxi+b)=11+exp{-(W1xi,1+W2xi,2+W3xi,3+W4xi,4+b)}.

Выход сигмоидального слоя эквивалентен модели логистической регрессии. Последний слой нейронной сети является бинарным слоем потери перекрестной энтропии. Минимизация бинарной потери перекрестной энтропии эквивалентна максимизации вероятности в модели логистической регрессии.

Многоуровневый Perceptron

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

mlpLayers = [
    featureInputLayer(4,'Normalization','zscore')
    fullyConnectedLayer(100)
    reluLayer
    fullyConnectedLayer(1)
    sigmoidLayer
    BinaryCrossEntropyLossLayer('output')];

deepNetworkDesigner(mlpLayers)

Остаточная сеть

Для итоговой сети создайте остаточную сеть (ResNet) [1] от нескольких стеков активаций ReLU и полносвязных слоев. Первоначально разработанный для классификации изображений, ResNets оказались успешными через многие области. Поскольку ResNet имеет намного больше параметров, чем многоуровневый perceptrons или логистические сети, они занимают больше времени, чтобы обучаться.

residualLayers = [
    featureInputLayer(4,'Normalization','zscore','Name','input')

    fullyConnectedLayer(16,'Name','fc1')
    batchNormalizationLayer('Name','bn1')
    reluLayer('Name','relu1')

    fullyConnectedLayer(32,'Name','resblock1-fc1')
    batchNormalizationLayer('Name','resblock1-bn1')
    reluLayer('Name','resblock1-relu1')

    fullyConnectedLayer(32,'Name','resblock1-fc2')
    additionLayer(2,'Name','resblock1-add')
    batchNormalizationLayer('Name','resblock1-bn2')
    reluLayer('Name','resblock1-relu2')

    fullyConnectedLayer(64,'Name','resblock2-fc1')
    batchNormalizationLayer('Name','resblock2-bn1')
    reluLayer('Name','resblock2-relu1')

    fullyConnectedLayer(64,'Name','resblock2-fc2')
    additionLayer(2,'Name','resblock2-add')
    batchNormalizationLayer('Name','resblock2-bn2')
    reluLayer('Name','resblock2-relu2')

    fullyConnectedLayer(1,'Name','fc2')
    sigmoidLayer('Name','sigmoid')
    BinaryCrossEntropyLossLayer('output')];

residualLayers = layerGraph(residualLayers);
residualLayers = addLayers(residualLayers,fullyConnectedLayer(32,'Name','resblock1-fc-shortcut'));
residualLayers = addLayers(residualLayers,fullyConnectedLayer(64,'Name','resblock2-fc-shortcut'));

residualLayers = connectLayers(residualLayers,'relu1','resblock1-fc-shortcut');
residualLayers = connectLayers(residualLayers,'resblock1-fc-shortcut','resblock1-add/in2');
residualLayers = connectLayers(residualLayers,'resblock1-relu2','resblock2-fc-shortcut');
residualLayers = connectLayers(residualLayers,'resblock2-fc-shortcut','resblock2-add/in2');

deepNetworkDesigner(residualLayers)

Сетевая глубина

Глубина сети является важной концепцией в глубоком обучении и задана как наибольшее число сверточных последовательных или полносвязные слоя (представленный желтыми блоками в следующей схеме) на пути от входного слоя до выходного слоя. Чем глубже сеть, тем более комплексные функции она может изучить. В этом примере логистическая сеть имеет глубину 1, многоуровневый perceptron имеет глубину 2, и остаточная сеть имеет глубину 6.

Задайте опции обучения

Задайте опции обучения.

  • Обучите использование оптимизатора Адама.

  • Установите начальную скорость обучения на 0,001.

  • Установите мини-пакетный размер на 512.

  • Включите график процесса обучения и выключите командное окно выход.

  • Переставьте данные в начале каждой эпохи.

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

options = trainingOptions('adam', ...
    'InitialLearnRate',0.001, ...
    'MiniBatchSize',512, ...
    'Plots','training-progress', ...
    'Verbose',false, ...
    'Shuffle','every-epoch', ...
    'ValidationData',tblValidation, ...
    'ValidationFrequency',1000);

Среда потерь сети логистической регрессии выпукла, поэтому, это не должно обучаться для как много эпох. Для логистической регрессии и многоуровневых perceptron моделей, обучайтесь в течение 15 эпох. Для более комплексной остаточной сети обучайтесь в течение 50 эпох.

logisticOptions = options;
logisticOptions.MaxEpochs = 15;

mlpOptions = options;
mlpOptions.MaxEpochs = 15;

residualOptions = options;
residualOptions.MaxEpochs = 50;

Эти три сети имеют различные архитектуры, таким образом, они требуют, чтобы различные наборы опций обучения достигли оптимальной эффективности. Можно выполнить оптимизацию программно или в интерактивном режиме использование Experiment Manager. Для примера, показывающего, как выполнить развертку гиперпараметра опций обучения, смотрите, Создают Эксперимент Глубокого обучения для Классификации.

Обучение сети

Обучите сети с помощью заданных архитектур, обучающие данные и опции обучения. По умолчанию, trainNetwork использует графический процессор, если вы доступны; в противном случае это использует центральный процессор. Обучение на графическом процессоре требует Parallel Computing Toolbox™ и поддерживаемого устройства графического процессора. Для получения информации о поддерживаемых устройствах смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Можно также задать среду выполнения при помощи ExecutionEnvironment аргумент значения имени trainingOptions.

Чтобы постараться не ожидать обучения, загрузите предварительно обученные сети путем установки doTrain отметьте к false. Обучать сети с помощью trainNetwork, установите doTrain отметьте к true.

Учебные времена с помощью NVIDIA® GeForce® RTX 2080 Ti:

  • Логистическая сеть — Приблизительно 4 минуты

  • Многоуровневый perceptron — Приблизительно 5 минут

  • Остаточная сеть — Приблизительно 35 минут

doTrain = false;

if doTrain
    logisticNet = trainNetwork(tblTrain,'Default',logisticLayers,logisticOptions);
    mlpNet = trainNetwork(tblTrain,'Default',mlpLayers,mlpOptions);
    residualNet = trainNetwork(tblTrain,'Default',residualLayers,residualOptions);
else
    load logisticTrainedNetwork
    load mlpTrainedNetwork
    load residualTrainedNetwork
end

Тестирование сети

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

tblTest.logisticPred = predict(logisticNet,tblTest(:,1:end-1));
tblTest.mlpPred = predict(mlpNet,tblTest(:,1:end-1));
tblTest.residualPred = predict(residualNet,tblTest(:,1:end-1));

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

Чтобы оценить эффективность сети, используйте groupsummary функционируйте, чтобы сгруппировать истинные уровни по умолчанию и соответствующие предсказания к годам на книгах (представленный YOB переменная), и вычисляют среднее значение.

summaryYOB = groupsummary(tblTest,'YOB','mean',{'Default','logisticPred','mlpPred','residualPred'});
head(summaryYOB)
ans=8×6 table
    YOB    GroupCount    mean_Default    mean_logisticPred    mean_mlpPred    mean_residualPred
    ___    __________    ____________    _________________    ____________    _________________

     1       19364         0.017352           0.017471          0.018056           0.017663    
     2       18917         0.012158           0.014209          0.015486           0.014192    
     3       18526         0.011875           0.011538          0.013154           0.011409    
     4       18232         0.011683          0.0093902          0.011151           0.010311    
     5       17925        0.0082008           0.007626         0.0089826          0.0093438    
     6       17727        0.0066565          0.0062047         0.0062967          0.0073401    
     7       12294        0.0030909          0.0050643         0.0042998          0.0047071    
     8        6361        0.0017293          0.0041463         0.0029052          0.0025272    

Постройте истинный средний уровень по умолчанию против средних предсказаний к годам на книгах.

networks = ["Logistic Regression Network","Multilayer Percerptron Network","Residual Network"];

figure
tiledlayout('flow','TileSpacing','compact')

for i = 1:3
    nexttile
    scatter(summaryYOB.YOB,summaryYOB.mean_Default*100,'*');
    hold on
    plot(summaryYOB.YOB,summaryYOB{:,i+3}*100);
    hold off
    title(networks(i))
    xlabel('Years on Books')
    ylabel('Default Rate (%)')
    legend('Observed','Predicted')
end

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

Уровни по умолчанию группами счета

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

Декодируйте ScoreGroup назад в категориальные группы счета.

ScoreGroup = onehotdecode(tblTest{:,2:4},{'HighRisk','MediumRisk','LowRisk'},2);
tblTest.ScoreGroup = ScoreGroup;
tblTest = removevars(tblTest,{'HighRisk','MediumRisk','LowRisk'});

riskGroups = categories(tblTest.ScoreGroup);

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

numYOB = height(summaryYOB);
numRiskGroups = height(riskGroups);

summaryYOBScore = groupsummary(tblTest,{'ScoreGroup','YOB'},'mean',{'Default','logisticPred','mlpPred','residualPred'});
head(summaryYOBScore)
ans=8×7 table
    ScoreGroup    YOB    GroupCount    mean_Default    mean_logisticPred    mean_mlpPred    mean_residualPred
    __________    ___    __________    ____________    _________________    ____________    _________________

     HighRisk      1        6424         0.029577           0.028404          0.031563            0.02973    
     HighRisk      2        6180         0.020065            0.02325          0.026649           0.023655    
     HighRisk      3        5949         0.019163           0.019013          0.022484           0.018724    
     HighRisk      4        5806         0.020668           0.015535          0.018957           0.017207    
     HighRisk      5        5634          0.01349           0.012686           0.01577           0.015374    
     HighRisk      6        5531         0.013379           0.010354          0.010799            0.01215    
     HighRisk      7        3862        0.0051787          0.0084466         0.0071398          0.0083738    
     HighRisk      8        2027        0.0034534          0.0068881         0.0047145          0.0040559    

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

figure
t = tiledlayout('flow','TileSpacing','compact');
color = lines(3);

YOB = summaryYOBScore.YOB;
default = summaryYOBScore.mean_Default*100;
group = summaryYOBScore.ScoreGroup;

for i = 1:3
    pred = summaryYOBScore{:,i+4}*100;
    meanScore = reshape(pred,numYOB,numRiskGroups);

    nexttile
    hs = gscatter(YOB,default,group,color,'*',6,false);
    hold on
    colororder(color)
    plot(meanScore)
    hold off
    title(networks(i))
    xlabel('Years on Books')
    ylabel('Default Rate (%)')
    grid on
end

labels = ["True: " + riskGroups; "Pred: " + riskGroups];
lgd = legend(labels);
lgd.Layout.Tile = 4;

График показывает, что все группы счета ведут себя так же, в то время как время прогрессирует с общей тенденцией к понижению. Через группу высокого риска год четыре не следует за тенденцией к понижению. В средней группе риска годы три и четыре кажутся плоскими. Наконец, в группе с низким риском, год три показывает увеличение. Эти неправильные тренды затрудняют, чтобы различить с более простой моделью логистической регрессии.

Для примера, показывающего, как использовать локально поддающиеся толкованию объяснения модели агностические (LIME) и значения Шепли interpretability методы, чтобы изучить предсказания остаточной сети для предсказания значения по умолчанию кредита, смотрите, Интерпретируют и Нейронные сети для глубокого обучения Стресс-теста для Вероятности Значения по умолчанию (Risk Management Toolbox).

Ссылки

[1] Он, Kaiming, Сянюй Чжан, Шаоцин Жэнь и Цзянь Сунь. "Глубокая невязка, учащаяся для распознавания изображений". В Продолжениях конференции по IEEE по компьютерному зрению и распознаванию образов, стр 770-778. 2016.

Смотрите также

| | | |

Связанные примеры

Больше о