Skip to main content

RelationExtractor

Trait RelationExtractor 

Source
pub trait RelationExtractor: Send + Sync {
    // Required method
    fn extract_with_relations(
        &self,
        text: &str,
        entity_types: &[&str],
        relation_types: &[&str],
        threshold: f32,
    ) -> Result<ExtractionWithRelations, Error>;
}
Expand description

Joint entity and relation extraction.

§Motivation

Real-world information extraction often requires both entities AND their relationships. For example, extracting “Steve Jobs” and “Apple” is useful, but knowing “Steve Jobs FOUNDED Apple” is far more valuable.

Joint extraction (vs pipeline) is preferred because:

  • Error propagation: Pipeline errors compound (bad entities → bad relations)
  • Shared context: Entities and relations inform each other
  • Efficiency: Single forward pass instead of two

§Architecture

Input: "Steve Jobs founded Apple in 1976."
               │
               ▼
┌──────────────────────────────────┐
│     Shared Encoder (BERT)        │
└──────────────────────────────────┘
               │
        ┌──────┴──────┐
        ▼             ▼
┌───────────────┐  ┌───────────────┐
│ Entity Head   │  │ Relation Head │
│ (span class.) │  │ (pair class.) │
└───────┬───────┘  └───────┬───────┘
        │                  │
        ▼                  ▼
Entities:              Relations:
- Steve Jobs [PER]     - (Steve Jobs, FOUNDED, Apple)
- Apple [ORG]          - (Apple, FOUNDED_IN, 1976)
- 1976 [DATE]

§Research Alignment

From GLiNER multi-task (arXiv:2406.12925):

“Generalist Lightweight Model for Various Information Extraction Tasks… joint entity and relation extraction.”

From W2NER (arXiv:2112.10070):

“Unified Named Entity Recognition as Word-Word Relation Classification… handles flat, overlapped, and discontinuous NER.”

§Example

use anno::RelationExtractor;

fn build_knowledge_graph(extractor: &dyn RelationExtractor, text: &str) {
    let entity_types = &["person", "organization", "date"];
    let relation_types = &["founded", "works_for", "acquired"];

    let result = extractor.extract_with_relations(
        text, entity_types, relation_types, 0.5
    ).unwrap();

    // Build graph nodes from entities
    for e in &result.entities {
        println!("Node: {} ({})", e.text, e.entity_type);
    }

    // Build graph edges from relations
    for r in &result.relations {
        let head = &result.entities[r.head_idx];
        let tail = &result.entities[r.tail_idx];
        println!("Edge: {} --[{}]--> {}", head.text, r.relation_type, tail.text);
    }
}

Required Methods§

Source

fn extract_with_relations( &self, text: &str, entity_types: &[&str], relation_types: &[&str], threshold: f32, ) -> Result<ExtractionWithRelations, Error>

Extract entities and relations jointly.

§Arguments
  • text - Input text
  • entity_types - Entity types to extract
  • relation_types - Relation types to extract
  • threshold - Confidence threshold
§Returns

Entities and relations between them

Implementors§

Source§

impl RelationExtractor for GLiNER2Onnx

Available on crate feature onnx only.
Source§

impl RelationExtractor for TPLinker