Contenu principal

Manage Validation Metrics with MATLAB Unit Tests

This example shows how to define and calculate model validation metrics with MATLAB unit tests, using a probability of default (PD) model validation example. In this example, you define each model validation metric as a MATLAB unit test, and then supply data as external parameters. This allows you to reuse the same MATLAB unit test with multiple models and compare against model validation metric thresholds. Open the example to get the supporting files you need.

Define Thresholds

Create a parameterized test suite object that contains numeric thresholds defined for model validation metrics. The threshold properties of the test suite contain numeric values that are compared against the actual metrics. If the metrics do not pass the threshold criteria, the unit test case will be marked as a failure.

ParameterizedPDTestSuite
ans = 
  ParameterizedPDTestSuite with properties:

              Data: [1×1 struct]
       KSThreshold: {[0]}
    AUROCThreshold: {[0.2000]}
      CAPThreshold: {[0.2000]}

Prepare Data

Load an existing credit scorecard to validate.

modelDataFile = "PDModel.mat";
inputData = load(modelDataFile); 

Set the response variable and default indicator.

responseVar = "status";
outcomeIndicator = 1;

Extract the scorecard and key data.

sc = inputData.sc;
model1 = struct('ModelScores', sc.score, 'ModelPDs', probdefault(sc), 'DefaultIndicators', sc.Data.(responseVar) == outcomeIndicator );

Prepare a second data set with randomly generated values.

model2 = struct('ModelScores', unifrnd(min(sc.score),max(sc.score), size(sc.score)), ...
    'ModelPDs', rand(size(probdefault(sc))), 'DefaultIndicators', sc.Data.(responseVar) == outcomeIndicator );

Run Tests

Run tests on both data sets. You supply both data sets to the test suite as External Parameters. The results capture the visualizations from the validation metrics, and test whether each validation metric passes the defined threshold. Because the second data set contains random data, a unit test related to the Cumulative Accuracy Profile (CAP) metric fails. From the name of the failed test, you can identify which data set and metric failed, allowing you to investigate further the cause of the failure.

import matlab.unittest.TestSuite
import matlab.unittest.parameters.Parameter
param = Parameter.fromData('Data', ...
    struct('Model1',model1,'Model2',model2));
suite = TestSuite.fromClass(?ParameterizedPDTestSuite,"ExternalParameters",param);
run(suite)
Running ParameterizedPDTestSuite

Figure contains an axes object. The axes object with title Kolmogorov-Smirnov Statistic, xlabel Scores (Riskiest to Safest), ylabel Cumulative Probability contains 5 objects of type line. These objects represent Hit rate, False alarm rate.

.

Figure contains an axes object. The axes object with title Kolmogorov-Smirnov Statistic, xlabel Scores (Riskiest to Safest), ylabel Cumulative Probability contains 5 objects of type line. These objects represent Hit rate, False alarm rate.

.

Figure contains an axes object. The axes object with title Cumulative Accuracy Profile (CAP) curve, xlabel Fraction of Borrowers, ylabel Fraction of Defaulters contains 3 objects of type line. These objects represent CAP curve, Perfect model, Random model.

.
================================================================================
Verification failed in ParameterizedPDTestSuite/testCAP(Data=Model2#ext,CAPThreshold=0.2).
    ----------------
    Test Diagnostic:
    ----------------
    Value 0.042978 is less than set threshold 0.2
    ---------------------
    Framework Diagnostic:
    ---------------------
    verifyGreaterThanOrEqual failed.
    --> The value must be greater than or equal to the minimum value.
    
    Actual Value:
       0.042978001261014
    Minimum Value (Inclusive):
       0.200000000000000
    ------------------
    Stack Information:
    ------------------
    In /tmp/Bdoc26a_3146167_513435/tpdbb66f20/mrm-ex21244219/PDTestSuite.m (PDTestSuite.testCAP) at 22
================================================================================

Figure contains an axes object. The axes object with title Cumulative Accuracy Profile (CAP) curve, xlabel Fraction of Borrowers, ylabel Fraction of Defaulters contains 3 objects of type line. These objects represent CAP curve, Perfect model, Random model.

.

Figure contains an axes object. The axes object with title Receiver Operating Characteristic (ROC) curve, xlabel Fraction of Non-Defaulters, ylabel Fraction of Defaulters contains an object of type line.

.

Figure contains an axes object. The axes object with title Receiver Operating Characteristic (ROC) curve, xlabel Fraction of Non-Defaulters, ylabel Fraction of Defaulters contains an object of type line.

.
Done ParameterizedPDTestSuite
__________

Failure Summary:

     Name                                                                Failed  Incomplete  Reason(s)
    =================================================================================================================
     ParameterizedPDTestSuite/testCAP(Data=Model2#ext,CAPThreshold=0.2)    X                 Failed by verification.
ans = 
  1×6 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   5 Passed, 1 Failed, 0 Incomplete.
   3.4621 seconds testing time.

Modify Thresholds

You can also supply different or multiple values for thresholds. In this section you pass two thresholds for the Kolmogorov-Smirnov statistic. From the names of the generated unit tests in the suite, you can see that tests will be run using both values of the threshold you specified. This allows you to automate parameter sweeps over thresholds.

param = Parameter.fromData('KSThreshold',{0.1,0.2});
suite = TestSuite.fromClass(?ParameterizedPDTestSuite,"ExternalParameters",param)
suite = 
  1×4 Test array with properties:

    Name
    ProcedureName
    TestClass
    BaseFolder
    Parameterization
    SharedTestFixtures
    Tags

Tests Include:
    5 Unique Parameterizations, 0 Shared Test Fixture Classes, 0 Tags.

suite.Name
ans = 
'ParameterizedPDTestSuite/testKS(Data=example,KSThreshold=0.1#ext)'
ans = 
'ParameterizedPDTestSuite/testKS(Data=example,KSThreshold=0.2#ext)'
ans = 
'ParameterizedPDTestSuite/testCAP(Data=example,CAPThreshold=0.2)'
ans = 
'ParameterizedPDTestSuite/testAUROC(Data=example,AUROCThreshold=0.2)'

See Also

Topics