Semantic role labeling (SRL) works out the underlying meaning of a sentence by identifying the semantic relationship between the verb (the predicate) and the phrases around it (the arguments).
The plain-English version of the task:
Who did what to whom at where?
The police officer detained the suspect at the scene of the crime
Who what whom where
Where Dependency Parsing gives the grammatical relation between words, SRL gives the role each phrase plays in the event.
3 Subtasks
| Subtask | What it does |
|---|---|
| Predicate detection | find the predicates or verbs, meaning the words expressing the main action or event |
| Argument identification | find the words or phrases that serve as arguments of that predicate |
| Argument classification | label the role of each argument that was found |
The 3 run in that order, because an argument only exists relative to a predicate.
The roles
| Role | Meaning | Example in "John broke the window with a hammer" |
|---|---|---|
| Agent | the doer of the action | John |
| Patient/Recipient | the thing acted on or received | the window |
| Means/Theme | the instrument or the thing moved | with a hammer |
| Predicate | the verb itself | broke |
A second example:
| Sentence | Predicate | Arguments | Roles |
|---|---|---|---|
| John sold a book to Mary. | sold | John, a book, to Mary | Agent, Theme, Recipient |
The predicate is the verb, not the object
A common trap is to read the sentence in surface order and label the first noun as the predicate. In "Students learn NLP in NTU", the Agent is Students, the Patient is NLP, and the Predicate is learn.
NTUis a location, so it is not one of the 3 core answers.
B-Arg and I-Arg tagging
Arguments are spans, not single words, so they are tagged the same way as in NER:
- B-Arg marks the beginning token of an argument span
- I-Arg marks a token inside the same span
John broke the window with a hammer.
Agent Pred Patient Patient Means Means Means
B-Arg B-Arg I-Arg B-Arg I-Arg I-Arg
Code
There is no dedicated SRL library in use here, since the AllenNLP repository is archived. The implementation reads spaCy dependency labels and maps them to roles.
import spacy
from collections import defaultdict
nlp = spacy.load("en_core_web_lg")
def extract_srl(sentence):
doc = nlp(sentence)
srl_results = []
for token in doc:
# Predicate detection (verbs)
if token.pos_ == "VERB":
roles = {
"predicate": token.text,
"arguments": defaultdict(list)
}
# Argument identification
for child in token.children:
# Argument classification
if child.dep_ == "nsubj":
roles["arguments"]["ARG0"].append(child.text) # Agent
elif child.dep_ == "dobj":
roles["arguments"]["ARG1"].append(child.text) # Patient
elif child.dep_ == "prep":
roles["arguments"]["ARGM-"+child.text.upper()].append(
" ".join([w.text for w in child.subtree])
)
srl_results.append(roles)
return srl_results
sentence = "John broke the window with a hammer."
results = extract_srl(sentence)Predicate: broke
ARG0: John
ARG1: window
ARGM-WITH: with a hammer
The dependency label to role mapping
spaCy dep_ | SRL label | Role |
|---|---|---|
nsubj | ARG0 | Agent |
dobj | ARG1 | Patient |
prep | ARGM-<PREP> | Modifier, such as the means |
- predicate detection is the single test
token.pos_ == "VERB", sopos_is used and nottag_ - argument identification only looks at
token.children, meaning the direct dependents of the verb child.subtreeis used for prepositions so that the whole phrase "with a hammer" is captured, not just the word "with"ARGMlabels are modifiers and are named after the preposition in upper case, sowithbecomesARGM-WITH
Limitations
- words and phrases have multiple meanings, which makes the correct role hard to pick
- SRL struggles to capture relationships across sentences or longer documents
- SRL needs a large amount of annotated data, which is time-consuming and expensive to produce
- language carries many nuances and exceptions, so accuracy suffers