CrucibleXAI.FeatureAttribution.Permutation (CrucibleXAI v0.4.0)

View Source

Permutation importance for feature attribution.

Measures the increase in model error when a feature's values are randomly shuffled. If a feature is important, shuffling it will significantly degrade model performance. If a feature is irrelevant, shuffling it will have little effect.

Algorithm

  1. Measure baseline performance on validation set
  2. For each feature: a. Shuffle that feature's values across the dataset b. Measure performance on shuffled data c. Importance = baseline_score - shuffled_score
  3. Repeat multiple times and compute mean and standard deviation

Advantages

  • Model-agnostic
  • Accounts for feature interactions
  • Easy to interpret (change in performance metric)

Disadvantages

  • Requires validation dataset
  • Can be slow for many features
  • May create unrealistic feature combinations when features are correlated

Examples

iex> predict_fn = fn [x, y] -> 2.0 * x + 3.0 * y end
iex> validation_data = [{[1.0, 1.0], 5.0}, {[2.0, 2.0], 10.0}]
iex> importance = CrucibleXAI.FeatureAttribution.Permutation.calculate(predict_fn, validation_data, num_repeats: 2)
iex> is_map(importance)
true

Summary

Functions

Calculate permutation importance for each feature.

Get top k features by importance.

Functions

calculate(predict_fn, validation_data, opts \\ [])

@spec calculate(function(), [{list(), number()}], keyword()) :: %{
  required(integer()) => %{importance: float(), std_dev: float()}
}

Calculate permutation importance for each feature.

Parameters

  • predict_fn - Prediction function
  • validation_data - List of {features, label} tuples
  • opts - Options:
    • :metric - Performance metric (:mse, :mae, :accuracy) (default: :mse)
    • :num_repeats - Number of permutations per feature (default: 10)

Returns

Map of feature_index => %{importance: float, std_dev: float}

Examples

iex> predict_fn = fn [x] -> x * 2.0 end
iex> data = [{[1.0], 2.0}, {[2.0], 4.0}, {[3.0], 6.0}]
iex> result = CrucibleXAI.FeatureAttribution.Permutation.calculate(predict_fn, data, num_repeats: 2)
iex> Map.has_key?(result, 0)
true
iex> is_float(result[0][:importance])
true

top_k(importance_map, k)

@spec top_k(%{required(integer()) => map()}, pos_integer()) :: [{integer(), map()}]

Get top k features by importance.

Parameters

  • importance_map - Map from calculate/3
  • k - Number of top features to return

Returns

List of {feature_index, stats} tuples sorted by importance

Examples

iex> importance = %{0 => %{importance: 0.5, std_dev: 0.1}, 1 => %{importance: 0.8, std_dev: 0.2}}
iex> top = CrucibleXAI.FeatureAttribution.Permutation.top_k(importance, 1)
iex> length(top)
1
iex> {idx, _} = hd(top)
iex> idx
1