Выглядит долго, но работает:
ner_output = [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION'), (u'Party', u'ORGANIZATION')]
chunked, pos = [], ""
for i, word_pos in enumerate(ner_output):
word, pos = word_pos
if pos in ['PERSON', 'ORGANIZATION', 'LOCATION'] and pos == prev_tag:
chunked[-1]+=word_pos
else:
chunked.append(word_pos)
prev_tag = pos
clean_chunked = [tuple([" ".join(wordpos[::2]), wordpos[-1]]) if len(wordpos)!=2 else wordpos for wordpos in chunked]
print clean_chunked
[из]:
[(u'Remaking', u'O'), (u'The', u'O'), (u'Republican Party', u'ORGANIZATION')]
Больше подробностей:
Первый цикл for "с памятью" дает примерно следующее:
[(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION')]
Вы поймете, что все Name Enitties будут иметь более двух элементов в кортеже, и вам нужны слова в качестве элементов в списке, то есть 'Republican Party'
в (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION')
, поэтому вы сделаете что-то вроде этого, чтобы получить четные элементы:
>>> x = [0,1,2,3,4,5,6]
>>> x[::2]
[0, 2, 4, 6]
>>> x[1::2]
[1, 3, 5]
Затем вы также поняли, что последний элемент в кортеже NE - это тег, который вам нужен, поэтому вы должны сделать `
>>> x = (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION')
>>> x[::2]
(u'Republican', u'Party')
>>> x[-1]
u'ORGANIZATION'
Это немного ad-hoc и vebose, но я надеюсь, что это поможет. И вот оно в функции, Благословенное Рождество:
ner_output = [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION'), (u'Party', u'ORGANIZATION')]
def rechunk(ner_output):
chunked, pos = [], ""
for i, word_pos in enumerate(ner_output):
word, pos = word_pos
if pos in ['PERSON', 'ORGANIZATION', 'LOCATION'] and pos == prev_tag:
chunked[-1]+=word_pos
else:
chunked.append(word_pos)
prev_tag = pos
clean_chunked = [tuple([" ".join(wordpos[::2]), wordpos[-1]])
if len(wordpos)!=2 else wordpos for wordpos in chunked]
return clean_chunked
print rechunk(ner_output)
person
alvas
schedule
23.12.2014