понеділок, 21 лютого 2011 р.

Чому точність зменшилась(Задача №30, Розділ№5 )

Умова задачі:
Preprocess the Brown News data by replacing low-frequency words with UNK,
but leaving the tags untouched. Now train and evaluate a bigram tagger on this
data. How much does this help? What is the contribution of the unigram tagger
and default tagger now?

За умовою задачі очікуємо підвищення точності аналізатора.
Пишемо програму:
>>> import nltk
>>> from nltk.corpus import brown
>>> brown_tagged_sents = brown.tagged_sents(categories='news')
>>> vocab = nltk.FreqDist(brown.words(categories='news'))
# Важливий момент. Заміна всіх слів з частотоу =< 2 на "UNK"
>>> mapping = nltk.defaultdict(lambda: 'UNK')
>>> for v,t in brown.tagged_words(categories='news'):
if vocab[v]>2:
mapping[v],t = v,t
# Частотніші слова у словнику відобразили самих на себе
# Всі інші міняємо і результат зберігаємо у списку new_tagged_sents
>>> new_tagged_sents=[]
>>> for i in brown.tagged_sents(categories='news'):
new_tagged_sents.append([(mapping[v],t) for (v,t) in i])

# Поглянули чи дійсно відбулася заміна
>>> brown.tagged_sents(categories='news')[10]
[('It', 'PPS'), ('urged', 'VBD'), ('that', 'CS'), ('the', 'AT'), ('city', 'NN'), ('``', '``'), ('take', 'VB'), ('steps', 'NNS'), ('to', 'TO'), ('remedy', 'VB'), ("''", "''"), ('this', 'DT'), ('problem', 'NN'), ('.', '.')]
>>> new_tagged_sents[10]
[('It', 'PPS'), ('urged', 'VBD'), ('that', 'CS'), ('the', 'AT'), ('city', 'NN'), ('``', '``'), ('take', 'VB'), ('steps', 'NNS'), ('to', 'TO'), ('UNK', 'VB'), ("''", "''"), ('this', 'DT'), ('problem', 'NN'), ('.', '.')]

# будуємо набори даних для тренування тестування
# будуємо і тренуємо аналізатори
# оцінюємо точність їх роботи
>>> size = int(len(brown_tagged_sents) * 0.9)
>>> train_sents1 = brown_tagged_sents[:size]
>>> test_sents1 = brown_tagged_sents[size:]
>>> train_sents2 = new_tagged_sents[:size]
>>> test_sents2 = new_tagged_sents[size:]
>>> t0 = nltk.DefaultTagger('NN')
>>> t1 = nltk.UnigramTagger(train_sents1, backoff=t0)
>>> t2 = nltk.BigramTagger(train_sents1, backoff=t1)
>>> print t2.evaluate(test_sents1)
0.844911791089
>>> t1 = nltk.UnigramTagger(train_sents2, backoff=t0)
>>> t2 = nltk.BigramTagger(train_sents2, backoff=t1)
>>> print t2.evaluate(test_sents2)
0.836938104256
>>> t2 = nltk.BigramTagger(train_sents2, backoff=t0)
>>> print t2.evaluate(test_sents2)
0.722416027111

Результат несподіваний. Точність зменшилась.
Хто знає чому?