(
X: Sequence[Sequence[float]],
y: Sequence[float],
feature_names: Sequence[str] | None = None,
sample_weight: Sequence[float] | None = None,
event_end_indices: Sequence[int] | None = None,
n_splits: int = 5,
pct_embargo: float = 0.01,
scoring: str = "neg_log_loss",
)
| 340 | for c in cols: |
| 341 | col = [row[c] for row in x_test] |
| 342 | shifted = col[-s:] + col[:-s] if s > 0 else col[:] |
| 343 | for i in range(n): |
| 344 | perm[i][c] = shifted[i] |
| 345 | |
| 346 | perm_score = _score(y_test, _predict_proba(model, perm), scoring, sample_weight_test) |
| 347 | if scoring == "neg_log_loss": |
| 348 | imp = (base - perm_score) / (-perm_score) if abs(perm_score) > _EPS else 0.0 |
| 349 | else: |
| 350 | imp = (base - perm_score) / (1.0 - perm_score) if abs(1.0 - perm_score) > _EPS else 0.0 |
| 351 | out.append(imp if imp == imp and imp != float("inf") and imp != float("-inf") else 0.0) |
| 352 | |
| 353 | return base, out |
| 354 | |
| 355 | |
| 356 | def mda_importance( |
| 357 | X: Sequence[Sequence[float]], |
| 358 | y: Sequence[float], |
| 359 | feature_names: Sequence[str] | None = None, |
| 360 | sample_weight: Sequence[float] | None = None, |
| 361 | event_end_indices: Sequence[int] | None = None, |
| 362 | n_splits: int = 5, |
| 363 | pct_embargo: float = 0.01, |
| 364 | scoring: str = "neg_log_loss", |
| 365 | allow_unpurged: bool = False, |
| 366 | ) -> dict[str, object]: |
| 367 | x = _as_matrix(X) |
| 368 | yv = _as_vector(y, len(x)) |
| 369 | names = _feature_names(len(x[0]), feature_names) |
| 370 | weights = _sample_weight(sample_weight, len(x)) |
| 371 | intervals = _build_intervals(event_end_indices, len(x), allow_unpurged=allow_unpurged) |
| 372 | splits = _purged_kfold_splits(intervals, n_splits=n_splits, pct_embargo=pct_embargo) |
| 373 | |
| 374 | per_feature: list[list[float]] = [[] for _ in names] |
| 375 | fold_scores: list[float] = [] |
| 376 | |
| 377 | for fold_idx, (train_idx, test_idx) in enumerate(splits): |
| 378 | x_train = [x[i] for i in train_idx] |
| 379 | y_train = [yv[i] for i in train_idx] |
| 380 | x_test = [x[i] for i in test_idx] |
| 381 | y_test = [yv[i] for i in test_idx] |
| 382 | w_train = [weights[i] for i in train_idx] if weights is not None else None |
| 383 | w_test = [weights[i] for i in test_idx] if weights is not None else None |
| 384 | |
| 385 | base, scores = _score_with_perm_groups( |
| 386 | x_train, |
| 387 | y_train, |
| 388 | x_test, |
| 389 | y_test, |
| 390 | [[j] for j in range(len(names))], |
| 391 | scoring, |
| 392 | w_train, |
| 393 | w_test, |
| 394 | shift=fold_idx + 1, |
| 395 | ) |
| 396 | fold_scores.append(base) |
| 397 | for j, imp in enumerate(scores): |
| 398 | per_feature[j].append(imp) |
| 399 |
no test coverage detected