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

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

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

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

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')

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')

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

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

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

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

Значение WOE <missing> интервал похож на значение WOE интервала 4. Поэтому заменяя отсутствующие значения в CustAge со значением mode разумно.

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

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

Для ResStatus, значение 'Home Owner' значение mode из данных и значения WOE <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 'points'.

Поэтому перед выигрышем, наборы данных должны быть обработаны тем же путем, обучающие данные были обработаны. Использование '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  
Для просмотра документации необходимо авторизоваться на сайте