Умова задачі:
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
Результат несподіваний. Точність зменшилась.
Хто знає чому?
я вважаю шо точність змінилась, тому що в першому випадку було застосовано і дефолт, і юніграм, і біграм тегер, в другому лише біграм і дефолт, впродовж тренування аналізатор вирішує шо "невідоме" слово швидше за все іменник, навіть якшо це не так. У випадку завстосування юніграм тегера, ми б дивились на контекст, і це збільшує точність. Тому і різні показники.
ВідповістиВидалитиХорошилова Валентина ПРЛс- 11
0.844911791089 - точність аналізатора (дефолт+ юніграм+біграм)тренованого на звичайних даних.
ВідповістиВидалити0.836938104256 - точність аналізатора (дефолт+ юніграм+біграм) тренованого на даних зі змінами (замість слів з низькою частотою UNK).
Слова з низькою частотою впливають на біграм аналізатор і така заміна мала би покращити ситуацію. А не покращила. Або я погано запрограмував, або треба ще побавитись...