Model-agnostic feature importance by measuring what breaking a feature costs.
Functions
Measure importance by shuffling a feature and watching the score fall.
Parameters
estimator
predict.
X
y
X.
scoring
'accuracy', 'r2', 'neg_mse', or a (y_true, y_pred) -> float callable.
n_repeats
feature_names
random_state
Returns
explanation
values holds the mean score drop per feature. metadata carries std, the per-repeat raw matrix and the unpermuted baseline_score.
Notes
Complexity. n_features n_repeats prediction passes; the model is never refitted.
Correlated features hide each other. If two columns carry the same information, permuting either leaves the model able to recover the signal from the other, and both score as unimportant. The result is not that neither matters — it is that neither matters given the other*. Group correlated columns and permute them together when that distinction matters, or use drop_column_importance, which retrains and so answers a different question.
Permuting also fabricates combinations the data never contains — a row with one feature's value drawn from a different row can be physically impossible — so the model is scored off its training distribution.
References
See Also
>>> import numpy as np
>>> from tuiml.explain import permutation_importance
>>> from tuiml.algorithms.trees import RandomForestClassifier
>>> rng = np.random.default_rng(0)
>>> X = rng.normal(size=(300, 4))
>>> y = (X[:, 1] > 0).astype(int) # only feature 1 matters
>>> model = RandomForestClassifier(n_estimators=50, random_state=0).fit(X, y)
>>> result = permutation_importance(X=X, y=y, estimator=model, random_state=0)
>>> result.top(1)[0][0]
'feature_1'
Measure importance by removing a feature and refitting.
Parameters
estimator
X
y
scoring
cv
feature_names
random_state
Returns
explanation
values holds the cross-validated score drop caused by dropping each feature. metadata carries baseline_score.
Notes
Complexity. (n_features + 1) cv model fits — far more expensive than permutation importance, which refits nothing. Reach for it when the decision at hand really is whether to collect a feature.
A negative value is meaningful, not noise to clip: it says the model scored better* without that feature, which happens when a column is pure noise the learner was overfitting to.
References
>>> import numpy as np
>>> from tuiml.explain import drop_column_importance
>>> from tuiml.algorithms.trees import DecisionTreeClassifier
>>> rng = np.random.default_rng(0)
>>> X = rng.normal(size=(200, 3))
>>> y = (X[:, 0] > 0).astype(int)
>>> result = drop_column_importance(
... DecisionTreeClassifier(max_depth=4), X, y, cv=3, random_state=0)
>>> result.top(1)[0][0]
'feature_0'