Как вывести NLTK pos_tag в строку вместо списка?

Мне нужно запустить nltk.pos_tag для большого набора данных, и мне нужно, чтобы его вывод был похож на тот, который предлагает Stanford tagger.

Например, во время выполнения следующего кода у меня есть;

import nltk
text=nltk.word_tokenize("We are going out.Just you and me.")
print nltk.pos_tag(text)

вывод: [('Мы', 'PRP'), ('являются', 'VBP'), ('идущие', 'VBG'), ('out.Just', 'IN'), ('вы ', 'PRP'), ('and', 'CC'), ('me', 'PRP'), ('.', '.')]

В том случае, если мне нужно, чтобы это было похоже на:

 We/PRP are/VBP going/VBG out.Just/NN you/PRP and/CC me/PRP ./.

Я предпочитаю не использовать строковые функции и нуждаюсь в прямом выводе, потому что объем текста очень высок, и это добавляет много временных сложностей к обработке

1 ответ

Решение

Короче:

' '.join([word + '/' + pos for word, pos in tagged_sent]

В длинных:

Я думаю, что вы задумывались об использовании строковых функций для объединения строк, это действительно не так дорого.

import time
from nltk.corpus import brown

tagged_corpus = brown.tagged_sents()

start = time.time()

with open('output.txt', 'w') as fout:
    for i, sent in enumerate(tagged_corpus):
        print(' '.join([word + '/' + pos for word, pos in sent]), end='\n', file=fout)

end = time.time() - start
print (i, end)

На моем ноутбуке потребовалось 2,955 секунды для всех 57339 предложений из коричневого корпуса.

[из]:

$ head -n1 output.txt 
The/AT Fulton/NP-TL County/NN-TL Grand/JJ-TL Jury/NN-TL said/VBD Friday/NR an/AT investigation/NN of/IN Atlanta's/NP$ recent/JJ primary/NN election/NN produced/VBD ``/`` no/AT evidence/NN ''/'' that/CS any/DTI irregularities/NNS took/VBD place/NN ./.

Но использование строки для объединения слова и POS может вызвать проблемы позже, когда вам нужно прочитать помеченный вывод, например

>>> from nltk import pos_tag
>>> tagged_sent = pos_tag('cat / dog'.split())
>>> tagged_sent_str = ' '.join([word + '/' + pos for word, pos in tagged_sent])
>>> tagged_sent_str
'cat/NN //CD dog/NN'
>>> [tuple(wordpos.split('/')) for wordpos in tagged_sent_str.split()]
[('cat', 'NN'), ('', '', 'CD'), ('dog', 'NN')]

Если вы хотите сохранить помеченный вывод, а затем прочитать его, лучше использовать pickle сохранить tagged_output, например

>>> import pickle
>>> tagged_sent = pos_tag('cat / dog'.split())
>>> with open('tagged_sent.pkl', 'wb') as fout:
...     pickle.dump(tagged_sent, fout)
... 
>>> tagged_sent = None
>>> tagged_sent
>>> with open('tagged_sent.pkl', 'rb') as fin:
...     tagged_sent = pickle.load(fin)
... 
>>> tagged_sent
[('cat', 'NN'), ('/', 'CD'), ('dog', 'NN')]
Другие вопросы по тегам