Обработайте отсутствующие данные в рабочем процессе карты показателей кредита с помощью fillmissing MATLAB ®

В этом примере показан рабочий процесс сбора недостающих данных, ручной обработки обучающих данных, разработки новой creditscorecard, и лечить новые данные перед подсчетом баллов с помощью fillmissing MATLAB ®.

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

Кроме того, после создания creditscorecard объект, можно использовать fillmissing функция для creditscorecard объект для заполнения отсутствующих значений. Для получения дополнительной информации об альтернативных подходах к «обработке» недостающих данных смотрите Моделирование карты показателей кредита с отсутствующими значениями.

The dataMissing таблица в CreditCardData.mat файл имеет два предиктора с отсутствующими значениями - CustAge и ResStatus.

load CreditCardData.mat
head(dataMissing)
ans=8×11 table
    CustID    CustAge    TmAtAddress     ResStatus     EmpStatus    CustIncome    TmWBank    OtherCC    AMBalance    UtilRate    status
    ______    _______    ___________    ___________    _________    __________    _______    _______    _________    ________    ______

      1          53          62         <undefined>    Unknown        50000         55         Yes       1055.9        0.22        0   
      2          61          22         Home Owner     Employed       52000         25         Yes       1161.6        0.24        0   
      3          47          30         Tenant         Employed       37000         61         No        877.23        0.29        0   
      4         NaN          75         Home Owner     Employed       53000         20         Yes       157.37        0.08        0   
      5          68          56         Home Owner     Employed       53000         14         Yes       561.84        0.11        0   
      6          65          13         Home Owner     Employed       48000         59         Yes       968.18        0.15        0   
      7          34          32         Home Owner     Unknown        32000         26         Yes       717.82        0.02        1   
      8          50          57         Other          Employed       51000         33         No        3041.2        0.13        0   

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

Создайте creditscorecard объект с использованием CreditCardData.mat файл для загрузки dataMissing который содержит отсутствующие значения. Установите 'BinMissingData' аргумент для creditscorecard на true для явного сообщения информации об отсутствующих значениях. Затем применить автоматическое раскладывание с помощью autobinning.

sc = creditscorecard(dataMissing,'IDVar','CustID','BinMissingData',true);
sc = autobinning(sc);

Информация о интервале и интервале графики для предикторов, которые имеют отсутствующие данные, показывают <missing> Интервал в конце. Два предиктора с отсутствующими значениями в этом наборе данных CustAge и ResStatus.

bi = bininfo(sc,'CustAge');
disp(bi)
         Bin         Good    Bad     Odds       WOE       InfoValue 
    _____________    ____    ___    ______    ________    __________

    {'[-Inf,33)'}     69      52    1.3269    -0.42156      0.018993
    {'[33,37)'  }     63      45       1.4    -0.36795      0.012839
    {'[37,40)'  }     72      47    1.5319     -0.2779     0.0079824
    {'[40,46)'  }    172      89    1.9326    -0.04556     0.0004549
    {'[46,48)'  }     59      25      2.36     0.15424     0.0016199
    {'[48,51)'  }     99      41    2.4146     0.17713     0.0035449
    {'[51,58)'  }    157      62    2.5323     0.22469     0.0088407
    {'[58,Inf]' }     93      25      3.72     0.60931      0.032198
    {'<missing>'}     19      11    1.7273    -0.15787    0.00063885
    {'Totals'   }    803     397    2.0227         NaN      0.087112
plotbins(sc,'CustAge')

Figure contains an axes. The axes with title CustAge contains 3 objects of type bar, line. These objects represent Good, Bad.

bi = bininfo(sc,'ResStatus');
disp(bi)
         Bin          Good    Bad     Odds        WOE       InfoValue 
    ______________    ____    ___    ______    _________    __________

    {'Tenant'    }    296     161    1.8385    -0.095463     0.0035249
    {'Home Owner'}    352     171    2.0585     0.017549    0.00013382
    {'Other'     }    128      52    2.4615      0.19637     0.0055808
    {'<missing>' }     27      13    2.0769     0.026469    2.3248e-05
    {'Totals'    }    803     397    2.0227          NaN     0.0092627
plotbins(sc,'ResStatus')

Figure contains an axes. The axes with title ResStatus contains 3 objects of type bar, line. These objects represent Good, Bad.

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

Для обработки отсутствующих значений можно применить различные критерии. Этот пример следует прямому подходу, чтобы заменить отсутствующие наблюдения наиболее общим или типичным значением в распределении данных, которое является значением mode для данных. В данном примере mode имеет такое же значение WOE, как и исходное <missing> Интервал. Сходство значений выгодно, потому что аналогичные значения ГОРЕ означают аналогичные точки в карте показателей.

Для CustAge, bin 4 - интервал с наибольшим количеством наблюдений и mode значение исходных данных 43.

modeCustAge = mode(dataMissing.CustAge);
disp(modeCustAge)
    43

Значение ГОРЕ <missing> интервал аналогичен значению ГОРЕ интервала 4. Поэтому замена отсутствующих значений в CustAge со значением mode разумно.

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

dataTreated = dataMissing;
dataTreated.CustAge = fillmissing(dataTreated.CustAge,'constant',modeCustAge);

Для ResStatus, значение 'Home Owner' - значение mode данных и значения ГОРЕ <missing> интервал наиболее близок к диску 'Home Owner' Интервал.

modeResStatus = mode(dataMissing.ResStatus);
disp(modeResStatus)
     Home Owner 

Используйте MATLAB ® fillmissing для замены недостающих данных на 'Home Owner'.

dataTreated.ResStatus = fillmissing(dataTreated.ResStatus,'constant',string(modeResStatus));

Обработанный набор данных теперь не имеет отсутствующих значений.

disp(any(any(ismissing(dataTreated))))
   0

Используя обработанный набор данных, примените типичные creditscorecard рабочий процесс. Во-первых, создайте creditscorecard объект с обработанными данными, а затем применить автоматическое раскладывание.

scTreated = creditscorecard(dataTreated,'IDVar','CustID');
scTreated = autobinning(scTreated);

Сравните информацию о интервале необработанных данных для CustAge с информацией о интервале обработанных данных для CustAge.

bi = bininfo(sc,'CustAge');
disp(bi)
         Bin         Good    Bad     Odds       WOE       InfoValue 
    _____________    ____    ___    ______    ________    __________

    {'[-Inf,33)'}     69      52    1.3269    -0.42156      0.018993
    {'[33,37)'  }     63      45       1.4    -0.36795      0.012839
    {'[37,40)'  }     72      47    1.5319     -0.2779     0.0079824
    {'[40,46)'  }    172      89    1.9326    -0.04556     0.0004549
    {'[46,48)'  }     59      25      2.36     0.15424     0.0016199
    {'[48,51)'  }     99      41    2.4146     0.17713     0.0035449
    {'[51,58)'  }    157      62    2.5323     0.22469     0.0088407
    {'[58,Inf]' }     93      25      3.72     0.60931      0.032198
    {'<missing>'}     19      11    1.7273    -0.15787    0.00063885
    {'Totals'   }    803     397    2.0227         NaN      0.087112
biTreated = bininfo(scTreated,'CustAge');
disp(biTreated)
         Bin         Good    Bad     Odds       WOE       InfoValue
    _____________    ____    ___    ______    ________    _________

    {'[-Inf,33)'}     69      52    1.3269    -0.42156     0.018993
    {'[33,37)'  }     63      45       1.4    -0.36795     0.012839
    {'[37,40)'  }     72      47    1.5319     -0.2779    0.0079824
    {'[40,45)'  }    156      86     1.814    -0.10891    0.0024345
    {'[45,48)'  }     94      39    2.4103     0.17531    0.0033002
    {'[48,58)'  }    256     103    2.4854     0.20603      0.01223
    {'[58,Inf]' }     93      25      3.72     0.60931     0.032198
    {'Totals'   }    803     397    2.0227         NaN     0.089977

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

Для ResStatusрезультаты для обработанных данных выглядят аналогично начальным результатам, за исключением более высоких отсчётов в 'Home Owner' интервал из-за лечения. Для категориальной переменной с большим количеством категорий (или уровней) автоматический алгоритм может найти группы категорий, и результаты могут показать больше различий для до и после обработки.

bi = bininfo(sc,'ResStatus');
disp(bi)
         Bin          Good    Bad     Odds        WOE       InfoValue 
    ______________    ____    ___    ______    _________    __________

    {'Tenant'    }    296     161    1.8385    -0.095463     0.0035249
    {'Home Owner'}    352     171    2.0585     0.017549    0.00013382
    {'Other'     }    128      52    2.4615      0.19637     0.0055808
    {'<missing>' }     27      13    2.0769     0.026469    2.3248e-05
    {'Totals'    }    803     397    2.0227          NaN     0.0092627
biTreated = bininfo(scTreated,'ResStatus');
disp(biTreated)
         Bin          Good    Bad     Odds        WOE       InfoValue 
    ______________    ____    ___    ______    _________    __________

    {'Tenant'    }    296     161    1.8385    -0.095463     0.0035249
    {'Home Owner'}    379     184    2.0598     0.018182    0.00015462
    {'Other'     }    128      52    2.4615      0.19637     0.0055808
    {'Totals'    }    803     397    2.0227          NaN     0.0092603

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

[scTreated, mdl] = fitmodel(scTreated,'Display','off');
scTreated = formatpoints(scTreated,'PointsOddsAndPDO',[500 2 50]);
ScPoints = displaypoints(scTreated);
disp(ScPoints)
      Predictors               Bin             Points
    ______________    _____________________    ______

    {'CustAge'   }    {'[-Inf,33)'        }    53.507
    {'CustAge'   }    {'[33,37)'          }    55.798
    {'CustAge'   }    {'[37,40)'          }    59.646
    {'CustAge'   }    {'[40,45)'          }    66.868
    {'CustAge'   }    {'[45,48)'          }    79.013
    {'CustAge'   }    {'[48,58)'          }    80.326
    {'CustAge'   }    {'[58,Inf]'         }    97.559
    {'CustAge'   }    {'<missing>'        }       NaN
    {'ResStatus' }    {'Tenant'           }    62.161
    {'ResStatus' }    {'Home Owner'       }    73.305
    {'ResStatus' }    {'Other'            }    90.777
    {'ResStatus' }    {'<missing>'        }       NaN
    {'EmpStatus' }    {'Unknown'          }    58.846
    {'EmpStatus' }    {'Employed'         }    86.887
    {'EmpStatus' }    {'<missing>'        }       NaN
    {'CustIncome'}    {'[-Inf,29000)'     }    29.906
    {'CustIncome'}    {'[29000,33000)'    }    56.219
    {'CustIncome'}    {'[33000,35000)'    }    67.938
    {'CustIncome'}    {'[35000,40000)'    }    70.123
    {'CustIncome'}    {'[40000,42000)'    }    70.931
    {'CustIncome'}    {'[42000,47000)'    }      82.3
    {'CustIncome'}    {'[47000,Inf]'      }    96.647
    {'CustIncome'}    {'<missing>'        }       NaN
    {'TmWBank'   }    {'[-Inf,12)'        }     51.05
    {'TmWBank'   }    {'[12,23)'          }    61.018
    {'TmWBank'   }    {'[23,45)'          }    61.818
    {'TmWBank'   }    {'[45,71)'          }    92.921
    {'TmWBank'   }    {'[71,Inf]'         }    133.14
    {'TmWBank'   }    {'<missing>'        }       NaN
    {'OtherCC'   }    {'No'               }    50.806
    {'OtherCC'   }    {'Yes'              }    75.642
    {'OtherCC'   }    {'<missing>'        }       NaN
    {'AMBalance' }    {'[-Inf,558.88)'    }    89.788
    {'AMBalance' }    {'[558.88,1254.28)' }    63.088
    {'AMBalance' }    {'[1254.28,1597.44)'}    59.711
    {'AMBalance' }    {'[1597.44,Inf]'    }    49.157
    {'AMBalance' }    {'<missing>'        }       NaN

Новая карта показателей не знает, что данные были обработаны, поэтому она присваивает NaNs в < отсутствующие > интервалы. Если вам нужно набрать новый набор данных, и он содержит отсутствующие данные, по умолчанию score функция устанавливает точки равными NaN. Чтобы дополнительно изучить обработку недостающих данных, берите несколько строк из исходных данных в качестве тестовых данных и вводите некоторые недостающие данные.

tdata = dataTreated(11:14,mdl.PredictorNames); % Keep only the predictors retained in the model
% Set some missing values
tdata.CustAge(1) = NaN;
tdata.ResStatus(2) = '<undefined>';
tdata.EmpStatus(3) = '<undefined>';
tdata.CustIncome(4) = NaN;
disp(tdata)
    CustAge     ResStatus      EmpStatus     CustIncome    TmWBank    OtherCC    AMBalance
    _______    ___________    ___________    __________    _______    _______    _________

      NaN      Tenant         Unknown          34000         44         Yes        119.8  
       48      <undefined>    Unknown          44000         14         Yes       403.62  
       65      Home Owner     <undefined>      48000          6         No        111.88  
       44      Other          Unknown            NaN         35         No        436.41  

Оцените новые данные и посмотрите, как точки NaN, что приводит к NaN счета.

[Scores,Points] = score(scTreated,tdata);
disp(Scores)
   NaN
   NaN
   NaN
   NaN
disp(Points)
    CustAge    ResStatus    EmpStatus    CustIncome    TmWBank    OtherCC    AMBalance
    _______    _________    _________    __________    _______    _______    _________

       NaN      62.161       58.846        67.938      61.818     75.642      89.788  
    80.326         NaN       58.846          82.3      61.018     75.642      89.788  
    97.559      73.305          NaN        96.647       51.05     50.806      89.788  
    66.868      90.777       58.846           NaN      61.818     50.806      89.788  

Чтобы назначить точки отсутствующим данным, одной из возможностей является использование аргумента пары "имя-значение" 'Missing' в formatpoints для выбора способа присвоения точек отсутствующим значениям.

Используйте 'MinPoints' опция для 'Missing' аргумент. Эта опция присваивает отсутствующим данным минимальное количество возможных точек в карте показателей. В этом примере минимальное количество возможных точек для CustIncome является 29.906, так что последняя строка таблицы получает 29.906 точки для отсутствующего CustIncome значение.

scTreated = formatpoints(scTreated,'Missing','MinPoints');
[Scores,Points] = score(scTreated,tdata);
disp(Scores)
  469.7003
  510.0812
  518.0013
  448.8099
disp(Points)
    CustAge    ResStatus    EmpStatus    CustIncome    TmWBank    OtherCC    AMBalance
    _______    _________    _________    __________    _______    _______    _________

    53.507      62.161       58.846        67.938      61.818     75.642      89.788  
    80.326      62.161       58.846          82.3      61.018     75.642      89.788  
    97.559      73.305       58.846        96.647       51.05     50.806      89.788  
    66.868      90.777       58.846        29.906      61.818     50.806      89.788  

Однако для предикторов, обработанных в обучающих данных, таких как CustAge, эффект 'Missing' аргумент несовместим с обработкой обучающих данных. Для примера, для CustAge, первое наблюдение становится 53.507 точки для отсутствующего значения, но если новые данные были «обработаны», и отсутствующее значение для CustAge были заменены на mode обучающих данных (возраст 43), это наблюдение падает в [40, 45) интервал и получает 66.868 точки.

Поэтому перед подсчетом баллов наборы данных должны обрабатываться так же, как и обучающие данные. Использование 'Missing' Аргумент все еще важен для назначения точек для необработанных предикторов, и обработанные предикторы получают точки таким образом, чтобы это соответствовало способу разработки модели.

tdataTreated = tdata;
tdataTreated.CustAge = fillmissing(tdataTreated.CustAge,'constant',modeCustAge);
tdataTreated.ResStatus = fillmissing(tdataTreated.ResStatus,'constant',string(modeResStatus));
disp(tdataTreated)
    CustAge    ResStatus      EmpStatus     CustIncome    TmWBank    OtherCC    AMBalance
    _______    __________    ___________    __________    _______    _______    _________

      43       Tenant        Unknown          34000         44         Yes        119.8  
      48       Home Owner    Unknown          44000         14         Yes       403.62  
      65       Home Owner    <undefined>      48000          6         No        111.88  
      44       Other         Unknown            NaN         35         No        436.41  
[Scores,Points] = score(scTreated,tdataTreated);
disp(Scores)
  483.0606
  521.2249
  518.0013
  448.8099
disp(Points)
    CustAge    ResStatus    EmpStatus    CustIncome    TmWBank    OtherCC    AMBalance
    _______    _________    _________    __________    _______    _______    _________

    66.868      62.161       58.846        67.938      61.818     75.642      89.788  
    80.326      73.305       58.846          82.3      61.018     75.642      89.788  
    97.559      73.305       58.846        96.647       51.05     50.806      89.788  
    66.868      90.777       58.846        29.906      61.818     50.806      89.788