SDP Causality Extraction
The Shortest Dependency Path (SDP) approach is a classical, linguistically motivated baseline for causal relation extraction. Given a sentence and two candidate entity spans, it finds the shortest path connecting the two entities in the syntactic dependency parse tree and uses that path as the feature representation for a downstream classifier.
The approach was introduced for general relation extraction by [@bunescu:2005] and later applied specifically to causal relations by (Girju 2003)1 and others. It remains a strong, interpretable baseline for the Causality Identification step of the extraction pipeline β it takes two already-known entity spans as input (see Algorithm below), so it has nothing to say about Causal Event Candidate Detection itself. For Causality Detection on an unmarked sentence, see the separate Causal Connective Lexicon baseline instead β the same underlying lexicon, used as a standalone rule rather than as one feature on a dependency path.
Motivation
A dependency parse tree encodes the grammatical structure of a sentence. For a sentence such as
The storm caused significant flooding.
the parse places caused as the root with storm and flooding as its subject and object dependents. The shortest path between storm and flooding passes through caused β the very word that expresses the causal relation.
More formally, the SDP between two node sets \(A\) and \(B\) in the dependency graph \(G\) is
where \(d_G\) is the graph distance in the undirected version of \(G\) and node sets \(A\), \(B\) are the head tokens of each entity span [@bunescu:2005].
This path tends to strip away syntactic material irrelevant to the relation between the two entities, yielding a compact, informative representation.
Algorithm
Input: sentence s, entity spans eβ and eβ
Output: relation label (causal / no-relation)
1. Parse s with a dependency parser (spaCy, Stanza) to obtain tree T.
2. Find the head token hβ of eβ and hβ of eβ using the span's root.
3. Find the shortest path P = (hβ, β¦, hβ) in the undirected T.
4. Encode P as a sequence of (token, dep_label, direction) triples,
where direction β {β, β} indicates whether each arc points toward
or away from the root.
5. Extract features from P (see below).
6. Apply a trained classifier to the feature vector.
Features
Classical (feature-based) encoding
| Feature group | Description |
|---|---|
| Path tokens | Lemmas of tokens on the SDP (bag-of-words or positional) |
| Dependency labels | Sequence of arc labels on the path (e.g. nsubj, obj, prep) |
| Arc directions | Direction of each arc relative to the path traversal (β toward root, β away) |
| Path length | Number of hops β short paths are more reliable [@bunescu:2005] |
| POS tags | Part-of-speech of each node on the path |
| Causal lexicon | Whether any known causal connective (cause, lead to, result in, β¦) appears on the path (Girju 2003)1 β see Causal Lexicon below |
| Entity types | Named-entity labels of \(e_1\) and \(e_2\) (useful when entities are noun phrases) |
A linear SVM trained on these features achieves competitive performance on SemEval-2010 Task 8 [@rink:2010].
Neural encoding
Rather than hand-crafting features, the SDP can be fed directly into a neural sequence model:
- SDP-CNN [@xu:2015a] β convolves over word and position embeddings of the SDP tokens.
- SDP-LSTM [@xu:2015b] β runs a bidirectional LSTM along the path; entity markers at the endpoints help the model locate the relation head. This variant achieves state-of-the-art results on SemEval-2010 Task 8 without additional linguistic features.
Causal Lexicon
Whether a known causal connective appears on (or near) the path is one of the oldest and
cheapest features for causal relation classification (Girju 2003)1. causalatee.nlp.find_causal_connectives
implements this over a small, hand-curated lexicon organized into the categories commonly
distinguished in the discourse-connective literature β causal verbs and nouns (cause, trigger,
result in, factor, consequence), subordinating cue phrases (because, due to, since),
and sentence-linking adverbials (therefore, consequently) β broadly following the connective
categories used by the Penn Discourse TreeBank's Contingency.Cause relation class [@pdtb:2008]
and the causal verb patterns cataloged by (Girju 2003)1. Verbs and nouns are matched by lemma
(one entry, e.g. "lead to", automatically covers every inflection: "leads to"/"led to"/"leading
to"); cue phrases and adverbials are matched as literal surface forms, since they don't
meaningfully inflect.
import spacy
from causalatee.nlp import find_causal_connectives
nlp = spacy.load("en_core_web_sm")
doc = nlp("The storm caused significant flooding.")
for match in find_causal_connectives(doc):
print(match.text, match.category)
# caused verb
A connective match is a candidate signal, not proof of a causal relation. Several entries in the lexicon are highly ambiguous outside of context β since and as are far more often temporal or comparative than causal in general text. This is exactly why the classical feature-based encoding above uses the causal lexicon as one feature among several (path length, POS tags, dependency labels), never as a standalone decision rule. Absence of a match is equally uninformative: (Hidey and McKeown 2016)2 show that many real causal relations use no fixed connective at all ("alternative lexicalizations" β see the AltLex dataset), motivating the neural encodings described above as a way to capture causality that lexical matching misses entirely.
Strengths and Limitations
| Interpretable | The extracted path is human-readable; misclassifications are easy to trace |
| Low data requirement | Feature-based variants work with a few hundred labeled examples |
| Parse-dependent | Errors in the dependency tree propagate directly to the relation representation |
| Explicit markers only | Fails on implicit causality where no lexical connective appears on the path |
| Span detection required | Assumes entity spans are already identified; not a stand-alone pipeline |
Practical Tools
| Tool | Language | Notes |
|---|---|---|
| spaCy | Python | en_core_web_trf gives transformer-backed parses; .root attribute gives the span head |
| Stanza | Python | Stanford NLP; supports 70+ languages; returns DependencyRelation objects |
| NetworkX | Python | nx.shortest_path on the token graph; convenient for SDP traversal |
causalatee.nlp.shortest_dependency_path implements the spaCy + NetworkX combination above directly,
taking character-offset spans rather than requiring the caller to locate head tokens manually:
import spacy
from causalatee.nlp import format_sdp, shortest_dependency_path
nlp = spacy.load("en_core_web_sm")
doc = nlp("The storm caused significant flooding.")
path = shortest_dependency_path(doc, span_a=(0, 9), span_b=(29, 37)) # "The storm", "flooding"
print(format_sdp(path))
# storm --nsubjβ--> caused --dobjβ--> flooding
Requires the baselines extra (pip install 'causalatee[baselines]') for spacy and networkx.
Ready-to-use Baseline
shortest_dependency_path is a representation, not a classifier β turning the path into a
relation label is left to the caller. causalatee.nlp.SDPIdentifier is that classifier: a
causalatee.models.PairwiseIdentification-conforming
wrapper implementing exactly the "connective on the path" decision rule described above, including
the negation handling from the Causal Lexicon section β a negated connective
on the path predicts Relation.Countercausal instead of Relation.Causal, matching how CCNC
itself defines that label ("did not cause" is still a claim about causality, just denying it):
from causalatee.nlp import SDPIdentifier
identifier = SDPIdentifier() # loads en_core_web_sm lazily; pass nlp=... to reuse one
identifier("<e1>The storm</e1> caused <e2>significant flooding</e2>.")
# {'relationship': 'Causal', 'score': 1.0}
identifier("<e1>The vaccine</e1> did not cause <e2>autism</e2>.")
# {'relationship': 'Countercausal', 'score': 1.0}
identifier("<e1>The cat</e1> sat on <e2>the mat</e2>.")
# {'relationship': 'NoRelation', 'score': 1.0}
score is always 1.0 β this is a deterministic rule, not a calibrated probability. Only the
first segment of each marked span is used, so discontinuous entity mentions aren't representable
here (there's no single syntactic head token for a multi-segment span).
References
-
Girju, Roxana. 2003. βAutomatic Detection of Causal Relations for Question Answering.β Proceedings of the ACL 2003 Workshop on Multilingual Summarization and Question Answering (Sapporo, Japan), 76β83. https://doi.org/10.3115/1119312.1119322. ↩↩↩↩
-
Hidey, Christopher, and Kathy McKeown. 2016. βIdentifying Causal Relations Using Parallel Wikipedia Articles.β Proceedings of the 54th Annual Meeting of the Association for Computational Linguistics, ACL 2016, August 7-12, 2016, Berlin, Germany, Volume 1: Long Papers. https://doi.org/10.18653/V1/P16-1135. ↩