main_text - это список списков, содержащих предложения, которые были помечены для части речи:
main_text = [[('the', 'DT'), ('mad', 'JJ'), ('hatter', 'NN'), ('likes','VB'),
('tea','NN'), ('and','CC'), ('hats', 'NN')], [('the', 'DT'), ('red','JJ')
('queen', 'NN'), ('hates','VB'),('alice','NN')]]
ngrams_to_match - это список списков, содержащих триграммы для части речи:
ngrams_to_match = [[('likes','VB'),('tea','NN'), ('and','CC')],
[('the', 'DT'), ('mad', 'JJ'), ('hatter', 'NN')],
[('hates', 'DT'), ('alice', 'JJ'), ('but', 'CC') ],
[('and', 'CC'), ('the', 'DT'), ('rabbit', 'NN')]]
(a) Для каждого предложения в main_text сначала проверьте, соответствует ли полная триграмма в ngrams_to _match.Если триграмма совпадает, вернуть соответствующую триграмму и предложение.
(b) Затем проверьте, соответствуют ли первый кортеж (униграмма) или первые два кортежа (биграмма) каждой из триграмм в main_text.
(c) Если униграмма или биграмма образуют подстроку уже согласованной триграммы, ничего не возвращайте.В противном случае верните соответствие биграмм или униграмм и предложение.
Вот что должно быть в результате:
trigram_match = [('the', 'DT'), ('mad', 'JJ'), ('hatter', 'NN')], sentence[0]
trigram_match = [('likes','VB'),('tea','NN'), ('and','CC')], sentence[0]
bigram_match = [('hates', 'DT'), ('alice', JJ')], sentence[1]
Условие (b) дает нам bigram_match.
НЕПРАВИЛЬНЫЙ вывод будет:
trigram_match = [('the', 'DT'), ('mad', 'JJ'), ('hatter', 'NN')], sentence[0]
bigram_match = [('the', 'DT'), ('mad', 'JJ')] #*bad by condition c
unigram_match = [ [('the', 'DT')] #*bad by condition c
trigram_match = [('likes','VB'),('tea','NN'), ('and','CC')], sentence[0]
bigram_match = [('likes','VB'),('tea','NN')] #*bad by condition c
unigram_match [('likes', 'VB')]# *bad by condition c
и т. Д.
Следующий, очень уродливый код работает хорошо для этого игрушечного примера.Но мне было интересно, есть ли у кого-то более обтекаемый подход.
for ngram in ngrams_to_match:
for sentence in main_text:
for tup in sentence:
#we can't be sure that our part-of-speech tagger will
#tag an ngram word and a main_text word the same way, so
#we match the word in the tuple, not the whole tuple
if ngram[0][0] == tup[0]: #if word in the first ngram matches...
unigram_index = sentence.index(tup) #...then this is our index
unigram = (sentence[unigram_index][0]) #save it as a unigram
try:
if sentence[unigram_index+2][0]==ngram[2][0]:
if sentence[unigram_index+2][0]==ngram[2][0]: #match a trigram
trigram = (sentence[unigram_index][0],span[1][0], ngram[2][0])#save the match
print 'heres the trigram-->', sentence,'\n', 'trigram--->',trigram
except IndexError:
pass
if ngram[0][0] == tup[0]:# == tup[0]: #same as above
unigram_index = sentence.index(tup)
if sentence[unigram_index+1][0]==span[1][0]: #get bigram match
bigram = (sentence[unigram_index][0],span[1][0])#save the match
if bigram[0] and bigram[1] in trigram: #no substring matches
pass
else:
print 'heres a sentence-->', sentence,'\n', 'bigram--->', bigram
if unigram in bigram or trigram: #no substring matches
pass
else:
print unigram