[workflow]
How the data is prepared, split and validated, and how the fitted models are evaluated. This is the largest section, so it is divided into sub-tables, each described below.
[workflow]
random_state = 42
n_jobs = 2
[workflow.preprocessing]
# ...
[workflow.validation.test_split]
# ...
[workflow.evaluation.metrics]
# ...
| Key | Type | Default | Description |
|---|---|---|---|
random_state |
integer | 42 |
Seed for the random parts of the pipeline. Must be 0 or more. |
n_jobs |
integer | 1 |
Number of parallel jobs. Use -1 for all processors. |
preprocessing |
table | none | Transformations applied to the predictors. |
validation |
table | required | How the data is split and cross-validated. |
evaluation |
table | required | Metrics, confidence intervals and subgroup analysis. |
random_state seeds the random train/test and recalibration splits, the shuffling in cross-validation, and the bootstrap resampling of the confidence intervals. Running the same configuration on the same data therefore gives the same splits and intervals. It is not passed to the models. To fix the randomness of a model, set the model's own random_state in its hyperparameters.
n_jobs sets the parallelism of cross-validation, grid search and the bootstrap resampling. It does not affect the plots.
[workflow.preprocessing]
Transformations that are applied to the predictors before they reach the model.
[workflow.preprocessing]
preprocess = true
operations = [
{ name = "OrdinalEncoder", columns = ["SEX", "ADMISSION_ACUITY", "ADMISSION_SOURCE", "CATEGORY_LEVEL_1"] },
{ name = "StandardScaler", columns = ["CATEGORY_LEVEL_1", "AGE"], with_mean = true },
]
| Key | Type | Default | Description |
|---|---|---|---|
preprocess |
boolean | none | Whether the operations are applied. When it is false or the table is omitted, the predictors are given to the model unchanged. |
operations |
list of tables | none | The operations, applied in order. Required when preprocess is true. |
Each operation is a table with the following keys:
| Key | Type | Description |
|---|---|---|
name |
string | Class name of the transformer. See available preprocessing operations. |
columns |
list of strings | Predictors the operation is applied to. It cannot be empty. |
| any other key | any | Passed to the constructor of the transformer, such as with_mean above. |
The operations are applied one after the other, each one to its own columns. All the other columns are passed on unchanged. In the example, the four categorical predictors are first encoded as numbers, and CATEGORY_LEVEL_1 and AGE are then scaled. A column can be used by several operations.
Some points to keep in mind:
columnsmust be listed indata.predictors. An operation on any other column is rejected when the configuration is validated, with a message that names the operation and the columns.columnsalways refers to the original name of a predictor. A later operation cannot refer to a column that an earlier operation replaced with several columns, such as the output of aOneHotEncoder.- The operations are fitted as part of the model, so during cross-validation they are fitted on the training folds only.
- The operation names and their arguments are only checked when the data is prepared. An unknown name or an argument the transformer does not accept stops the run at that point.
[workflow.validation]
How the data is divided. The test set is set aside first. If a recalibration split is defined, the recalibration set is taken from what remains, and the rest is the training set. Cross-validation is then run on the training set only.
all data ──► test set
└─► remaining ──► recalibration set (optional)
└─► training set ──► cross-validation folds
| Key | Type | Default | Description |
|---|---|---|---|
test_split |
table | required | The held-out test set. |
recalibration_split |
table | none | The set used to recalibrate the models. Required when recalibration is used. |
cross_validation |
table | none | Cross-validation on the training set. Required when run_mode is "cv" or "audit". |
test_split
| Key | Type | Default | Description |
|---|---|---|---|
strategy |
string | "random" |
"random" or "group". |
test_size |
float | none | Fraction of the data used for testing, strictly between 0 and 1. Required for "random". |
group_column |
string | none | Column that defines the groups. Required for "group". |
values |
list of strings or integers | none | Values of group_column that go to the test set. Required for "group". |
- With the
"random"strategy, rows are assigned to the test set at random, usingrandom_state. The split is not stratified. - With the
"group"strategy, every row whosegroup_columnvalue is invaluesis in the test set, and all the other rows are not. This is useful for temporal or geographical validation, for example to test on the most recent year or on a hospital that was not used for training.
recalibration_split
[workflow.validation.recalibration_split]
strategy = "group"
group_column = "OP_YEAR"
values = [2023]
| Key | Type | Default | Description |
|---|---|---|---|
strategy |
string | required | "random" or "group". It must be the same as the test split. |
recalibration_size |
float | none | Fraction of the data left after the test split that is used for recalibration, strictly between 0 and 1. Required for "random". |
group_column |
string | none | Required for "group". It must be the same as in the test split. |
values |
list of strings or integers | none | Values of group_column that go to the recalibration set. Required for "group". None of them can also be in the test split. |
The recalibration split follows the same logic as the test split, and has to be consistent with it. For example, with test_size = 0.3 and recalibration_size = 0.2, the test set has 30% of the data, the recalibration set has 20% of the remaining 70%, and the training set has the rest. The recalibration split is required whenever recalibration is enabled for a model.
cross_validation
[workflow.validation.cross_validation]
strategy = "group"
grid_search = true
group_column = "DHB_NAME"
n_splits = 3
shuffle = true
| Key | Type | Default | Description |
|---|---|---|---|
strategy |
string | required | "random", "group" or "loso". |
n_splits |
integer | none | Number of folds, 2 or more. Required for "random" and "group". Not used for "loso". |
group_column |
string | none | Column that defines the groups. Required for "group" and "loso". |
shuffle |
boolean | true |
Whether to shuffle the data before it is divided into folds. The shuffling uses random_state. |
grid_search |
boolean | none | Whether to search over the list-valued hyperparameters. |
The strategies are:
| Strategy | Folds | Classifiers | Regressors |
|---|---|---|---|
"random" |
n_splits folds of random rows |
StratifiedKFold, which keeps the share of positives in every fold |
KFold |
"group" |
n_splits folds in which a group is never split between folds |
StratifiedGroupKFold |
GroupKFold |
"loso" |
One fold per group, each holding out a single group (leave one group out) | LeaveOneGroupOut |
LeaveOneGroupOut |
The models are scored on every metric in workflow.evaluation.metrics.metrics. What happens next depends on grid_search:
grid_search = true: every combination of the list-valued hyperparameters is tried. The best combination is chosen using the first metric of themetricslist, and the model is refitted with it on the whole training set.- Otherwise: the cross-validation only reports the scores. The model is then fitted on the whole training set, using the first value of every list-valued hyperparameter.
The fold scores are saved in the CV/ folder of the run. Cross-validation is only run when run_mode is "cv" or "audit".
[workflow.evaluation]
How the fitted models are evaluated on the test set.
metrics
| Key | Type | Default | Description |
|---|---|---|---|
metrics |
list of strings | ["roc_auc", "ici"] |
Metrics to compute. See the list of available metrics. |
n_bootstraps |
integer | 200 |
Number of bootstrap resamples used to compute the confidence intervals. Use 0 to skip the intervals. |
ci_level |
float | 0.95 |
Confidence level of the intervals, between 0 and 1. |
cv_splines |
integer | 3 |
Number of internal folds used by the spline fit of the ici metric, 2 or more. Lower values are faster. It has no effect on other metrics. |
Every metric is computed on the test set with a bootstrapped confidence interval. The names are checked when the configuration is validated, so a metric you registered with MetricRegistry is accepted if it is registered before the pipeline is created. The metrics are also checked against the type of outcome: for a classifier, a metric that needs a predictive distribution (crps) is rejected. The regression page lists the rules for regressors.
The results are saved for each outcome in results/<outcome>_evaluation_results.json, with the point estimate and the bounds of the interval for every metric:
{
"outcome": "MORTALITY_30D",
"overall": {
"roc_auc": {"point_estimate": 0.61, "ci_lower": 0.42, "ci_upper": 0.74}
},
"strata": {}
}
The strata entry has the same values for each subgroup of the fairness analysis.
With n_bootstraps = 0 the bootstrap is skipped: only the point estimates are computed, and ci_lower and ci_upper are saved as NaN.
fairness
Optional. Computes the metrics on subgroups of the test set, to check whether the model performs equally across patient groups. The results are also drawn as heatmaps when figures are produced.
| Key | Type | Default | Description |
|---|---|---|---|
strata |
list of strings | required | Columns that define the subgroups. |
groups |
table | none | Ranges to use for some of the strata. |
For every column in strata:
- If the column is not in
groups, there is one subgroup for each distinct value of the column. In the example,SEXgives one subgroup per sex. - If the column is in
groups, each entry is a[minimum, maximum]range, and both ends are included. In the example,AGEgives the subgroups[18, 50]and[51, 120]. Every entry must have exactly two values.
A key of groups must also be in strata, and its list cannot be empty. Ranges are for numeric columns. To make subgroups of a categorical column, leave it out of groups.
The strata columns have to exist in the data, but they do not have to be predictors. A column that is only used for the fairness analysis, for example a hospital, is read from the data but never given to the model. A column that is missing stops the run before any model is fitted.