sevensense-interpretation

Crates.iosevensense-interpretation
lib.rssevensense-interpretation
version0.1.0
created_at2026-01-16 13:51:28.965868+00
updated_at2026-01-16 13:51:28.965868+00
descriptionLLM-powered interpretation for 7sense bioacoustics platform
homepage
repositoryhttps://github.com/ruvnet/ruvector
max_upload_size
id2048637
size165,467
rUv (ruvnet)

documentation

README

sevensense-interpretation

Crate Docs License

Evidence-based interpretation and explanation generation for bioacoustic AI.

sevensense-interpretation generates human-readable explanations for AI predictions. Using the RAB (Reasoning, Accountability, Believability) framework, it produces "evidence packs" that document why a species was identified, what features contributed to the decision, and how confident the system is—essential for scientific credibility and regulatory compliance.

Features

  • RAB Evidence Packs: Structured explanation documents
  • Confidence Scoring: Multi-factor confidence with breakdowns
  • Feature Attribution: Which acoustic features drove predictions
  • Uncertainty Quantification: Epistemic vs. aleatoric uncertainty
  • Natural Language: Human-readable narratives
  • Audit Trails: Complete decision provenance

Use Cases

Use Case Description Key Functions
Evidence Generation Create explanation packs EvidencePack::generate()
Confidence Scoring Multi-factor confidence ConfidenceScorer::score()
Feature Attribution Explain which features matter attribute_features()
Narrative Generation Human-readable explanations generate_narrative()
Audit Export Compliance documentation export_audit_trail()

Installation

Add to your Cargo.toml:

[dependencies]
sevensense-interpretation = "0.1"

Quick Start

use sevensense_interpretation::{EvidenceGenerator, EvidenceConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create evidence generator
    let generator = EvidenceGenerator::new(EvidenceConfig::default());

    // Generate evidence pack for a prediction
    let evidence = generator.generate(
        &query_embedding,
        &prediction,
        &neighbors,
        &cluster_info,
    )?;

    println!("Confidence: {:.1}%", evidence.confidence * 100.0);
    println!("Reasoning: {}", evidence.narrative);
    println!("Key features: {:?}", evidence.top_features);

    Ok(())
}

Tutorial: Generating Evidence Packs

Basic Evidence Generation

use sevensense_interpretation::{EvidenceGenerator, EvidenceConfig, Prediction};

let config = EvidenceConfig {
    include_neighbors: true,
    include_features: true,
    include_uncertainty: true,
    narrative_style: NarrativeStyle::Scientific,
};

let generator = EvidenceGenerator::new(config);

// Prediction to explain
let prediction = Prediction {
    species_id: "Turdus merula".into(),
    confidence: 0.94,
    embedding: query_embedding.clone(),
};

// Generate evidence
let evidence = generator.generate(
    &prediction,
    &neighbors,      // Similar examples from index
    &cluster_info,   // Clustering context
)?;

println!("{}", evidence.to_json()?);

Evidence Pack Structure

// The EvidencePack contains:
println!("=== Evidence Pack ===");
println!("Prediction: {}", evidence.prediction.species_id);
println!("Overall Confidence: {:.1}%", evidence.overall_confidence * 100.0);

println!("\nConfidence Breakdown:");
println!("  Neighbor Agreement: {:.1}%", evidence.breakdown.neighbor_agreement * 100.0);
println!("  Cluster Membership: {:.1}%", evidence.breakdown.cluster_membership * 100.0);
println!("  Embedding Quality: {:.1}%", evidence.breakdown.embedding_quality * 100.0);

println!("\nSupporting Evidence:");
for (i, neighbor) in evidence.neighbors.iter().take(3).enumerate() {
    println!("  {}. {} (similarity: {:.3})",
        i + 1, neighbor.species_id, neighbor.similarity);
}

println!("\nNarrative:");
println!("{}", evidence.narrative);
Tutorial: Confidence Scoring

Multi-Factor Confidence

use sevensense_interpretation::{ConfidenceScorer, ConfidenceConfig};

let config = ConfidenceConfig {
    neighbor_weight: 0.4,      // Weight for neighbor agreement
    cluster_weight: 0.3,       // Weight for cluster membership
    quality_weight: 0.3,       // Weight for embedding quality
};

let scorer = ConfidenceScorer::new(config);

let score = scorer.score(
    &prediction,
    &neighbors,
    &cluster_info,
)?;

println!("Overall: {:.3}", score.overall);
println!("Components:");
println!("  Neighbor Agreement: {:.3}", score.neighbor_agreement);
println!("  Cluster Membership: {:.3}", score.cluster_membership);
println!("  Embedding Quality: {:.3}", score.embedding_quality);

Confidence Calibration

use sevensense_interpretation::{ConfidenceCalibrator, CalibrationData};

// Calibrate confidence scores using validation data
let calibrator = ConfidenceCalibrator::train(&validation_predictions)?;

// Apply calibration
let raw_confidence = 0.85;
let calibrated = calibrator.calibrate(raw_confidence);

println!("Raw: {:.2}, Calibrated: {:.2}", raw_confidence, calibrated);

// Calibration diagnostics
let diagnostics = calibrator.diagnostics();
println!("ECE (Expected Calibration Error): {:.4}", diagnostics.ece);
println!("MCE (Maximum Calibration Error): {:.4}", diagnostics.mce);

Uncertainty Decomposition

use sevensense_interpretation::{UncertaintyEstimator, UncertaintyType};

let estimator = UncertaintyEstimator::new();

let uncertainty = estimator.estimate(&prediction, &neighbors)?;

println!("Total Uncertainty: {:.3}", uncertainty.total);
println!("  Epistemic (model uncertainty): {:.3}", uncertainty.epistemic);
println!("  Aleatoric (data uncertainty): {:.3}", uncertainty.aleatoric);

// Interpretation
if uncertainty.epistemic > uncertainty.aleatoric {
    println!("High epistemic uncertainty: model needs more training data");
} else {
    println!("High aleatoric uncertainty: inherently ambiguous input");
}
Tutorial: Feature Attribution

Identifying Important Features

use sevensense_interpretation::{FeatureAttributor, AttributionMethod};

let attributor = FeatureAttributor::new(AttributionMethod::Gradient);

// Get feature importance scores
let attributions = attributor.attribute(
    &model,
    &query_embedding,
    &prediction,
)?;

println!("Top 10 most important embedding dimensions:");
let mut sorted: Vec<_> = attributions.iter().enumerate().collect();
sorted.sort_by(|a, b| b.1.abs().partial_cmp(&a.1.abs()).unwrap());

for (dim, importance) in sorted.iter().take(10) {
    println!("  Dimension {}: {:.4}", dim, importance);
}

Acoustic Feature Mapping

use sevensense_interpretation::{AcousticFeatureMapper, AcousticFeature};

let mapper = AcousticFeatureMapper::new();

// Map embedding dimensions to acoustic features
let acoustic_attributions = mapper.map_to_acoustic(&attributions)?;

println!("Important acoustic features:");
for (feature, importance) in acoustic_attributions.iter().take(5) {
    println!("  {:?}: {:.3}", feature, importance);
}
// Output example:
//   Frequency Range (2-4 kHz): 0.342
//   Temporal Modulation: 0.287
//   Harmonic Structure: 0.156

Contrastive Explanations

use sevensense_interpretation::ContrastiveExplainer;

let explainer = ContrastiveExplainer::new();

// Why species A and not species B?
let explanation = explainer.explain(
    &query_embedding,
    "Turdus merula",    // Predicted
    "Turdus philomelos", // Alternative
)?;

println!("Why {} and not {}?", explanation.predicted, explanation.contrast);
println!("Key differences:");
for diff in &explanation.differences {
    println!("  {}: {:.3} vs {:.3}",
        diff.feature, diff.predicted_value, diff.contrast_value);
}
Tutorial: Narrative Generation

Scientific Narratives

use sevensense_interpretation::{NarrativeGenerator, NarrativeStyle};

let generator = NarrativeGenerator::new(NarrativeStyle::Scientific);

let narrative = generator.generate(&evidence)?;

println!("{}", narrative);
// Output:
// "The audio segment was classified as Turdus merula (Eurasian Blackbird)
// with 94.2% confidence. This classification is supported by high similarity
// (>0.90) to 8 confirmed Turdus merula recordings in the reference database.
// The embedding falls within the core region of the Turdus merula cluster
// (silhouette score: 0.87). Key discriminating features include the
// characteristic frequency range (2.1-4.3 kHz) and the presence of
// melodic phrases with harmonic structure typical of the species."

Conversational Narratives

let generator = NarrativeGenerator::new(NarrativeStyle::Conversational);

let narrative = generator.generate(&evidence)?;

println!("{}", narrative);
// Output:
// "This sounds like a Eurasian Blackbird! I'm 94% confident because
// it matches several confirmed blackbird recordings in our database.
// The distinctive melodic whistling in the 2-4 kHz range is a classic
// blackbird signature."

Template-Based Narratives

use sevensense_interpretation::{NarrativeTemplate, TemplateEngine};

let template = NarrativeTemplate::new(
    "Species: {{species_name}} ({{confidence}}% confidence). \
     Based on {{neighbor_count}} similar recordings. \
     {{#if low_confidence}}Note: Confidence is below threshold.{{/if}}"
);

let engine = TemplateEngine::new();
let narrative = engine.render(&template, &evidence)?;
Tutorial: Audit Trails

Creating Audit Records

use sevensense_interpretation::{AuditTrail, AuditRecord};

let mut audit = AuditTrail::new();

// Record prediction event
audit.record(AuditRecord::Prediction {
    timestamp: Utc::now(),
    input_hash: hash(&audio_data),
    prediction: prediction.clone(),
    confidence: 0.94,
    model_version: "perch-2.0".into(),
});

// Record evidence generation
audit.record(AuditRecord::Evidence {
    timestamp: Utc::now(),
    prediction_id: prediction.id,
    evidence_pack: evidence.clone(),
});

Exporting for Compliance

use sevensense_interpretation::{AuditExporter, ExportFormat};

let exporter = AuditExporter::new();

// Export to JSON
let json = exporter.export(&audit, ExportFormat::Json)?;
std::fs::write("audit_trail.json", json)?;

// Export to CSV (for spreadsheet analysis)
let csv = exporter.export(&audit, ExportFormat::Csv)?;
std::fs::write("audit_trail.csv", csv)?;

// Export to PDF report
let pdf = exporter.export(&audit, ExportFormat::Pdf)?;
std::fs::write("audit_report.pdf", pdf)?;

Provenance Tracking

use sevensense_interpretation::ProvenanceTracker;

let tracker = ProvenanceTracker::new();

// Track data lineage
tracker.record_input("recording_001.wav", &audio_metadata)?;
tracker.record_processing("segmentation", &segment_config)?;
tracker.record_processing("embedding", &embedding_config)?;
tracker.record_prediction(&prediction)?;

// Generate provenance graph
let graph = tracker.to_graph()?;
println!("{}", graph.to_dot());  // GraphViz format

Configuration

EvidenceConfig Parameters

Parameter Default Description
include_neighbors true Include similar examples
include_features true Include feature attribution
include_uncertainty true Include uncertainty estimates
narrative_style Scientific Narrative style
max_neighbors 10 Max neighbors to include

ConfidenceConfig Parameters

Parameter Default Description
neighbor_weight 0.4 Neighbor agreement weight
cluster_weight 0.3 Cluster membership weight
quality_weight 0.3 Embedding quality weight

RAB Framework

Component Description Implementation
Reasoning Why was this prediction made? Feature attribution, neighbors
Accountability Who/what is responsible? Audit trails, model versions
Believability How trustworthy is this? Confidence, uncertainty

Links

License

MIT License - see LICENSE for details.


Part of the 7sense Bioacoustic Intelligence Platform by rUv

Commit count: 729

cargo fmt