Semantic Role Labeling
Semantic role labeling finds the verb and labels who did what to whom, so the active and passive versions of one event get the same tags.
Why Does This Exist?
Syntax tells you how words attach. It does not tell you who did what. John broke the window and the window was broken by John have wildly different trees, yet they describe one event with one breaker and one thing broken. Without a semantic layer, every downstream system must relearn that equivalence from examples.
Semantic role labeling supplies that layer. It marks the predicate, usually a verb, and labels each participant with a role such as agent, patient, time, or location. Question answering and extraction then read roles instead of tree shapes, so paraphrases collapse to one frame. You will see it called shallow semantic parsing because it stops at who did what, without full logic.
This page covers verb frames in the PropBank style: core roles ARG0 through ARG5 plus adjuncts such as ARGM-TMP and ARGM-LOC. The syntactic prerequisite is dependency parsing, which finds heads and dependents but not their event parts. Spans of people and places come from named entity recognition, while links between two entities belong to relation extraction.
The one idea you need first
A predicate is the event word, often a verb such as reported or sold. An argument is a span that fills a part in that event, such as the reporter or the thing reported. Labels split into core roles that depend on the verb and adjuncts that mean the same across verbs. ARG0 is usually the doer and ARG1 the thing done to, while ARGM-TMP always means when. The syntax that feeds this is in dependency parsing.
Think of It Like This
An incident form with fixed blanks
You carry a paper form with blanks for action, doer, thing affected, time, and place. One witness says a man stole a car last night at the mall. Another says last night the car was stolen by a man at the mall. Different word order, same form.
You write stole in the action blank, a man as doer, a car as affected, last night as time, and at the mall as place. Both phrasings land in identical boxes, so a later search for car thefts finds both without caring how anyone spoke.
Where it stops: a paper form lets you scribble notes in the margins. This task lets you pick only from a fixed role list, so anything outside ARG0 plus ARG1 plus the adjunct set has nowhere to go.
How It Actually Works
Fix a predicate such as reported. The system segments the sentence into spans and assigns each span one label from the role set. In plain words: is the event anchor, ARG0 names the typical doer, ARG1 names the typical thing affected, ARG2 through ARG5 are verb specific extras, and ARGM labels such as TMP, LOC, MNR, and NEG add time, place, manner, and negation across all verbs.
Find the predicate
The first pass finds event words, usually verbs and sometimes event nouns such as destruction. One sentence can hold several predicates, and each gets its own frame. In the dog barked and chased the cat, barked and chased each anchor a separate set of roles. Missing a predicate means missing its whole event.
Find the argument spans
With fixed, the system tests spans for participation using BIO tags: B marks a span start, I continues it, O sits outside. For Yesterday, the company reported its earnings, the gold tags read B-ARGM-TMP for Yesterday, B-ARG0 plus I-ARG0 for the company, B-V for reported, and B-ARG1 plus I-ARG1 for its earnings. This turns span finding into per token classification with clean boundaries.
Classify each span
A classifier scores every candidate span against the role set. Take the company as an example with three labels ARG0, ARG1, and O and logits . Exponentiate to , sum to , and divide to . The span becomes ARG0 at 0.844, with ARG1 kept as a distant second. The same softmax runs per span, so overlapping or duplicate core roles can still slip through at this stage.
Enforce one valid frame
The final pass applies structure: spans cannot overlap, and most verbs take each core role at most once. Joint inference picks the highest scoring global assignment that obeys those constraints. That is why two strong ARG0 spans for one predicate get resolved to one winner plus a re-label, instead of two doers.
Worked example
Run the full sentence Yesterday, the company reported its earnings with predicate reported. The frame is ARGM-TMP Yesterday, ARG0 the company, V reported, ARG1 its earnings. Swap to passive as Its earnings were reported by the company yesterday and the frame stays identical: the company is still ARG0 even though it is no longer the subject. That stability under paraphrase is the product, and it is what syntax alone cannot give you.
Code
This snippet replays the span decision and decodes BIO tags, so you can check the winning role and the final frame without a trained model.
import mathfrom typing import List
def softmax(logits: List[float]) -> List[float]: exps = [math.exp(v) for v in logits] total = sum(exps) return [v / total for v in exps]
labels = ["ARG0", "ARG1", "O"]logits = [2.0, 0.0, -1.0]probs = softmax(logits)for name, p in zip(labels, probs): print(f"{name:<4} {p:.3f}")# -> ARG0 0.844# -> ARG1 0.114# -> O 0.042
tags = ["B-ARGM-TMP", "O", "B-ARG0", "I-ARG0", "B-V", "B-ARG1", "I-ARG1", "O"]words = ["Yesterday", ",", "the", "company", "reported", "its", "earnings", "."]frame = {}current = ""for w, t in zip(words, tags): if t.startswith("B-"): current = t[2:] frame.setdefault(current, []).append(w) elif t.startswith("I-") and current: frame[current].append(w)print(frame["ARG0"], frame["ARG1"], frame["ARGM-TMP"])# -> ['the', 'company'] ['its', 'earnings'] ['Yesterday']The softmax matches the hand division to three decimals, and the decoded frame shows the company as doer plus its earnings as affected plus Yesterday as time.
Watch Out For
Reading ARG0 straight off the subject
In active sentences ARG0 often lines up with the subject, so teams hardcode that shortcut. Passive voice breaks it on day one: in the cake was eaten by Mary, the subject is the cake but the agent is Mary. Psych verbs break it too, since I fear dogs and dogs frighten me assign the experiencer to different roles.
The symptom is a role swap that looks confident. Always read the verb specific frame in PropBank instead of mapping syntax positions to roles.
Scoring only the main verb
A sentence with two verbs holds two frames that overlap. In she promised to call him, she is ARG0 of promised and also the understood ARG0 of call. A pipeline that keeps only the root predicate drops the embedded event entirely.
The fix is mechanical: run identification plus classification per predicate and store frames keyed by verb. If your recall looks low on long sentences, count predicates first before blaming the classifier.
The Quick Version
- Semantic role labeling marks the predicate and labels each span as ARG0, ARG1, or an ARGM adjunct such as time or location.
- Core roles depend on the verb while adjuncts mean the same across verbs.
- Spans are found with BIO tags, scored with softmax, then cleaned by constraints such as no overlap and one core role each.
- Logits [2.0, 0.0, -1.0] give [0.844, 0.114, 0.042], so the company is ARG0 of reported.
- Active and passive versions of one event share one frame, but one sentence can hold several frames.