A sense is one meaning of a word. Its like saying what I sense of this word.
bank sense 1: a financial institution
bank sense 2: sloping land beside a river
WSD is the task of choosing the correct sense of a word, with reference to the context around the word.
2 Terms to know
| Term | Meaning | Example |
|---|---|---|
| Homonymy | Two unrelated meanings share a spelling | bank (money), bank (river) |
| Polysemy | Several related meanings of one word | mouth of a person, mouth of a river |
| Gloss | Simply a short definition of a sense | - |
3 Approaches to WSD
| Approach | Needs labelled data? | Resource used | How it decides |
|---|---|---|---|
| Dictionary-based (also called knowledge-based) | No | Dictionary or WordNet glosses | Counts overlapping words between the gloss and the context |
| Supervised | Yes, a sense-annotated corpus | SemCor, Senseval, SemEval | Trains a classifier for each ambiguous word |
| Unsupervised (word sense induction) | No | Raw text only | Clusters similar contexts, then treats each cluster as a sense |
| Semi-supervised | A few seed examples | Seeds plus raw text | Bootstraps from the seeds using heuristics |
The Lesk Algorithm
This is a dictionary based method that Michael Lesk published in 1986. The main idea is to choose a sense whose gloss shares the most words with the context.
There are some variants of Lesk:
- Simplified Lesk compares the gloss against the words in the sentence
- Original Lesk compares the glosses of 2 ambiguous words against each other
- Extended Lesk adds the glosses of related synsets, such as hypernyms and examples, to make the gloss longer
1. Steps
- Take the ambiguous word and the sentence around it
- Remove stopwords from the sentence to get the context set
- Look up every sense of the word in WordNet
- For each sense, take its gloss, and count how many words it shares with the context set. This count is the overlap score
- Return the sense with the highest overlap
2. Worked Example of Simplified Lesk
- Given:
I went to the bank to deposit my money. - Context set after stopword removal:
went,deposit, `money - Look up every sense of this word
bank
| Sense | Gloss (Meaning) | Shared words | Score |
|---|---|---|---|
| bank #1 financial institution | "a financial institution that accepts deposits and channels the money into lending activities" | deposit, money | 2 |
| bank #2 sloping land | "sloping land beside a body of water" | none | 0 |
In this case, sense #1 is chosen because of a higher matching rate.
3. Weakness of Lesk:
- glosses are short, so the overlap is often zero for every sense
- the result depends on the exact wording of the dictionary
- accuracy sits around 50-60%
Code
# ---------- 1. setup ----------
import nltk
nltk.download('wordnet')
nltk.download('omw-1.4')
nltk.download('punkt_tab')
nltk.download('stopwords')
from nltk.corpus import wordnet as wn
from nltk.tokenize import word_tokenize
from nltk.wsd import lesk
# ---------- 2. list the senses of a word ----------
senses = wn.synsets('bank')
print(len(senses), senses)
# ---------- 3. read one sense ----------
s = wn.synset('bank.n.01')
print(s.name(), s.pos())
print(s.definition())
print(s.examples())
# ---------- 4. lemmas: synonyms and antonyms ----------
print(s.lemma_names())
print(wn.synset('good.a.01').lemmas()[0].antonyms())
# ---------- 5. the hierarchy ----------
dog = wn.synset('dog.n.01')
print(dog.hypernyms())
print(dog.hyponyms())
# ---------- 6. run WSD ----------
sent = word_tokenize("I went to the bank to deposit my money")
sense = lesk(sent, 'bank', 'n')
print(sense, '|', sense.definition())
# ---------- 7. Lesk written by hand ----------
def my_lesk(context_sentence, word, pos=None):
context = set(context_sentence)
synsets = wn.synsets(word, pos) if pos else wn.synsets(word)
if not synsets:
return None
best, best_score = None, -1
for ss in synsets:
score = len(context.intersection(ss.definition().split()))
if score > best_score:
best, best_score = ss, score
return bestLesk needs the word class before it can compare glosses, so it runs after Part-of-Speech (POS) Tagging.