середа, 6 березня 2019 р.

Задача №8 Лаб. робота №9

Умова задачі: Напишіть програму, яка обробить Brown Corpus і допоможе відповісти на наступне запитання: які іменники частіше зустрічаються у множині ніж в однині (розглядати тільки регулярні форми множини).

Аналіз задачі. Потрібно знайти слова, які промарковані "NN" або "NNS" і порівняти їх частоту. Якщо dog - NN - зустрічається 5 разів а dogs - NNS - зустрічається 7 разів то "dog" частіше зустрічається у множині ніж в однині.


Один з варіантів рішення.
Подаю без коментарів і сподіваюсь на обговорення.



Трохи страшненько але може спонукає студентів до акуратного аналізу і розбору рішення

субота, 8 квітня 2017 р.

Задача №16a 8 розділ

Умова задачі: Write a program to find those verbs in the PP Attachment Corpus nltk.corpus.ppattach. Find any cases where the same verb exhibits two different attachments, but where  the  first noun, or  second noun, or preposition  stays unchanged (as we saw in our discussion of syntactic ambiguity in Section 8.2).

Аналіз задачі:
1. Переглядаємо формат корпуса PP Attachment Corpus.

The PP Attachment Corpus contains several files having the format:
sentence_id verb noun1 preposition noun2 attachment
For example:
42960 gives authority to administration V 
46742 gives inventors of microchip N
The PP attachment is to the verb phrase (V) or noun phrase (N), i.e.:
(VP gives (NP authority) (PP to administration)) (VP gives (NP inventors (PP of microchip)))
2. Аналізуємо приклад на сторінці 316.
# записи корпуса з частини 'training'
entries = nltk.corpus.ppattach.attachments('training')
# пустий словник по замовчуванню, значеннями записів якого будуть словники
table = nltk.defaultdict(lambda: nltk.defaultdict(set))
# заповнення словника за ключами які будуть містити іменник1-прийменник-іменник1
# а значеннями за цими ключами будуть словники з ключами attachment (V або N - до чого приєднується прийменниковий вираз) і значеннями - дієслово
for entry in entries:
...     key = entry.noun1 + '-' + entry.prep + '-' + entry.noun2
...     table[key][entry.attachment].add(entry.verb)

# перегляд словника і вивід на екран
for key in sorted(table):
...     if len(table[key]) > 1:
...         print key, 'N:', sorted(table[key]['N']), 'V:', sorted(table[key]['V'])


Пробуємо розв'язати задачу.
В результаті отримуємо щось таке:
('give', 'gives-authority', defaultdict(, {'V': set(['authority-to-Department']), 'N': set(['authority-for-veto'])}))
('give', 'give-sets', defaultdict(, {'V': set(['sets-in-promotion']), 'N': set(['sets-of-Boy'])}))
('give', 'given-attractiveness', defaultdict(, {'V': set(['attractiveness-as-consolidation']), 'N': set(['attractiveness-of-flows'])}))


Для зручності переписуємо програмку з використанням функцій:

понеділок, 31 жовтня 2016 р.

Задача №11 Лаб. робота №8

Умова задачі: Гематрія – метод виявлення прихованого змісту слів на основі порівняння чисел, які відповідають словам. Слова з однаковими числами мають однаковий зміст. Число слова визначається сумуванням чисел, як відповідають його літерам. Написати функцію decode() для обробки тексту, яка випадковим чином замінює слова на їх Гематрія-еквіваленти. Чи вдалося виявити "прихований зміст" тексту? (Використовувати letter_vals з попередньої задачі).

Аналіз задачі. Функція decode() повинна приймати один аргумент текст, який повинен бути списком слів або якщо текст стрічка то його потрібно буде перетворити у список. Слова з тексту повинні переглядатися одне за одним і для слова визначається його гематрія (число). Серед довільного списку слів вибираються слова які мають таке саме значення гематрії і серед них на екран виводиться випадково вибране слово.

субота, 6 квітня 2013 р.

Задача №18 8 розділ

В умові задачі згадуються перехідні та неперехідні прийменники - Extend the grammar in grammar2 with productions that expand prepositions as intransitive,  transitive, and  requiring a PP complement.
Матеріали курсу LING 100 — Fundamentals of Grammar http://courses.washington.edu/ling100/ будуть корисними для виконання цього завдання. http://courses.washington.edu/ling100/lect_slides/14_prep2/14_lmcg.pdf
Успіхів!

неділя, 13 листопада 2011 р.

Відповідь на лист стосовно 19го завдання 9ї лабораторної"Згадайте про n-грами"

Лист
Доброго вечора)
Маю до Вас запитання стосовно 19го завдання 9ї лабораторної.
Напишіть програми для знаходження слів та словосполучень згідно відповідних їм тегів для відповіді на наступне питання:
які послідовності слів маркуються як IN + DET + NN.

Чи можна це записати як:
brown_tagged=nltk.corpus.brown.tagged_words()
def findwords(text):
        s=nltk.defaultdict(list)
        for i in text:
                s[i[0]]+=[i[1]]
                a=[]
        for i in s.items():
                if 'IN' in i[1]:
                        a+=[i[0]]
        return a [:50]
findwords(brown_tagged)
Чи ось так:
cfd=nltk.ConditionalFreqDist((tag,word) for (word,tag) in
brown_tagged)
cfd['IN'].keys()
Або так:
brown_tagged=nltk.corpus.brown.tagged_words()
cfd=nltk.ConditionalFreqDist(brown_tagged)
[w for w in cfd.conditions() if 'IN' in cfd[w]]
Порадьте щось будь ласка)) Буду вдячна!!!




Відповідь у темі....
help(nltk.trigrams)
help(nltk.ngrams)
Також сподіваюсь Ви читали 10 сторінку методичних вказівок
for (w1,t1), (w2,t2), (w3,t3) in nltk.trigrams(sentence):

Відповідь на лист "лр 9, завд 18"

Добрий день!
Питання таке: лр 9, завд 18. Потрібно знайти співвідношення між жін. і чол.
займенниками. Таке розв'язання зараховується?)
from nltk import FreqDist, ConditionalFreqDist
from nltk.corpus import brown
fd = FreqDist()
cfd = ConditionalFreqDist()
for sentence in brown.tagged_sents():
    for (token, tag) in sentence:
        fd.inc(tag)
        cfd[token].inc(tag)
male = ['he','his','him','himself'] # masculine pronouns
female = ['she','hers','her','herself'] # feminine pronouns
n_male, n_female = 0, 0
for m in male:
    n_male += cfd[m].N()
n_male
16207
for f in female:
    n_female += cfd[f].N()
n_female
4975
print float(n_male)/n_female
3.2576884422


Відповідь_______________

Зарахувати завдання звичайно можна, але Ваша програм це просто підрахунок 'he','his','him','himself' та 'she','hers','her','herself'.
Я дев'ята лабораторна робота присвячена вивченню морфологічно розмічених корпусів. Тому я сподівався що при рішенні цієї задачі буде використовуватись інформація про теги якими маркуються займенники nltk.help.brown_tagset('P.*').
Наприклад Ваша програма не буде враховувати займенники записані наприклад так як he's she'd а використовуючи теги ви це врахуєте:
PPS+HVZ: pronoun, personal, nominative, 3rd person singular + verb 'to have', present tense, 3rd person singular
    it's he's she's
PPS+HVD: pronoun, personal, nominative, 3rd person singular + verb 'to have', past tense
    she'd he'd it'd

Відповідь на лист про гематрію

Доброї ночі!

Я у Вас вже була питала на парі про задачу з гематрією, але щось все одно в
мене не виходить... Подивіться, будь ласка, де помилка?
import nltk
state=nltk.corpus.state_union.words()
letter_vals = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':80, 'g':3,
'h':8,'i':10, 'j':10, 'k':20, 'l':30, 'm':40, 'n':50, 'o':70, 'p':80,
'q':100, 'r':200, 's':300, 't':400, 'u':6, 'v':6, 'w':800, 'x':60, 'y':10,
'z':7}
def gematria(state):
    for i in range(len(state)):
        word=state
        gem=0
        for i in word.lower():
            gem+=letter_vals[i]
        word=gem
        return word
for w in state:
    k=0
    if ([letter_vals[w] for w in state if w.isalpha() and w.islower() and
len(w)==3 and gematria(w)==555]):
    k+=1
    print k


__________________________________-


Перше - у восьмій лаб. роботі Ви вивчаєте, як зневаджувати програми. Потрібно цими знаннями скористатися і тоді....
Друге - у сьомій лаб. роботі Ви знайомилися з елементами стилю програмування. Але у своїй програмі у Вас state то список слів з корпуса то аргумент функції. Те саме з word.... 
Третє - В останньому циклі Ви перебираєте слова корпуса і далі стрічка:
 if ([letter_vals[w] for w in state if w.isalpha() and w.islower() and
len(w)==3 and gematria(w)==555]):
у якій перевіряєте все на купу, і довжину слова, і навіщось, чи є у letter_vals запис з ключем w(слово з корпуса) і так далі...
Порада - наведіть порядок зі змінними і тоді Вам буде простіше написати те що потрібно і зрозумієте де помилка 
Підказка - помилки у letter_vals[w] for w in state

вівторок, 8 листопада 2011 р.

Задача №6 Лабораторна робота №8

Умова. Написати програму для створення двовимірного масиву word_vowels елементами якого є набори. Програма повинна обробити список слів і додати кожне зі слів до word_vowels[l][v] де l – довжина слова, v – кількість голосних у слові.

Отже, якщо у мене, наприклад, список слів Іван, Петро, Василь - то я повинен в комірку масиву з індексами 4,2 записати слово Іван, в комірку масиву з індексами 5,2 записати слово Петро, в комірку масиву з індексами 6,2 записати слово Василь.

import nltk
from nltk.corpus import brown
list_w=[w.lower() for w in brown.words()[:10]] # список слів
# побудова двовимірного масиву
# сторінка 12 лаб.робота №7
#>>> m, n = 3, 7
#>>> array = [[set() for i in range(n)] for j in range(m)]
#>>> array[2][5].add('Alice')
#>>> pprint.pprint(array)
#[[set([]), set([]), set([]), set([]), set([]), set([]), set([])],
#[set([]), set([]), set([]), set([]), set([]), set([]), set([])],
#[set([]), set([]), set([]), set([]), set([]), set(['Alice']), set([])]]
#m, n - розміри масиву #як їх отримати,
#максимальне значення, яке може мати m - це довжина найдовшого слова зі списку #максимальне значення, яке може мати n - це найбільша кількість голосних у слові зі списку len_m_of_array=max([len(w) for w in list_w])
len_n_of_array=max([len([char for char in w if char in 'aoieu']) for w in list_w])
array = [[set() for i in range(len_n_of_array+1)] for j in range(len_m_of_array+1)]
# заповнення масиву
for w in list_w:
    array[len(w)][len([char for char in w if char in 'aoieu'])].add(w)
# переглядаю масив
pprint.pprint(array)

Це рішення має одну проблему. Я два рази для кожного слова знаходжу його довжину та кількість голосних. Перший раз при визначенні розміру масиву, а другий при його заповненні. Потрібно подумати, як уникнути цих подвійних обчислень.

середа, 28 вересня 2011 р.

Unicode в Python (лаб.робота №5)

Додаткову інформацію по роботі з Unicode в Python
можна знайти в:
http://boodebr.org/main/python/all-about-python-and-unicode
http://www.uchi-it.ru/9/11/6.html
http://www.py-my.ru/post/4bfb3c6a1d41c846bc00009b
або
http://www.python.su/forum/viewtopic.php?id=7742
http://www.python.su/forum/viewtopic.php?id=11747

пʼятниця, 6 травня 2011 р.

Перегляд синсетів у які входить задане слово (Задача №7 11 розділ)

Write a function which displays the complete entry for a lexeme. When the
lexeme is incorrectly spelled, it should display the entry for the most similarly
spelled lexeme.

Вважаю, що entry для lexeme це будуть всі синсети з WordNet у які вона входить.
Повністю повторення прикладу зі сторінки 424 але все зроблено, як одна функція, хоча так робити недоцільно. Кожен раз коли виконується ця функція відбувається індексування словника signatures = nltk.Index((signature(w), w) for w in nltk.corpus.words.words())

import nltk, re

def fuzzy_spell(word):
mappings = [('ph', 'f'), ('ght', 't'), ('^kn', 'n'), ('qu', 'kw'), ('[aeiou]+', 'a'), (r'(.)\1', r'\1')]
def signature(word):
for patt, repl in mappings:
word = re.sub(patt, repl, word)
pieces = re.findall('[^aeiou]+', word)
return ''.join(char for piece in pieces for char in piece)

signatures = nltk.Index((signature(w), w) for w in nltk.corpus.words.words())

def rank(word, wordlist):
ranked = sorted((nltk.edit_distance(word, w), w) for w in wordlist)
return [word for (_, word) in ranked]

# Якщо слово відсутнє у словнику то вважаємо що воно містить помилку
if word not in nltk.corpus.words.words():
sig = signature(word)
if sig in signatures:
for words in rank(word, signatures[sig]):
print words, nltk.corpus.wordnet.synsets(words)
else:
return []
else:
print nltk.corpus.wordnet.synsets(word)

print fuzzy_spell('closeі')

Зовсім просто (Задача№1 11 Розділ)

In Example 11.8 the new field appeared at the bottom of the entry. Modify this program so that it inserts the new subelement right after the lx field. (Hint: create the new cv field using Element('cv'), assign a text value to it, then use the insert() method of the parent element.)

Доволі все просто.
import nltk,re,pprint
from nltk.corpus import toolbox
from nltk.etree.ElementTree import Element

lexicon = toolbox.xml('rotokas.dic')

def cv(s):
s = s.lower()
s = re.sub(r'[^a-z]', r'_', s)
s = re.sub(r'[aeiou]', r'V', s)
s = re.sub(r'[^V_]', r'C', s)
return (s)

def add_cv_field(entry):

for field in entry:
if field.tag == 'lx':
cv_field = Element('cv')
cv_field.text = cv(field.text)
entry.insert(1,cv_field)

print nltk.toolbox.to_sfm_string(lexicon[53])
add_cv_field(lexicon[53])
print nltk.toolbox.to_sfm_string(lexicon[53])

пʼятниця, 11 березня 2011 р.

Які будуть ще ідеї (Задача №8 Розділ №6)

Умова задачі: Word features can be very useful for performing document classification, since the words that appear in a document give a strong indication about what its semantic content is. However, many words occur very infrequently, and some of the most informative words in a document may never have occurred in our training data. One solution is to make use of a lexicon, which describes how different words relate to one another. Using WordNet lexicon, augment the movie review document classifier presented in this chapter to use features that generalize the words that appear in a document, making it more likely that they will match words found in the training data.

#Спробую врахувати вплив гіпернімів.
#Варіант 1.
#Згідно приладу з підручника:
import nltk
import random
from nltk.corpus import movie_reviews
from nltk.corpus import wordnet as wn
documents = [(list(movie_reviews.words(fileid)), category)
for category in movie_reviews.categories()
for fileid in movie_reviews.fileids(category)]
random.shuffle(documents)
all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
word_features = all_words.keys()[:2000]
def document_features(document):
document_words = set(document)
features = {}
for word in word_features:
features['contains(%s)' % word] = (word in document_words)
return features
featuresets = [(document_features(d), c) for (d,c) in documents]
train_set, test_set = featuresets[1800:], featuresets[:200]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print nltk.classify.accuracy(classifier, test_set)
#Отримую базову точність
#Якщо слово не попало в список з 2000 найчастотніших але його гіперніми зустрічаються серед слів корпуса то:
#Збільшую частоту для цих гіпернімів і знову беру 2000 найчастотніших
for word in all_words.keys():
if all_words[word]<70:
for synset in wn.synsets(word):
for hypernyms in synset.hypernyms():
for l_names in hypernyms.lemma_names:
all_words.inc(l_names)
word_features1 = all_words.keys()[:2000]
# Яких змін зазнав список найчастотніших слів
print len([word for word in word_features1 if word not in word_features])
word_features = all_words.keys()[:2000]
featuresets = [(document_features(d), c) for (d,c) in documents]
train_set, test_set = featuresets[1800:], featuresets[:200]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print nltk.classify.accuracy(classifier, test_set)

Результати погані точність не збільшилась, список змінився на 270 слів.
0.725
270
0.71
>>>
0.715
270
0.72
>>>
0.765
270
0.75
>>>
0.805
270
0.805
>>>
0.69
270
0.705
>>>
#Варіант 2.
#Згідно приладу з підручника:
import nltk
import random
from nltk.corpus import movie_reviews
from nltk.corpus import wordnet as wn
documents = [(list(movie_reviews.words(fileid)), category)
for category in movie_reviews.categories()
for fileid in movie_reviews.fileids(category)[:100]]
random.shuffle(documents)
all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
print len(all_words)
word_features = all_words.keys()[:200]
def document_features(document):
document_words = set(document)
features = {}
for word in word_features:
features['contains(%s)' % word] = (word in document_words)
return features
featuresets = [(document_features(d), c) for (d,c) in documents]
train_set, test_set = featuresets[80:], featuresets[:20]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print nltk.classify.accuracy(classifier, test_set)
#Отримую базову точність
#Якщо слово не попало в список найчастотніших але його гіперніми входять у цей список то:
#додати це слово до списку найчастотніших
for word in all_words.keys()[:300]:
if all_words[word]< all_words[all_words.keys()[200]]:
for synset in wn.synsets(word):
for hypernyms in synset.hypernyms():
for l_names in hypernyms.lemma_names:
if l_names in all_words.keys()[:200]:
if word not in word_features:
word_features.append(word)
#Скільки слів додалося до списку
print len(word_features)
featuresets = [(document_features(d), c) for (d,c) in documents]
train_set, test_set = featuresets[80:], featuresets[:20]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print nltk.classify.accuracy(classifier, test_set)
Слів додалося 37 а точність так і не збільшилась.

>>>
0.55
237
0.65
>>>
0.55
237
0.5
>>>
0.65
237
0.55
>>>
39768
0.5
237
0.5
>>>
0.65
237
0.65
>>>

Потрібні ще ідеї по використанню WordNet для рішення цієї задачі

понеділок, 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

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

вівторок, 6 квітня 2010 р.

Задача №7 розділ №6 "Learning to Classify Text"

Умова задачі:
The dialogue act classifier assigns labels to individual posts, without considering
the context in which the post is found. However, dialogue acts are highly dependent
on context, and some sequences of dialogue act are much more likely than
others. For example, a ynQuestion dialogue act is much more likely to be answered
by a yanswer than by a greeting. Make use of this fact to build a consecutive classifier
for labeling dialogue acts. Be sure to consider what features might be useful.
See the code for the consecutive classifier for part-of-speech tags in Example 6-5
to get some ideas.

Варіант рішення:
В умові задачі міститься підказка.
Потрібно поєднати приклад 6-5 та приклад зі сторінки 235.
Ось що в мене вийшло.
>>> import nltk
>>> posts = nltk.corpus.nps_chat.xml_posts()
>>> history=[] # змінна для збереження типу попереднього повідомлення (post’s dialogue act type)
# функція для вилучення властивостей(ознак) з повідомлення
>>> def dialogue_act_features(post,i,history):
features = {}
for word in nltk.word_tokenize(post):
features['contains(%s)' % word.lower()] = True
if i == 0:
features["prev-class"] = ""
else:
features["prev-class"] = history[i-1] # тип попереднього повідомлення
return features
>>> featuresets=[]
>>> for i, post in enumerate(posts): # обробляємо пронумерований список повідомлень
featuresets.append((dialogue_act_features(post.text, i, history), post.get('class')))
history.append(post.get('class')) # список типів всіх повідомлень
>>> size = int(len(featuresets) * 0.1)
>>> train_set, test_set = featuresets[size:], featuresets[:size]
>>> classifier = nltk.NaiveBayesClassifier.train(train_set)
>>> print nltk.classify.accuracy(classifier, test_set)
0.644886363636

# а чому точність нижча ніж у прикладі зі сторінки 235, де тип попереднього повідомлення не враховувався?

Задача №6 розділ №6 "Learning to Classify Text"

Умова задачі:
The synonyms strong and powerful pattern differently (try combining them with
chip and sales). What features are relevant in this distinction? Build a classifier that predicts when each word should be used.

Варіант рішення:
Основне питання задачі це знайти ознаки за якими можна було б описати випадки вживання цих двох прикметників. Що впливає на вибір того чи іншого прикметника? Потрібно почитати граматику англійської мови, можливо стилістику, порадитись з спеціалістами філологами. Але в мене часу мало, тому вибираю найпростішу ознаку. Аналізую контексти вживання цих прикметників, а саме наступне після прикметника слово та його морфологічні характеристики. Звідки взяти цю інформацію, яка буде служити даними для тренування класифікатора? Корпус Brown.
# з корпуса Brown вибираю всі біграми в яких перше слово "strong" або "powerful" і промарковане, як прикметник. Зберігаю всі наступні слова та тери якими вони промарковані у словнику.
>>> import nltk
>>> from nltk.corpus import brown
>>> featureset=[]
>>> context={}
>>> for tagged_sent in brown.tagged_sents():
for (w1,t1), (w2,t2) in nltk.bigrams(tagged_sent):
if t1.startswith('JJ') and w1 == 'strong':
context[w2]=t2
featureset.append((a,w1))
context={}
elif t1.startswith('JJ') and w1 == 'powerful':
context[w2]=t2
featureset.append((a,w1))
context={}
# дивимось що отримали
>>> featureset[5]
({'New': 'JJ-TL'}, 'powerful')
>>> len(featureset)
253
# в корпусі мало випадків вживання цих прикментників. Всього 253. Як їх збільшити? Це я і буду питати при здачі практичної роботи.
# далі шлях побудови класифікатора вже знайомий
>>> size = int(len(featureset) * 0.1)
>>> train_set, test_set = featureset[size:], featureset[:size]
>>> classifier = nltk.NaiveBayesClassifier.train(train_set)
>>> nltk.classify.accuracy(classifier, test_set)
0.59999999999999998
>>> classifier.classify({'fight':'NN'})
'strong'
>>> classifier.classify({'fight':'v'})
'strong'
>>> classifier.classify({'fight':'JJ'})
'strong'
>>> classifier.classify({'fight':'VB'})
'strong'
>>> classifier.classify({'chip':'NN'})
'strong'
# от і результат недостатності даних для тренування, і вибору ознаки.

субота, 3 квітня 2010 р.

Задача №3 розділ №6 "Learning to Classify Text"

Умова задачі:
The Senseval 2 Corpus contains data intended to train word-sense disambiguation
classifiers. It contains data for four words: hard, interest, line, and serve.
Choose one of these four words, and load the corresponding data:
>>> from nltk.corpus import senseval
>>> instances = senseval.instances('hard.pos')
>>> size = int(len(instances) * 0.1)
>>> train_set, test_set = instances[size:], instances[:size]
Using this dataset, build a classifier that predicts the correct sense tag for a given
instance. See the corpus HOWTO at http://www.nltk.org/howto for information
on using the instance objects returned by the Senseval 2 Corpus.

Шлях рішення:
Спочатку здається все просто. instances - це ознаки (features) на основі яких ми можемо тренувати будь-який з класифікаторів. Пробуємо:
>>> import nltk
>>> from nltk.corpus import senseval
>>> instances = senseval.instances('hard.pos')
>>> size = int(len(instances) * 0.1)
>>> train_set, test_set = instances[size:], instances[:size]
>>> classifier = nltk.NaiveBayesClassifier.train(train_set)

Traceback (most recent call last):
File "", line 1, in
classifier = nltk.NaiveBayesClassifier.train(train_set)
File "C:\Python26\lib\site-packages\nltk\classify\naivebayes.py", line 192, in train
for featureset, label in labeled_featuresets:
TypeError: 'SensevalInstance' object is not iterable

!!! Помилка. Використати instances як ознаки (features) не вдалося.
Потрібно розібратися у якому вигляді класифікатор (в даному випадку NaiveBayesClassifier) потребує дані для тренування (train_set)
Беремо будь-який з прикладів з підручника і аналізуємо(приклад сторінка 225):
>>> from nltk.corpus import names
>>> import random
>>> names = ([(name, 'male') for name in names.words('male.txt')] +
[(name, 'female') for name in names.words('female.txt')])
>>> random.shuffle(names)
>>> def gender_features2(name):
features = {}
features["firstletter"] = name[0].lower()
features["lastletter"] = name[-1].lower()
for letter in 'abcdefghijklmnopqrstuvwxyz':
features["count(%s)" % letter] = name.lower().count(letter)
features["has(%s)" % letter] = (letter in name.lower())
return features
>>> featuresets = [(gender_features2(n), g) for (n,g) in names]
>>> train_set, test_set = featuresets[500:], featuresets[:500]
# перевіримо що за змінна train_set
>>> type(train_set)
# тип цієї змінної - список
# скільки елементів у цьому списку
>>> len(train_set)
7444
# багато, поглянемо на один з них
>>> train_set[5]
({'count(u)': 0, 'has(d)': False, 'count(b)': 0, 'count(w)': 0, 'has(b)': False, 'count(l)': 1, 'count(q)': 0, 'count(n)': 0, 'has(j)': False, 'count(s)': 0, 'count(h)': 0, 'has(h)': False, 'has(y)': False, 'count(j)': 0, 'has(f)': False, 'has(o)': False, 'count(x)': 0, 'has(m)': True, 'count(z)': 0, 'has(k)': False, 'has(u)': False, 'count(d)': 0, 'has(s)': False, 'count(f)': 0, 'lastletter': 'a', 'has(q)': False, 'has(w)': False, 'has(e)': False, 'has(z)': False, 'count(t)': 0, 'count(c)': 0, 'has(c)': False, 'has(x)': False, 'count(v)': 0, 'count(m)': 1, 'has(a)': True, 'has(v)': False, 'count(p)': 0, 'count(o)': 0, 'has(i)': False, 'count(i)': 0, 'has(r)': False, 'has(g)': False, 'count(k)': 0, 'firstletter': 'm', 'count(y)': 0, 'has(n)': False, 'has(l)': True, 'count(e)': 0, 'has(t)': False, 'count(g)': 0, 'count(r)': 0, 'count(a)': 2, 'has(p)': False}, 'female')
# структура елементу складна. кортеж, словник, стрічки....
>>> type(train_set[5])
# тип елемента списку train_set - кортеж
>>> len(train_set[5])
2 # цей кортеж складається з двох елементів
>>> type(train_set[5][0])
# тип першого елемента - словник
>>> type(train_set[5][1])
# тип другого елемента - стрічка
Все зрозуміло, за допомогою словника описуються ознаки а за допомогою стрічки описується мітка, яка відповідає цим ознакам.
Тепер потрібно розібратися що таке - instances. Найпростіше почитати HOWTO at http://www.nltk.org/howto як рекомендують автори. Точніше читаємо тут: http://nltk.googlecode.com/svn/trunk/doc/howto/corpus.html#other-corpora
instances - також складний об'єкт. Він складається з окремих SensevalInstance - в яких описано слово (word), позиція цього слова у реченні (position), всі слова речення та їх морфологічні характеристики (context) та значення слова (senses).
Для доступу до елементів SensevalInstance є окремі методи:
.position, .word, .context, .senses
Отже потрібно доступитися до SensevalInstance і перетворити його елементи до вигляду:
Окремий SensevalInstance це буде кортеж, position, word, context, - словник, senses - стрічка.
Пишемо текст програми:
# імпортуємо необхідні для роботи програми модулі
import nltk
import types
from nltk.corpus import senseval
# доступаємся до даних з корпусв
instances = senseval.instances('serve.pos')
features=[]
# перетворюємо instances до потрібного вигляду (списку кортежів кожен з яких складається зі словника та стрічки). Змінна features і буде цим списком.
for inst in instances:
zx=[]
for i in inst.context:
if type(i) == types.TupleType:
zx.append(i)
elif type(i) == types.StringType:
zx.append(("None",i))
a={"word": inst.word,"position": inst.position,}
b=dict(zx)
a.update(b)
features.append((a,' '.join(inst.senses)))
# далі вже все просто
# встановлюємо розмір даних для тестуваня (10%)
size = int(len(features) * 0.1)
# ділимо всі дані на дві частини - для тренування і для тестування
train_set, test_set = features[size:], features[:size]
# тренуємо класифікатор
classifier1 = nltk.NaiveBayesClassifier.train(train_set)
# оцінюємо точність його роботи
print nltk.classify.accuracy(classifier1, test_set)
0.66590389016
# точність - так собі, не дуже
але задачу здається виконали....

пʼятниця, 2 квітня 2010 р.

Задача №1 розділ №6 "Learning to Classify Text"

Умова задачі: Read up on one of the language technologies mentioned in this section, such as
word sense disambiguation, semantic role labeling, question answering, machine
translation, or named entity recognition. Find out what type and quantity of annotated
data is required for developing such systems. Why do you think a large
amount of data is required?

Що потрібно зробити:
- прочитати про word sense disambiguation, semantic role labeling, question answering, machine translation, named entity recognition в підручнику починаючи зі сторінки 28;
- прочитати про word sense disambiguation, semantic role labeling, question answering, machine translation, named entity recognition в інших книжках (Jurafsky), інтернет ресурсах (Вікіпедія) тощо...
- обдумати, які дані (корпуси) необхідні для побудови (тренування) класифікатора для вирішення тої чи ншої задачі;
- аргументувати, який об'єм даних потрібний для успішного вирішення задачі.

Складнощі з вивченням розділу "Learning to Classify Text"

При вивчення розділу "Learning to Classify Text" студенти зіткнулися із значними труднощами. В наступних дописах будуть розглядатися задачі з цього розділу.

понеділок, 11 січня 2010 р.

Контрольна робота: умови, вимоги, критерії оцінювання

Практична частина контрольної роботи буде проводитись 20-го та 21-го січня згідно розкладу лабораторних робіт.
Тривалість – 45 хвилин.
Максимальна кількість балів -20.
Практична частина контрольної роботи передбачає розробку програми для вирішення певної задачі, умова якої міститься у завданні.
Основні вимоги до розробки програми:
Програма повинна бути оформлена у вигляді окремого модуля (файл *.py). Назва файлу відповідає прізвищу студента.
Програма повинна передбачати збереження результатів роботи у файл (*.dat). Назва файлу відповідає прізвищу студента.
Для розробки програми студент повинен володіти засобами мови програмування
Python та бібліотеки програм NLTK, а саме:
функціями та методами роботи з типами даних : стрічка, список, словник
;
функціями та методами доступу (відкриття, читання) до файлів
;
функціями та методами збереження даних (відкриття, запис) у файл
;
функціями та методами доступу до корпусів текстів
;
функціями та методами для роботи з
WordNet;
функціями та методами для роботи з морфологічно розміченими корпусами текстів.

Критерії оцінки
Виконані всі вимоги: розроблено модуль, який вирішує поставлену задачу і зберігає результати у файл - 20 балів.
Вимоги виконані частково:
відсутній модуль - мінус 3 бали;
в модулі відсутні коментарі - мінус 2 бали;
результати не зберігаються у файл - мінус 3 бали;
задача вирішена частково або неправильно - мінус 10 балів

вівторок, 8 грудня 2009 р.

Задача №15 Лабораторна робота №5

Перепишіть наступний цикл як list comprehension :
>>> words = ['attribution', 'confabulation', 'elocution','sequoia', 'tenacious', 'unidirectional']
>>> vsequences = set()
>>> for word in words:
vowels = []
for char in word:
if char in 'aeiou':
vowels.append(char)
vsequences.add(''.join(vowels))


>>> sorted(vsequences)
['aiuio', 'eaiou', 'eouio', 'euoia', 'oauaio', 'uiieioa']