Neither stemmer or lemmatizer can get you from greatest
-> great
:
>>> from nltk.stem import WordNetLemmatizer
>>> from nltk.stem import WordNetLemmatizer, PorterStemmer
>>> porter = PorterStemmer()
>>> wnl = WordNetLemmatizer()
>>> greatest = 'greatest'
>>> porter.stem(greatest)
u'greatest'
>>> wnl.lemmatize(greatest)
'greatest'
>>> greater = 'greater'
>>> wnl.lemmatize(greater)
'greater'
>>> porter.stem(greater)
u'greater'
But seems like you can make use of some nice properties of the PennTreeBank tagset to get from greatest -> great
:
>>> from nltk import pos_tag
>>> pos_tag(['greatest'])
[('greatest', 'JJS')]
>>> pos_tag(['greater'])
[('greater', 'JJR')]
>>> pos_tag(['great'])
[('great', 'JJ')]
Let's try a crazy rule based system, let's start from greatest
:
>>> import re
>>> word1 = 'greatest'
>>> re.sub('est$', '', word1)
'great'
>>> re.sub('est$', 'er', word1)
'greater'
>>> pos_tag([re.sub('est$', '', word1)])[0][1]
'JJ'
>>> pos_tag([re.sub('est$', 'er', word1)])[0][1]
'JJR'
>>> word1
'greatest'
Now that we know that we can build our own little superlative stemmer/lemmatizer/tail_substituter, let's write a rule that says if a word gives a superlative POS tag and our tail_substituter
gives us JJ when we stem and JJR when we convert, we can safely say that the comparative and base form of the word can be easily gotten with our tail_substituter
:
>>> if pos_tag([word1])[0][1] == 'JJS' \
... and pos_tag([re.sub('est$', '', word1)])[0][1] == 'JJ' \
... and pos_tag([re.sub('est$', 'er', word1)])[0][1] == 'JJR':
... comparative = re.sub('est$', 'er', word1)
... adjective = re.sub('est$', '', word1)
...
>>> adjective
'great'
>>> comparative
'greater'
Now that gets you from greatest -> greater -> great
. From great -> best
is sort of weird, since lexically they're not not related although their semantics relative seems related.
So i think it would be subjective to say that great -> best
is a valid transformation