Microfactual API Reference
Core
Core data structures for microfactual.
- class microfactual.core.MicrobiomeDataset(abundance, metadata, target_column, sample_column='Sample ID')
Bases:
objectCentral data structure for microbiome datasets.
This class provides a clean interface for microbiome data, building on the existing data processing functions while providing sklearn-compatible data access patterns.
- abundance(pd.DataFrame)
- Type:
Abundance data (features x samples)
- metadata(pd.DataFrame)
- Type:
Sample metadata
- target_column(str)
- Type:
Name of target variable column
- sample_column(str)
- Type:
Name of sample ID column
- property X: DataFrame
Features matrix in sklearn format (samples x features).
- Returns:
Transposed abundance matrix with samples as rows, features as columns
- Return type:
pd.DataFrame
- clr_transform(log_n0=1e-06, inplace=True)
Apply CLR transformation using existing clr_transform function.
- Parameters:
log_n0 (float, optional) – Pseudocount for zero replacement, by default 1e-6
inplace (bool, optional) – Whether to modify dataset in place, by default True
- Returns:
Transformed dataset if inplace=False, None otherwise
- Return type:
MicrobiomeDataset or None
- property feature_names: Index
Get feature names (e.g., species names).
- Returns:
Feature names from abundance data index
- Return type:
pd.Index
- filter_features(abundance_cutoff=1e-06, prevalence_cutoff=0.05, inplace=True)
Apply feature filtering using existing filter_data function.
- Parameters:
abundance_cutoff (float, optional) – Minimum mean abundance threshold, by default 1e-6
prevalence_cutoff (float, optional) – Minimum prevalence threshold, by default 0.05
inplace (bool, optional) – Whether to modify dataset in place, by default True
- Returns:
Filtered dataset if inplace=False, None otherwise
- Return type:
MicrobiomeDataset or None
- classmethod from_files(abundance_file, metadata_file, target_column, sample_column='Sample ID')
Create MicrobiomeDataset from files using existing load_data function.
- Parameters:
abundance_file (str) – Path to abundance data file (tab-separated)
metadata_file (str) – Path to metadata file (tab-separated)
target_column (str) – Column name for target variable
sample_column (str, optional) – Column name for sample IDs, by default “Sample ID”
- Returns:
Initialized dataset object
- Return type:
- get_info()
Get comprehensive dataset information.
- Returns:
Dictionary containing dataset statistics and metadata
- Return type:
dict
- reset_preprocessing()
Reset to original data, removing all preprocessing steps.
- Return type:
None
- property sample_names: Index
Get sample names/IDs.
- Returns:
Sample IDs from abundance data columns
- Return type:
pd.Index
- property target_names: list
Get the original target class names.
- Returns:
List of unique target class names
- Return type:
list
- property y: Series
Target vector with encoded categorical labels.
- Returns:
Encoded target labels as categorical codes
- Return type:
pd.Series
Central data structure for microbiome datasets.
- class microfactual.core.dataset.MicrobiomeDataset(abundance, metadata, target_column, sample_column='Sample ID')
Bases:
objectCentral data structure for microbiome datasets.
This class provides a clean interface for microbiome data, building on the existing data processing functions while providing sklearn-compatible data access patterns.
- abundance(pd.DataFrame)
- Type:
Abundance data (features x samples)
- metadata(pd.DataFrame)
- Type:
Sample metadata
- target_column(str)
- Type:
Name of target variable column
- sample_column(str)
- Type:
Name of sample ID column
- property X: DataFrame
Features matrix in sklearn format (samples x features).
- Returns:
Transposed abundance matrix with samples as rows, features as columns
- Return type:
pd.DataFrame
- clr_transform(log_n0=1e-06, inplace=True)
Apply CLR transformation using existing clr_transform function.
- Parameters:
log_n0 (float, optional) – Pseudocount for zero replacement, by default 1e-6
inplace (bool, optional) – Whether to modify dataset in place, by default True
- Returns:
Transformed dataset if inplace=False, None otherwise
- Return type:
MicrobiomeDataset or None
- property feature_names: Index
Get feature names (e.g., species names).
- Returns:
Feature names from abundance data index
- Return type:
pd.Index
- filter_features(abundance_cutoff=1e-06, prevalence_cutoff=0.05, inplace=True)
Apply feature filtering using existing filter_data function.
- Parameters:
abundance_cutoff (float, optional) – Minimum mean abundance threshold, by default 1e-6
prevalence_cutoff (float, optional) – Minimum prevalence threshold, by default 0.05
inplace (bool, optional) – Whether to modify dataset in place, by default True
- Returns:
Filtered dataset if inplace=False, None otherwise
- Return type:
MicrobiomeDataset or None
- classmethod from_files(abundance_file, metadata_file, target_column, sample_column='Sample ID')
Create MicrobiomeDataset from files using existing load_data function.
- Parameters:
abundance_file (str) – Path to abundance data file (tab-separated)
metadata_file (str) – Path to metadata file (tab-separated)
target_column (str) – Column name for target variable
sample_column (str, optional) – Column name for sample IDs, by default “Sample ID”
- Returns:
Initialized dataset object
- Return type:
- get_info()
Get comprehensive dataset information.
- Returns:
Dictionary containing dataset statistics and metadata
- Return type:
dict
- reset_preprocessing()
Reset to original data, removing all preprocessing steps.
- Return type:
None
- property sample_names: Index
Get sample names/IDs.
- Returns:
Sample IDs from abundance data columns
- Return type:
pd.Index
- property target_names: list
Get the original target class names.
- Returns:
List of unique target class names
- Return type:
list
- property y: Series
Target vector with encoded categorical labels.
- Returns:
Encoded target labels as categorical codes
- Return type:
pd.Series
Preprocessing
Preprocessing module for microbiome data transformations.
- class microfactual.preprocessing.AbundanceFilter(min_abundance=1e-06)
Bases:
BaseEstimator,TransformerMixinFilter features by minimum mean abundance.
- Parameters:
min_abundance (float, default=1e-6) – Minimum mean abundance required to retain a feature.
Examples
>>> filt = AbundanceFilter(min_abundance=0.01) >>> X_filtered = filt.fit_transform(X)
- fit(X, y=None)
Learn which features pass the abundance threshold.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the abundance filter.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
Filtered data with low-abundance features removed.
- Return type:
pd.DataFrame
- class microfactual.preprocessing.CLRTransform(pseudocount=1e-06)
Bases:
BaseEstimator,TransformerMixinCentered Log-Ratio (CLR) transformation for compositional data.
The CLR transformation is appropriate for microbiome abundance data which is compositional (relative abundances sum to 1).
- Parameters:
pseudocount (float, default=1e-6) – Small value added to zeros before log transformation.
Examples
>>> clr = CLRTransform() >>> X_transformed = clr.fit_transform(X)
- fit(X, y=None)
Fit the transformer.
CLR is a stateless transformation, so this just validates input.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the CLR transformation.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
CLR-transformed data with the same shape.
- Return type:
pd.DataFrame
- class microfactual.preprocessing.PrevalenceFilter(min_prevalence=0.05)
Bases:
BaseEstimator,TransformerMixinFilter features by minimum prevalence (fraction of non-zero samples).
- Parameters:
min_prevalence (float, default=0.05) – Minimum fraction of samples in which a feature must be present. Must be between 0 and 1.
Examples
>>> filt = PrevalenceFilter(min_prevalence=0.1) >>> X_filtered = filt.fit_transform(X)
- fit(X, y=None)
Learn which features pass the prevalence threshold.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the prevalence filter.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
Filtered data with rare features removed.
- Return type:
pd.DataFrame
Sklearn-compatible preprocessing transforms for microbiome data.
All transforms follow sklearn’s fit/transform pattern and can be used in sklearn.pipeline.Pipeline.
- class microfactual.preprocessing.transforms.AbundanceFilter(min_abundance=1e-06)
Bases:
BaseEstimator,TransformerMixinFilter features by minimum mean abundance.
- Parameters:
min_abundance (float, default=1e-6) – Minimum mean abundance required to retain a feature.
Examples
>>> filt = AbundanceFilter(min_abundance=0.01) >>> X_filtered = filt.fit_transform(X)
- fit(X, y=None)
Learn which features pass the abundance threshold.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the abundance filter.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
Filtered data with low-abundance features removed.
- Return type:
pd.DataFrame
- class microfactual.preprocessing.transforms.CLRTransform(pseudocount=1e-06)
Bases:
BaseEstimator,TransformerMixinCentered Log-Ratio (CLR) transformation for compositional data.
The CLR transformation is appropriate for microbiome abundance data which is compositional (relative abundances sum to 1).
- Parameters:
pseudocount (float, default=1e-6) – Small value added to zeros before log transformation.
Examples
>>> clr = CLRTransform() >>> X_transformed = clr.fit_transform(X)
- fit(X, y=None)
Fit the transformer.
CLR is a stateless transformation, so this just validates input.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the CLR transformation.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
CLR-transformed data with the same shape.
- Return type:
pd.DataFrame
- class microfactual.preprocessing.transforms.PrevalenceFilter(min_prevalence=0.05)
Bases:
BaseEstimator,TransformerMixinFilter features by minimum prevalence (fraction of non-zero samples).
- Parameters:
min_prevalence (float, default=0.05) – Minimum fraction of samples in which a feature must be present. Must be between 0 and 1.
Examples
>>> filt = PrevalenceFilter(min_prevalence=0.1) >>> X_filtered = filt.fit_transform(X)
- fit(X, y=None)
Learn which features pass the prevalence threshold.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
y (None) – Ignored; present for scikit-learn API compatibility.
- get_feature_names_out(input_features=None)
Get output feature names for transformation.
- Parameters:
input_features (array-like of str or None, default=None) – Input features.
- Returns:
Transformed feature names.
- Return type:
array of str
- transform(X)
Apply the prevalence filter.
- Parameters:
X (pd.DataFrame) – Abundance data (samples x features).
- Returns:
Filtered data with rare features removed.
- Return type:
pd.DataFrame
Models
Models module for microfactual.
- class microfactual.models.MicrobiomeClassifier(algorithm='random_forest', preprocessing='auto', **model_params)
Bases:
ClassifierMixin,BaseEstimatorClassifier with built-in microbiome preprocessing.
This provides a simple interface for microbiome classification with sensible defaults. It wraps sklearn classifiers with optional preprocessing steps.
- _estimator_type
Type of estimator, set to “classifier” for sklearn compatibility.
- Type:
str
- Parameters:
algorithm (str, default="random_forest") – The classification algorithm to use. Options: “random_forest”, “svm”, “logistic”
preprocessing (str, list, or None, default="auto") – Preprocessing strategy: - “auto”: Apply abundance filter, prevalence filter, CLR transform - None: No preprocessing (use raw features) - list: Custom list of sklearn-compatible transformers
**model_params – Additional parameters passed to the underlying classifier.
Examples
>>> clf = MicrobiomeClassifier() >>> clf.fit(X, y) >>> predictions = clf.predict(X_test)
- ALGORITHMS = {'logistic': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'random_forest': <class 'sklearn.ensemble._forest.RandomForestClassifier'>}
- property feature_importances_
Get feature importances if available.
- fit(X, y)
Fit the classifier.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
y (pd.Series or np.ndarray) – Target vector.
- Return type:
self
- get_params(deep=True)
Get parameters for this estimator (sklearn-compatible).
Extends the default behaviour so that keyword arguments forwarded to the underlying classifier (e.g.
n_estimators,max_depth) are exposed as top-level params. This makes the estimator usable withsklearn.clone,set_paramsandGridSearchCVover those params.- Parameters:
deep (bool, default=True) – Kept for sklearn API compatibility; has no nested effect here.
- Returns:
Parameter names mapped to their values, including forwarded model params.
- Return type:
dict
- predict(X)
Predict class labels.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
- Returns:
y_pred – Predicted class labels.
- Return type:
np.ndarray
- predict_proba(X)
Predict class probabilities.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
- Returns:
proba – Probability for each class, shape (n_samples, n_classes).
- Return type:
np.ndarray
- set_params(**params)
Set the parameters of this estimator (sklearn-compatible).
Unknown parameters are treated as keyword arguments for the underlying classifier rather than raising, mirroring the
**model_paramsaccepted by__init__.- Parameters:
**params – Estimator parameters to set.
- Returns:
self.
- Return type:
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') MicrobiomeClassifier
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
Microbiome-optimized classifiers with built-in preprocessing.
The MicrobiomeClassifier provides a batteries-included approach to microbiome classification with sensible defaults for preprocessing.
- class microfactual.models.classifiers.MicrobiomeClassifier(algorithm='random_forest', preprocessing='auto', **model_params)
Bases:
ClassifierMixin,BaseEstimatorClassifier with built-in microbiome preprocessing.
This provides a simple interface for microbiome classification with sensible defaults. It wraps sklearn classifiers with optional preprocessing steps.
- _estimator_type
Type of estimator, set to “classifier” for sklearn compatibility.
- Type:
str
- Parameters:
algorithm (str, default="random_forest") – The classification algorithm to use. Options: “random_forest”, “svm”, “logistic”
preprocessing (str, list, or None, default="auto") – Preprocessing strategy: - “auto”: Apply abundance filter, prevalence filter, CLR transform - None: No preprocessing (use raw features) - list: Custom list of sklearn-compatible transformers
**model_params – Additional parameters passed to the underlying classifier.
Examples
>>> clf = MicrobiomeClassifier() >>> clf.fit(X, y) >>> predictions = clf.predict(X_test)
- ALGORITHMS = {'logistic': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'random_forest': <class 'sklearn.ensemble._forest.RandomForestClassifier'>}
- property feature_importances_
Get feature importances if available.
- fit(X, y)
Fit the classifier.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
y (pd.Series or np.ndarray) – Target vector.
- Return type:
self
- get_params(deep=True)
Get parameters for this estimator (sklearn-compatible).
Extends the default behaviour so that keyword arguments forwarded to the underlying classifier (e.g.
n_estimators,max_depth) are exposed as top-level params. This makes the estimator usable withsklearn.clone,set_paramsandGridSearchCVover those params.- Parameters:
deep (bool, default=True) – Kept for sklearn API compatibility; has no nested effect here.
- Returns:
Parameter names mapped to their values, including forwarded model params.
- Return type:
dict
- predict(X)
Predict class labels.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
- Returns:
y_pred – Predicted class labels.
- Return type:
np.ndarray
- predict_proba(X)
Predict class probabilities.
- Parameters:
X (pd.DataFrame or np.ndarray) – Feature matrix (samples x features).
- Returns:
proba – Probability for each class, shape (n_samples, n_classes).
- Return type:
np.ndarray
- set_params(**params)
Set the parameters of this estimator (sklearn-compatible).
Unknown parameters are treated as keyword arguments for the underlying classifier rather than raising, mirroring the
**model_paramsaccepted by__init__.- Parameters:
**params – Estimator parameters to set.
- Returns:
self.
- Return type:
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') MicrobiomeClassifier
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
Explainability
Explainability module for interpretability methods.
- class microfactual.explainability.BaseExplainer(model, data, **kwargs)
Bases:
ABCAbstract base class for model explainers.
- abstractmethod explain(query_instance, **kwargs)
Generate explanations for a query instance.
- Parameters:
query_instance (pd.DataFrame) – Instance(s) to explain.
**kwargs – Additional parameters for generating the explanation.
- Returns:
The explanation object (framework specific).
- Return type:
Any
- class microfactual.explainability.CounterfactualResult(original, counterfactuals, model, feature_names, class_names=None, raw=None, atol=1e-08)
Bases:
objectInterpretable wrapper around a set of counterfactuals for one sample.
- Parameters:
original (array-like) – The query sample’s feature values.
counterfactuals (array-like) – Counterfactual rows (n_cfs x n_features), already sparsified if desired.
model (Any) – Fitted classifier used to (re)validate predictions.
feature_names (list of str) – Names of the features, in column order.
class_names (list of str, optional) – Human-readable class labels, indexed by predicted integer class.
raw (Any, optional) – The underlying DiCE explanation object, kept for advanced use.
atol (float, default=1e-8) – Tolerance below which a feature is considered unchanged.
- changes(cf_index=None)
Return the per-feature changes for one or all counterfactuals.
- Parameters:
cf_index (int, optional) – If given, return changes for that single counterfactual. Otherwise return the changes for all counterfactuals stacked, with a
cfcolumn identifying each.- Returns:
Columns:
cf(omitted whencf_indexgiven),feature,original,counterfactual,delta,direction. Only rows where the feature actually changed are included, sorted by descending absolute change.- Return type:
pd.DataFrame
- property n_changes: list[int]
Number of features changed by each counterfactual.
- property n_counterfactuals: int
Number of counterfactuals held.
- property original_prediction: int
Predicted class for the original sample.
- summary()
Return a short human-readable summary of the counterfactuals.
- Return type:
str
- property validity: float
Fraction of counterfactuals that actually flip the prediction.
- visualize_as_dataframe(*args, **kwargs)
Delegate to the underlying DiCE explanation’s visualizer, if present.
- Return type:
Any
- class microfactual.explainability.DiCEExplainer(model, background_data, target_column, target_data=None, backend='sklearn', continuous_features=None, **kwargs)
Bases:
BaseExplainerWrapper for DiCE (Diverse Counterfactual Explanations).
Generates counterfactual examples: “What changes to the input would flip the model prediction?”
- explain(query_instance, total_CFs=5, desired_class='opposite', **kwargs)
Generate counterfactual explanations.
- Parameters:
query_instance (pd.DataFrame) – The instance to explain.
total_CFs (int, default=5) – Number of counterfactuals to generate.
desired_class (str, default="opposite") – Desired target class (“opposite” or specific class index).
**kwargs – Additional parameters passed to exp.generate_counterfactuals()
- Returns:
The explanation object containing counterfactuals.
- Return type:
dice_ml.counterfactual_explanations.CounterfactualExplanations
- microfactual.explainability.counterfactual_concordance(result, X, y, reference_class)
Fraction of changed taxa whose counterfactual moves toward the reference.
For each changed taxon, checks whether the counterfactual’s change is in the same direction as the gap between the sample’s original value and the reference-class median. A high score means the counterfactual shifts the sample toward the reference distribution rather than in some arbitrary model-exploiting direction — a cheap plausibility signal.
- Parameters:
result (CounterfactualResult) – A result from
explain_counterfactual().X (pd.DataFrame) – Feature matrix used to compute the reference median.
y (array-like) – Class labels aligned with
X.reference_class (Any) – The label value in
yto move toward.
- Returns:
Concordance in
[0, 1], ornanif there are no changes.- Return type:
float
- microfactual.explainability.counterfactual_importance(model, X, y, *, background_data=None, target_column='outcome', total_CFs=3, desired_class='opposite', features_to_vary='all', permitted_range=None, sparse=True, method='genetic', backend='sklearn', top_n=None, **kwargs)
Aggregate counterfactuals across a cohort into per-taxon importance.
Generates counterfactuals for every sample in
Xand summarises how often each taxon has to change to flip predictions, and in which direction. This is a local-aggregated importance: unlike a global feature-importance score, it reflects the taxa that actually drive individual decisions across the cohort, with an interpretable direction of change.As with
explain_counterfactual(), pass everything in the model’s input feature space (e.g. CLR).- Parameters:
model (Any) – Fitted, sklearn-compatible classifier.
X (pd.DataFrame) – Samples to explain (samples x features).
y (pd.Series, pd.DataFrame, or array-like) – Targets aligned with
background_data.background_data (pd.DataFrame, optional) – Distribution DiCE samples from; defaults to
Xitself.target_column (str, default="outcome") – See
explain_counterfactual().total_CFs (int, default=3) – Counterfactuals generated per sample before aggregation.
desired_class (str, default="opposite") – See
explain_counterfactual().features_to_vary (str or list of str, default="all") – See
explain_counterfactual().permitted_range (dict, optional) – See
explain_counterfactual().sparse (bool, default=True) – See
explain_counterfactual().method (str, default="genetic") – See
explain_counterfactual().backend (str, default="sklearn") – See
explain_counterfactual().top_n (int, optional) – If given, return only the
top_nmost frequently implicated taxa.**kwargs (
Any) – Forwarded todice_ml.Dice.generate_counterfactuals.
- Returns:
One row per implicated taxon, sorted by how many samples implicate it. Columns:
feature,n_samples(samples whose counterfactuals change it),frequency(fraction of explained samples),mean_delta(mean signed change, averaged per sample),direction(net “increase”/ “decrease”).- Return type:
pd.DataFrame
- microfactual.explainability.explain_counterfactual(model, query, background_data, y, *, target_column='outcome', total_CFs=5, desired_class='opposite', features_to_vary='all', permitted_range=None, sparse=True, class_names=None, continuous_features=None, method='genetic', backend='sklearn', return_raw=False, **kwargs)
Generate actionable counterfactual explanations for one or more samples.
This is MicroFactual’s headline entry point: it answers “what minimal change in feature values would flip this sample’s prediction?” in a single call, wrapping
DiCEExplainer.Two features make the result actionable rather than a wall of numbers:
features_to_vary/permitted_rangerestrict the search to the taxa you consider modifiable and to plausible value ranges;sparse=True(default) post-processes each counterfactual to a near-minimal set of changes that still flips the prediction, so you get “change these few taxa” instead of “change everything”.
Because DiCE searches for counterfactuals in the model’s input space, pass
model,queryandbackground_datain the same feature space the model was trained on (e.g. CLR-transformed features, if the model was fit on CLR-transformed data).- Parameters:
model (Any) – A fitted, sklearn-compatible classifier (e.g. a
MicrobiomeClassifieror a bare sklearn estimator) exposingpredict/predict_proba.query (pd.DataFrame) – Sample(s) to explain, as one or more rows with the same feature columns as
background_data.background_data (pd.DataFrame) – Training features (samples x features) used to describe the data distribution DiCE samples from.
y (pd.Series, pd.DataFrame, or array-like) – Training targets aligned with
background_data.target_column (str, default="outcome") – Name DiCE uses for the outcome column internally. Only needs to differ from the feature names; it is not a column in
query.total_CFs (int, default=5) – Number of counterfactuals to generate per query sample.
desired_class (str, default="opposite") – Target class for the counterfactuals (“opposite” flips the prediction).
features_to_vary (str or list of str, default="all") – Which features DiCE may change. Pass a list to restrict the search to modifiable taxa (e.g. diet-associated genera).
permitted_range (dict, optional) – Per-feature
{name: [min, max]}bounds constraining counterfactual values to a plausible range.sparse (bool, default=True) – If True, greedily reduce each counterfactual to a near-minimal set of changes that preserves the flipped prediction.
class_names (list of str, optional) – Human-readable class labels (indexed by integer class) for the summary.
continuous_features (list of str, optional) – Feature names to treat as continuous. Defaults to all columns of
background_data(appropriate for abundance / CLR features).method (str, default="genetic") – DiCE search method (“genetic”, “random”, or “kdtree”).
backend (str, default="sklearn") – DiCE model backend.
return_raw (bool, default=False) – If True, return the raw
dice_mlexplanation object instead of aCounterfactualResult.**kwargs (
Any) – Additional arguments forwarded todice_ml.Dice.generate_counterfactuals.
- Returns:
One result per query sample (a single result if
queryhas one row). Only genuine counterfactuals — those that actually flip the prediction — are kept; DiCE rows that fail to flip are discarded. Each result exposes.changes(),.n_changes,.validityand.summary(). Ifreturn_raw=True, the raw DiCE object is returned instead.- Return type:
CounterfactualResult or list of CounterfactualResult
- Raises:
ImportError – If the optional
explainabilityextra (dice-ml) is not installed.
Examples
>>> import microfactual as mf >>> model = mf.MicrobiomeClassifier(preprocessing=None).fit(X_clr, y) >>> cf = mf.explain_counterfactual(model, X_clr.iloc[[0]], X_clr, y) >>> print(cf.summary()) >>> cf.changes()
- microfactual.explainability.plausible_range(X, y, reference_class, *, q=(0.05, 0.95), features=None)
Per-feature
[low, high]bounds from a reference class’s quantiles.Feed the result to
explain_counterfactual(..., permitted_range=...)so counterfactuals are confined to values actually observed in the reference (e.g. control) class, rather than extrapolating to implausible extremes.- Parameters:
X (pd.DataFrame) – Feature matrix (samples x features), in the model’s input space.
y (array-like) – Class labels aligned with
X.reference_class (Any) – The label value in
ywhose distribution defines “plausible”.q (tuple of float, default=(0.05, 0.95)) – Lower/upper quantiles used as the bounds.
features (list of str, optional) – Restrict to these features; defaults to all columns of
X.
- Returns:
{feature: [low, high]}suitable for DiCE’spermitted_range.- Return type:
dict
Base interface for all explanation methods.
Decouples the core library from specific explainability frameworks.
- class microfactual.explainability.base.BaseExplainer(model, data, **kwargs)
Bases:
ABCAbstract base class for model explainers.
- abstractmethod explain(query_instance, **kwargs)
Generate explanations for a query instance.
- Parameters:
query_instance (pd.DataFrame) – Instance(s) to explain.
**kwargs – Additional parameters for generating the explanation.
- Returns:
The explanation object (framework specific).
- Return type:
Any
Counterfactual explanations using DiCE.
- class microfactual.explainability.counterfactuals.DiCEExplainer(model, background_data, target_column, target_data=None, backend='sklearn', continuous_features=None, **kwargs)
Bases:
BaseExplainerWrapper for DiCE (Diverse Counterfactual Explanations).
Generates counterfactual examples: “What changes to the input would flip the model prediction?”
- explain(query_instance, total_CFs=5, desired_class='opposite', **kwargs)
Generate counterfactual explanations.
- Parameters:
query_instance (pd.DataFrame) – The instance to explain.
total_CFs (int, default=5) – Number of counterfactuals to generate.
desired_class (str, default="opposite") – Desired target class (“opposite” or specific class index).
**kwargs – Additional parameters passed to exp.generate_counterfactuals()
- Returns:
The explanation object containing counterfactuals.
- Return type:
dice_ml.counterfactual_explanations.CounterfactualExplanations
- microfactual.explainability.counterfactuals.counterfactual_importance(model, X, y, *, background_data=None, target_column='outcome', total_CFs=3, desired_class='opposite', features_to_vary='all', permitted_range=None, sparse=True, method='genetic', backend='sklearn', top_n=None, **kwargs)
Aggregate counterfactuals across a cohort into per-taxon importance.
Generates counterfactuals for every sample in
Xand summarises how often each taxon has to change to flip predictions, and in which direction. This is a local-aggregated importance: unlike a global feature-importance score, it reflects the taxa that actually drive individual decisions across the cohort, with an interpretable direction of change.As with
explain_counterfactual(), pass everything in the model’s input feature space (e.g. CLR).- Parameters:
model (Any) – Fitted, sklearn-compatible classifier.
X (pd.DataFrame) – Samples to explain (samples x features).
y (pd.Series, pd.DataFrame, or array-like) – Targets aligned with
background_data.background_data (pd.DataFrame, optional) – Distribution DiCE samples from; defaults to
Xitself.target_column (str, default="outcome") – See
explain_counterfactual().total_CFs (int, default=3) – Counterfactuals generated per sample before aggregation.
desired_class (str, default="opposite") – See
explain_counterfactual().features_to_vary (str or list of str, default="all") – See
explain_counterfactual().permitted_range (dict, optional) – See
explain_counterfactual().sparse (bool, default=True) – See
explain_counterfactual().method (str, default="genetic") – See
explain_counterfactual().backend (str, default="sklearn") – See
explain_counterfactual().top_n (int, optional) – If given, return only the
top_nmost frequently implicated taxa.**kwargs (
Any) – Forwarded todice_ml.Dice.generate_counterfactuals.
- Returns:
One row per implicated taxon, sorted by how many samples implicate it. Columns:
feature,n_samples(samples whose counterfactuals change it),frequency(fraction of explained samples),mean_delta(mean signed change, averaged per sample),direction(net “increase”/ “decrease”).- Return type:
pd.DataFrame
- microfactual.explainability.counterfactuals.explain_counterfactual(model, query, background_data, y, *, target_column='outcome', total_CFs=5, desired_class='opposite', features_to_vary='all', permitted_range=None, sparse=True, class_names=None, continuous_features=None, method='genetic', backend='sklearn', return_raw=False, **kwargs)
Generate actionable counterfactual explanations for one or more samples.
This is MicroFactual’s headline entry point: it answers “what minimal change in feature values would flip this sample’s prediction?” in a single call, wrapping
DiCEExplainer.Two features make the result actionable rather than a wall of numbers:
features_to_vary/permitted_rangerestrict the search to the taxa you consider modifiable and to plausible value ranges;sparse=True(default) post-processes each counterfactual to a near-minimal set of changes that still flips the prediction, so you get “change these few taxa” instead of “change everything”.
Because DiCE searches for counterfactuals in the model’s input space, pass
model,queryandbackground_datain the same feature space the model was trained on (e.g. CLR-transformed features, if the model was fit on CLR-transformed data).- Parameters:
model (Any) – A fitted, sklearn-compatible classifier (e.g. a
MicrobiomeClassifieror a bare sklearn estimator) exposingpredict/predict_proba.query (pd.DataFrame) – Sample(s) to explain, as one or more rows with the same feature columns as
background_data.background_data (pd.DataFrame) – Training features (samples x features) used to describe the data distribution DiCE samples from.
y (pd.Series, pd.DataFrame, or array-like) – Training targets aligned with
background_data.target_column (str, default="outcome") – Name DiCE uses for the outcome column internally. Only needs to differ from the feature names; it is not a column in
query.total_CFs (int, default=5) – Number of counterfactuals to generate per query sample.
desired_class (str, default="opposite") – Target class for the counterfactuals (“opposite” flips the prediction).
features_to_vary (str or list of str, default="all") – Which features DiCE may change. Pass a list to restrict the search to modifiable taxa (e.g. diet-associated genera).
permitted_range (dict, optional) – Per-feature
{name: [min, max]}bounds constraining counterfactual values to a plausible range.sparse (bool, default=True) – If True, greedily reduce each counterfactual to a near-minimal set of changes that preserves the flipped prediction.
class_names (list of str, optional) – Human-readable class labels (indexed by integer class) for the summary.
continuous_features (list of str, optional) – Feature names to treat as continuous. Defaults to all columns of
background_data(appropriate for abundance / CLR features).method (str, default="genetic") – DiCE search method (“genetic”, “random”, or “kdtree”).
backend (str, default="sklearn") – DiCE model backend.
return_raw (bool, default=False) – If True, return the raw
dice_mlexplanation object instead of aCounterfactualResult.**kwargs (
Any) – Additional arguments forwarded todice_ml.Dice.generate_counterfactuals.
- Returns:
One result per query sample (a single result if
queryhas one row). Only genuine counterfactuals — those that actually flip the prediction — are kept; DiCE rows that fail to flip are discarded. Each result exposes.changes(),.n_changes,.validityand.summary(). Ifreturn_raw=True, the raw DiCE object is returned instead.- Return type:
CounterfactualResult or list of CounterfactualResult
- Raises:
ImportError – If the optional
explainabilityextra (dice-ml) is not installed.
Examples
>>> import microfactual as mf >>> model = mf.MicrobiomeClassifier(preprocessing=None).fit(X_clr, y) >>> cf = mf.explain_counterfactual(model, X_clr.iloc[[0]], X_clr, y) >>> print(cf.summary()) >>> cf.changes()
Structured, interpretable counterfactual results.
Wraps the raw DiCE output into an object that answers the questions a user actually has: which taxa changed, by how much, in which direction, and does the counterfactual really flip the model’s prediction?
- class microfactual.explainability.result.CounterfactualResult(original, counterfactuals, model, feature_names, class_names=None, raw=None, atol=1e-08)
Bases:
objectInterpretable wrapper around a set of counterfactuals for one sample.
- Parameters:
original (array-like) – The query sample’s feature values.
counterfactuals (array-like) – Counterfactual rows (n_cfs x n_features), already sparsified if desired.
model (Any) – Fitted classifier used to (re)validate predictions.
feature_names (list of str) – Names of the features, in column order.
class_names (list of str, optional) – Human-readable class labels, indexed by predicted integer class.
raw (Any, optional) – The underlying DiCE explanation object, kept for advanced use.
atol (float, default=1e-8) – Tolerance below which a feature is considered unchanged.
- changes(cf_index=None)
Return the per-feature changes for one or all counterfactuals.
- Parameters:
cf_index (int, optional) – If given, return changes for that single counterfactual. Otherwise return the changes for all counterfactuals stacked, with a
cfcolumn identifying each.- Returns:
Columns:
cf(omitted whencf_indexgiven),feature,original,counterfactual,delta,direction. Only rows where the feature actually changed are included, sorted by descending absolute change.- Return type:
pd.DataFrame
- property n_changes: list[int]
Number of features changed by each counterfactual.
- property n_counterfactuals: int
Number of counterfactuals held.
- property original_prediction: int
Predicted class for the original sample.
- summary()
Return a short human-readable summary of the counterfactuals.
- Return type:
str
- property validity: float
Fraction of counterfactuals that actually flip the prediction.
- visualize_as_dataframe(*args, **kwargs)
Delegate to the underlying DiCE explanation’s visualizer, if present.
- Return type:
Any
- microfactual.explainability.result.sparsify_counterfactual(original, counterfactual, model, atol=1e-08)
Greedily revert changed features while preserving the flipped prediction.
DiCE (especially the genetic method on continuous features) often perturbs every feature. This reduces a counterfactual to a near-minimal set of changes: changed features are reverted to their original value one at a time, smallest change first, keeping a revert only when the model’s prediction is unchanged. The result is a sparse, actionable counterfactual.
- Parameters:
original (np.ndarray) – The original sample’s feature values (1D).
counterfactual (np.ndarray) – The counterfactual feature values (1D, same order as
original).model (Any) – Fitted classifier exposing
predicton a 2D array.atol (float, default=1e-8) – Absolute tolerance below which a feature is considered unchanged.
- Returns:
A sparsified counterfactual with the same predicted class as the input counterfactual.
- Return type:
np.ndarray
Reference-class plausibility helpers for counterfactuals.
Vanilla DiCE can propose counterfactual values far outside anything seen in the
data. These helpers (1) derive a plausible value range from a reference class to
constrain the search (permitted_range), and (2) score how well a
counterfactual moves a sample toward that reference class.
- microfactual.explainability.plausibility.counterfactual_concordance(result, X, y, reference_class)
Fraction of changed taxa whose counterfactual moves toward the reference.
For each changed taxon, checks whether the counterfactual’s change is in the same direction as the gap between the sample’s original value and the reference-class median. A high score means the counterfactual shifts the sample toward the reference distribution rather than in some arbitrary model-exploiting direction — a cheap plausibility signal.
- Parameters:
result (CounterfactualResult) – A result from
explain_counterfactual().X (pd.DataFrame) – Feature matrix used to compute the reference median.
y (array-like) – Class labels aligned with
X.reference_class (Any) – The label value in
yto move toward.
- Returns:
Concordance in
[0, 1], ornanif there are no changes.- Return type:
float
- microfactual.explainability.plausibility.plausible_range(X, y, reference_class, *, q=(0.05, 0.95), features=None)
Per-feature
[low, high]bounds from a reference class’s quantiles.Feed the result to
explain_counterfactual(..., permitted_range=...)so counterfactuals are confined to values actually observed in the reference (e.g. control) class, rather than extrapolating to implausible extremes.- Parameters:
X (pd.DataFrame) – Feature matrix (samples x features), in the model’s input space.
y (array-like) – Class labels aligned with
X.reference_class (Any) – The label value in
ywhose distribution defines “plausible”.q (tuple of float, default=(0.05, 0.95)) – Lower/upper quantiles used as the bounds.
features (list of str, optional) – Restrict to these features; defaults to all columns of
X.
- Returns:
{feature: [low, high]}suitable for DiCE’spermitted_range.- Return type:
dict
Visualization
Visualization module for microfactual.
- microfactual.visualization.explore(data, abundance_cutoff=1e-06, prevalence_cutoff=0.01, figsize=(16, 4))
Render a cutoff-diagnostics panel for a microbiome dataset.
Combines the abundance histogram, prevalence histogram, and the joint prevalence-vs-abundance scatter into one figure, all sharing the proposed
AbundanceFilter/PrevalenceFiltercutoffs, so you can eyeball whether the defaults suit your data before fitting a model.- Parameters:
data (MicrobiomeDataset or pd.DataFrame) – Data to summarise (a
MicrobiomeDatasetor a features x samples abundance DataFrame).abundance_cutoff (float, optional) – Proposed abundance cutoff (matches
AbundanceFilter(min_abundance=...)).prevalence_cutoff (float, optional) – Proposed prevalence cutoff (matches
PrevalenceFilter(min_prevalence=...)).figsize (tuple of float, default=(16, 4)) – Figure size in inches.
- Returns:
The assembled 1x3 panel figure.
- Return type:
matplotlib.figure.Figure
- microfactual.visualization.plot_abundance_histogram(data, abundance_cutoff=1e-06, ax=None, bins=50)
Histogram of per-taxon mean abundance on a log10 axis.
Microbiome abundances span many orders of magnitude and the distribution is often bimodal; the trough is a natural place to set the abundance cutoff.
- Parameters:
data (MicrobiomeDataset or pd.DataFrame) – Data to summarise (see
_get_abundance()).abundance_cutoff (float, optional) – If given, draw a vertical line at this abundance and annotate how many taxa fall at or above it.
ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure/axes is created if omitted.
bins (int, default=50) – Number of histogram bins.
- Returns:
The axes containing the plot.
- Return type:
matplotlib.axes.Axes
- microfactual.visualization.plot_confusion_matrix(y_true, y_pred, labels=None, title='Confusion Matrix', cmap='Blues')
Plot confusion matrix.
- Parameters:
y_true (array-like) – True class labels.
y_pred (array-like) – Predicted class labels.
labels (list of str, optional) – Display labels for classes.
title (str, default="Confusion Matrix") – Plot title.
cmap (str, default="Blues") – Colormap for the matrix.
- Returns:
fig – The matplotlib figure object.
- Return type:
matplotlib.figure.Figure
Examples
>>> fig = plot_confusion_matrix(y_test, y_pred, labels=["Healthy", "Disease"])
- microfactual.visualization.plot_counterfactual_heatmap(result, X, y, *, reference_class, comparison_class=None, cf_index=0, top_n=15, ax=None)
Heatmap of a counterfactual against class-reference distributions.
For the taxa a counterfactual changes, shows the sample’s original value, the counterfactual value, and the class medians — all expressed in reference-class standard deviations (0 = reference-class centre). This makes it easy to see whether the counterfactual moves the sample toward the reference (e.g. control) distribution, and whether it overshoots into implausible territory. The title reports the concordance-with-reference score.
- Parameters:
result (CounterfactualResult) – A result from
explain_counterfactual().X (pd.DataFrame) – Feature matrix (samples x features) used to compute class references.
y (array-like) – Class labels aligned with
X.reference_class (Any) – Label value in
yto treat as the reference (e.g. the control/healthy class the counterfactual should move toward).comparison_class (Any, optional) – A second class whose median is shown for contrast (e.g. the disease class). If None, only the reference median is shown.
cf_index (int, default=0) – Which counterfactual (row) of
resultto display.top_n (int, optional) – Show only the
top_ntaxa with the largest absolute change. None shows all changed taxa.ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure/axes is created if omitted.
- Returns:
The axes containing the heatmap.
- Return type:
matplotlib.axes.Axes
- microfactual.visualization.plot_feature_importance(importance, feature_names=None, top_n=None, title='Feature Importance')
Plot feature importance as horizontal bar chart.
- Parameters:
importance (pd.Series, np.ndarray, or model with
feature_importances_) – Feature importance scores. Can be: - pd.Series with feature names as index - np.ndarray (requires feature_names) - Model object with afeature_importances_attributefeature_names (list of str, optional) – Feature names (required if importance is array or model).
top_n (int, optional) – Show only top N most important features.
title (str, default="Feature Importance") – Plot title.
- Returns:
fig – The matplotlib figure object.
- Return type:
matplotlib.figure.Figure
Examples
>>> fig = plot_feature_importance(model.feature_importances_, feature_names) >>> fig = plot_feature_importance(importance_series, top_n=20)
- microfactual.visualization.plot_prevalence_abundance(data, abundance_cutoff=1e-06, prevalence_cutoff=0.01, ax=None)
Joint scatter of per-taxon prevalence vs. mean abundance.
Each point is one taxon. With both cutoffs supplied, the retained region is shaded and the number of surviving taxa is annotated — the clearest single view for choosing both filters together.
- Parameters:
data (MicrobiomeDataset or pd.DataFrame) – Data to summarise.
abundance_cutoff (float, optional) – Abundance threshold; drawn as a vertical line.
prevalence_cutoff (float, optional) – Prevalence threshold; drawn as a horizontal line.
ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure/axes is created if omitted.
- Returns:
The axes containing the plot.
- Return type:
matplotlib.axes.Axes
- microfactual.visualization.plot_prevalence_histogram(data, prevalence_cutoff=0.01, ax=None, bins=50)
Histogram of per-taxon prevalence (fraction of samples present).
Prevalence distributions are typically U-shaped (taxa present in almost no samples or almost all). The plot helps place the prevalence cutoff.
- Parameters:
data (MicrobiomeDataset or pd.DataFrame) – Data to summarise.
prevalence_cutoff (float, optional) – If given, draw a vertical line at this prevalence and annotate how many taxa fall at or above it.
ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure/axes is created if omitted.
bins (int, default=50) – Number of histogram bins.
- Returns:
The axes containing the plot.
- Return type:
matplotlib.axes.Axes
- microfactual.visualization.plot_roc(y_true, y_proba, title='ROC Curve')
Plot ROC curve with AUC score.
- Parameters:
y_true (array-like) – True binary labels.
y_proba (array-like) – Predicted probabilities for the positive class.
title (str, default="ROC Curve") – Plot title.
- Returns:
fig – The matplotlib figure object.
- Return type:
matplotlib.figure.Figure
Examples
>>> fig = plot_roc(y_test, model.predict_proba(X_test)[:, 1]) >>> fig.savefig("roc.png")
Visualizations for counterfactual explanations.
- microfactual.visualization.counterfactual_plots.plot_counterfactual_heatmap(result, X, y, *, reference_class, comparison_class=None, cf_index=0, top_n=15, ax=None)
Heatmap of a counterfactual against class-reference distributions.
For the taxa a counterfactual changes, shows the sample’s original value, the counterfactual value, and the class medians — all expressed in reference-class standard deviations (0 = reference-class centre). This makes it easy to see whether the counterfactual moves the sample toward the reference (e.g. control) distribution, and whether it overshoots into implausible territory. The title reports the concordance-with-reference score.
- Parameters:
result (CounterfactualResult) – A result from
explain_counterfactual().X (pd.DataFrame) – Feature matrix (samples x features) used to compute class references.
y (array-like) – Class labels aligned with
X.reference_class (Any) – Label value in
yto treat as the reference (e.g. the control/healthy class the counterfactual should move toward).comparison_class (Any, optional) – A second class whose median is shown for contrast (e.g. the disease class). If None, only the reference median is shown.
cf_index (int, default=0) – Which counterfactual (row) of
resultto display.top_n (int, optional) – Show only the
top_ntaxa with the largest absolute change. None shows all changed taxa.ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure/axes is created if omitted.
- Returns:
The axes containing the heatmap.
- Return type:
matplotlib.axes.Axes