Note
Go to the end to download the full example code.
Using skrub DataOp cross-validation#
When a skrub DataOp defines a cross-validation splitter on
mark_as_X(), evaluate() can reuse that
configuration — including split_kwargs such as groups — instead of
skore’s default 80/20 holdout.
This example builds a small grouped cross-validation setup with skrub and evaluates it with skore.
Configure cross-validation on the DataOp#
We use the toy products dataset and group products by seller. The goal is to
assess generalization to new sellers with
LeaveOneGroupOut.
import skrub
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import LeaveOneGroupOut
df = skrub.datasets.toy_products()
data = skrub.var("df")
groups = data["seller"]
X = data[["description", "price"]].skb.mark_as_X(
cv=LeaveOneGroupOut(), split_kwargs={"groups": groups}
)
y = data["category"].skb.mark_as_y()
pred = X.skb.apply(DummyClassifier(), y=y)
learner = pred.skb.make_learner()
Evaluate with skore (no explicit splitter)#
Because mark_as_X was called with an explicit cv argument, calling
evaluate() without a splitter returns a
CrossValidationReport that respects the DataOp grouping.
| Metric | Label | mean | std |
|---|---|---|---|
| Score | 0.666667 | 0.000000e+00 | |
| Accuracy | 0.666667 | 0.000000e+00 | |
| Precision | electronics | 0.666667 | 0.000000e+00 |
| Precision | tools | 0.000000 | 0.000000e+00 |
| Recall | electronics | 1.000000 | 0.000000e+00 |
| Recall | tools | 0.000000 | 0.000000e+00 |
| ROC AUC | 0.500000 | 0.000000e+00 | |
| Log loss | 0.636514 | 0.000000e+00 | |
| Brier score | 0.222222 | 2.775558e-17 | |
| Fit time (s) | 0.003148 | 2.069348e-05 | |
| Predict time (s) | 0.001972 | 8.291251e-05 |
- [SKD002] Potential underfitting. Detected in 2/2 evaluated splits. Read more about this here.
No tips were emitted for your report.
- [SKD008] Highly correlated input features. Expected train data to have between 2 and 1000 features; got 1. Read more about this here.
- [SKD006] Coefficient interpretation. Estimator is not a linear model: it does not have a `coef_` attribute. Read more about this here.
- [SKD015] Hyperparameters worth tuning. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
- [SKD007] MDI biased for high-cardinality features. Estimator is not a tree-based model: it does not have a `feature_importances_` attribute. Read more about this here.
- [SKD016] Estimator not tuned. No parameter to recommend for the estimator. Read more about this here.
- [SKD005] Underrepresented classes. ML task is not multiclass classification. Got binary-classification. Read more about this here.
- [SKD013] Train-test overlap in time series. No datetime column found. Read more about this here.
- [SKD014] Hyperparameters at search edge. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
Fast mode is on: expensive checks are skipped unless already cached.
Mute a check by passing its code to ignore, e.g. .checks.summarize(ignore=['SKD001']).
SkrubLearner(data_op=<Apply DummyClassifier>)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
| description | price | category | |
|---|---|---|---|
| 0 | screen | 100 | electronics |
| 1 | hammer | 15 | tools |
| 2 | keyboard | 20 | electronics |
| 3 | usb key | 9 | electronics |
| 4 | charger | 13 | electronics |
| 5 | screwdriver | 12 | tools |
description
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
price
Int64DType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
- Mean ± Std
- 28.2 ± 35.4
- Median ± IQR
- 13 ± 8
- Min | Max
- 9 | 100
category
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 2 (33.3%)
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
|
Column
|
Column name
|
dtype
|
Is sorted
|
Null values
|
Unique values
|
Mean
|
Std
|
Min
|
Median
|
Max
|
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | description | ObjectDType | False | 0 (0.0%) | 6 (100.0%) | |||||
| 1 | price | Int64DType | False | 0 (0.0%) | 6 (100.0%) | 28.2 | 35.4 | 9 | 13 | 100 |
| 2 | category | ObjectDType | False | 0 (0.0%) | 2 (33.3%) |
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
Please enable javascript
The skrub table reports need javascript to display correctly. If you are displaying a report in a Jupyter notebook and you see this message, you may need to re-execute the cell or to trust the notebook (button on the top right or "File > Trust notebook").
There are two sellers, so cross-validation runs in two folds:
len(report.reports_)
2
Inspect aggregated metrics with the same API as other skore reports:
report.metrics.summarize().frame()
| SkrubLearner | |||
|---|---|---|---|
| mean | std | ||
| Metric | Label | ||
| Score | 0.666667 | 0.000000e+00 | |
| Accuracy | 0.666667 | 0.000000e+00 | |
| Precision | electronics | 0.666667 | 0.000000e+00 |
| tools | 0.000000 | 0.000000e+00 | |
| Recall | electronics | 1.000000 | 0.000000e+00 |
| tools | 0.000000 | 0.000000e+00 | |
| ROC AUC | 0.500000 | 0.000000e+00 | |
| Log loss | 0.636514 | 0.000000e+00 | |
| Brier score | 0.222222 | 2.775558e-17 | |
| Fit time (s) | 0.003148 | 2.069348e-05 | |
| Predict time (s) | 0.001972 | 8.291251e-05 | |
Default behavior without an explicit DataOp cv#
If mark_as_X is called without an explicit cv argument,
evaluate() still defaults to a single 80/20 holdout and returns
an EstimatorReport.
simple_learner = skrub.X().skb.apply(DummyClassifier(), y=skrub.y()).skb.make_learner()
holdout_report = evaluate(
simple_learner,
data={"X": df[["description", "price"]], "y": df["category"]},
)
holdout_report
| Metric | Label | SkrubLearner |
|---|---|---|
| Score | 0.500000 | |
| Accuracy | 0.500000 | |
| Precision | electronics | 0.500000 |
| Precision | tools | 0.000000 |
| Recall | electronics | 1.000000 |
| Recall | tools | 0.000000 |
| ROC AUC | 0.500000 | |
| Log loss | 0.836988 | |
| Brier score | 0.312500 | |
| Fit time (s) | 0.001667 | |
| Predict time (s) | 0.000833 |
- [SKD001] Potential overfitting. Significant train/test gaps were found for 5/9 default predictive metrics. Read more about this here.
- [SKD002] Potential underfitting. Train/test scores are on par and not significantly better than the dummy baseline for 9/9 comparable metrics. Read more about this here.
No tips were emitted for your report.
- [SKD004] High class imbalance. Read more about this here.
- [SKD005] Underrepresented classes. ML task is not multiclass classification. Got binary-classification. Read more about this here.
- [SKD006] Coefficient interpretation. Estimator is not a linear model: it does not have a `coef_` attribute. Read more about this here.
- [SKD007] MDI biased for high-cardinality features. Estimator is not a tree-based model: it does not have a `feature_importances_` attribute. Read more about this here.
- [SKD008] Highly correlated input features. Expected train data to have between 2 and 1000 features; got 1. Read more about this here.
- [SKD013] Train-test overlap in time series. No datetime column found. Read more about this here.
- [SKD014] Hyperparameters at search edge. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
- [SKD015] Hyperparameters worth tuning. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
- [SKD016] Estimator not tuned. No parameter to recommend for the estimator. Read more about this here.
Fast mode is on: expensive checks are skipped unless already cached.
Mute a check by passing its code to ignore, e.g. .checks.summarize(ignore=['SKD001']).
SkrubLearner(data_op=<Apply DummyClassifier>)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Fitted attributes
| Name | Type | Value |
|---|---|---|
| classes_ | ndarray[object](2,) | ['electronics','tools'] |
| description | price | category | |
|---|---|---|---|
| 0 | hammer | 15 | tools |
| 1 | usb key | 9 | electronics |
| 2 | screen | 100 | electronics |
| 3 | charger | 13 | electronics |
| 4 | screwdriver | 12 | tools |
| 5 | keyboard | 20 | electronics |
description
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
price
Int64DType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
- Mean ± Std
- 28.2 ± 35.4
- Median ± IQR
- 13 ± 8
- Min | Max
- 9 | 100
category
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 2 (33.3%)
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
|
Column
|
Column name
|
dtype
|
Is sorted
|
Null values
|
Unique values
|
Mean
|
Std
|
Min
|
Median
|
Max
|
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | description | ObjectDType | False | 0 (0.0%) | 6 (100.0%) | |||||
| 1 | price | Int64DType | False | 0 (0.0%) | 6 (100.0%) | 28.2 | 35.4 | 9 | 13 | 100 |
| 2 | category | ObjectDType | False | 0 (0.0%) | 2 (33.3%) |
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
Please enable javascript
The skrub table reports need javascript to display correctly. If you are displaying a report in a Jupyter notebook and you see this message, you may need to re-execute the cell or to trust the notebook (button on the top right or "File > Trust notebook").
Explicitly passing a splitter always overrides the DataOp configuration.
override_report = evaluate(learner, data={"df": df}, splitter=2)
override_report
| Metric | Label | mean | std |
|---|---|---|---|
| Score | 0.666667 | 0.000000e+00 | |
| Accuracy | 0.666667 | 0.000000e+00 | |
| Precision | electronics | 0.666667 | 0.000000e+00 |
| Precision | tools | 0.000000 | 0.000000e+00 |
| Recall | electronics | 1.000000 | 0.000000e+00 |
| Recall | tools | 0.000000 | 0.000000e+00 |
| ROC AUC | 0.500000 | 0.000000e+00 | |
| Log loss | 0.636514 | 0.000000e+00 | |
| Brier score | 0.222222 | 2.775558e-17 | |
| Fit time (s) | 0.001891 | 2.055842e-05 | |
| Predict time (s) | 0.001030 | 2.491349e-05 |
- [SKD002] Potential underfitting. Detected in 2/2 evaluated splits. Read more about this here.
No tips were emitted for your report.
- [SKD008] Highly correlated input features. Expected train data to have between 2 and 1000 features; got 1. Read more about this here.
- [SKD006] Coefficient interpretation. Estimator is not a linear model: it does not have a `coef_` attribute. Read more about this here.
- [SKD015] Hyperparameters worth tuning. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
- [SKD007] MDI biased for high-cardinality features. Estimator is not a tree-based model: it does not have a `feature_importances_` attribute. Read more about this here.
- [SKD016] Estimator not tuned. No parameter to recommend for the estimator. Read more about this here.
- [SKD005] Underrepresented classes. ML task is not multiclass classification. Got binary-classification. Read more about this here.
- [SKD013] Train-test overlap in time series. No datetime column found. Read more about this here.
- [SKD014] Hyperparameters at search edge. Estimator is not a BaseSearchCV instance. Got <class 'skrub.SkrubLearner'>. Read more about this here.
Fast mode is on: expensive checks are skipped unless already cached.
Mute a check by passing its code to ignore, e.g. .checks.summarize(ignore=['SKD001']).
SkrubLearner(data_op=<Apply DummyClassifier>)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
| description | price | category | |
|---|---|---|---|
| 0 | screen | 100 | electronics |
| 1 | hammer | 15 | tools |
| 2 | keyboard | 20 | electronics |
| 3 | usb key | 9 | electronics |
| 4 | charger | 13 | electronics |
| 5 | screwdriver | 12 | tools |
description
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
price
Int64DType- Null values
- 0 (0.0%)
- Unique values
- 6 (100.0%)
- Mean ± Std
- 28.2 ± 35.4
- Median ± IQR
- 13 ± 8
- Min | Max
- 9 | 100
category
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 2 (33.3%)
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
|
Column
|
Column name
|
dtype
|
Is sorted
|
Null values
|
Unique values
|
Mean
|
Std
|
Min
|
Median
|
Max
|
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | description | ObjectDType | False | 0 (0.0%) | 6 (100.0%) | |||||
| 1 | price | Int64DType | False | 0 (0.0%) | 6 (100.0%) | 28.2 | 35.4 | 9 | 13 | 100 |
| 2 | category | ObjectDType | False | 0 (0.0%) | 2 (33.3%) |
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
Please enable javascript
The skrub table reports need javascript to display correctly. If you are displaying a report in a Jupyter notebook and you see this message, you may need to re-execute the cell or to trust the notebook (button on the top right or "File > Trust notebook").
Total running time of the script: (0 minutes 2.128 seconds)