pub use crate::interpretability::{
ActionableInsight,
AttentionAnalysisResult,
AttentionBottleneck,
AttentionFlowAnalysis,
AttentionFlowPath,
AttentionHeadResult,
AttentionInsight,
AttentionLayerResult,
AttentionPatterns,
AttentionStatistics,
AttributionMethod,
AttributionMethodResult,
AttributionVisualizationData,
BlockPattern,
BottleneckType,
BoundaryCrossingPoint,
ChangeDirection,
Counterfactual,
CounterfactualQualityMetrics,
CounterfactualResult,
DecisionBoundaryAnalysis,
DiagonalPattern,
FeatureAttribution,
FeatureAttributionResult,
FeatureChange,
FeatureContribution,
FeatureImportance,
FeatureInteraction,
FeatureSensitivityAnalysis,
FlowEfficiencyMetrics,
FlowTransformation,
HeadCluster,
HeadRedundancyAnalysis,
HeadSpecializationAnalysis,
HeadSpecializationType,
ImplementationDifficulty,
InsightType,
InteractionEffect,
InteractionEffectType,
InteractionType,
InterpretabilityAnalyzer,
InterpretabilityConfig,
InterpretabilityReport,
LayerAttentionPatterns,
LayerAttentionStats,
LayerFlowStats,
LayerFlowStep,
LimeAnalysisResult,
MethodAgreementAnalysis,
NeighborhoodStats,
PerturbationAnalysis,
PerturbationResult,
PruningImpact,
PruningRecommendation,
RedundancyType,
RedundantHeadPair,
RepetitivePattern,
RiskLevel,
ShapAnalysisResult,
ShapSummary,
SparsityDistribution,
SpecializationEvolution,
SpecializationTransition,
SpecializationTrend,
ThresholdAnalysis,
TimeHorizon,
TimelinePoint,
TokenAttentionScore,
TopFeature,
VerticalPattern,
};
#[cfg(test)]
mod tests {
use crate::interpretability::{
AttributionMethod, InterpretabilityAnalyzer, InterpretabilityConfig,
};
use std::collections::HashMap;
#[tokio::test]
async fn test_interpretability_analyzer_creation() {
let config = InterpretabilityConfig::default();
let _analyzer = InterpretabilityAnalyzer::new(config);
}
#[tokio::test]
async fn test_shap_analysis() {
let config = InterpretabilityConfig::default();
let mut analyzer = InterpretabilityAnalyzer::new(config);
let mut instance = HashMap::new();
instance.insert("feature1".to_string(), 1.0);
instance.insert("feature2".to_string(), 2.0);
let model_predictions = vec![0.8, 0.7, 0.9];
let background_data = vec![{
let mut bg = HashMap::new();
bg.insert("feature1".to_string(), 0.5);
bg.insert("feature2".to_string(), 1.0);
bg
}];
let result = analyzer.analyze_shap(&instance, &model_predictions, &background_data).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_lime_analysis() {
let config = InterpretabilityConfig::default();
let mut analyzer = InterpretabilityAnalyzer::new(config);
let mut instance = HashMap::new();
instance.insert("feature1".to_string(), 1.0);
instance.insert("feature2".to_string(), 2.0);
let model_fn: Box<dyn Fn(&HashMap<String, f64>) -> f64> =
Box::new(|input: &HashMap<String, f64>| input.values().sum::<f64>() * 0.1);
let result = analyzer.analyze_lime(&instance, model_fn).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_feature_attribution_integrated_gradients() {
let config = InterpretabilityConfig {
enable_feature_attribution: true,
attribution_methods: vec![AttributionMethod::IntegratedGradients],
..InterpretabilityConfig::default()
};
let mut analyzer = InterpretabilityAnalyzer::new(config);
let mut instance = HashMap::new();
instance.insert("feature1".to_string(), 0.5);
instance.insert("feature2".to_string(), 1.5);
instance.insert("feature3".to_string(), 2.0);
let model_predictions = vec![0.7, 0.6, 0.8];
let background_data = vec![{
let mut bg = HashMap::new();
bg.insert("feature1".to_string(), 0.0);
bg.insert("feature2".to_string(), 0.0);
bg.insert("feature3".to_string(), 0.0);
bg
}];
let result = analyzer.analyze_shap(&instance, &model_predictions, &background_data).await;
assert!(result.is_ok());
let shap_result = result.expect("SHAP analysis failed");
assert!(
!shap_result.feature_contributions.is_empty(),
"attributions must be non-empty"
);
}
}