Чтение и запись предложений с тегами POS из текстовых файлов с использованием NLTK и Python - PullRequest
1 голос
/ 07 апреля 2011

Кто-нибудь знает, существует ли существующий модуль или простой метод для чтения и записи предложений с частичной речью в текстовые файлы и из них? Я использую Python и Natural Language Toolkit (NLTK). Например, этот код:

import nltk

sentences = "Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world."

tagged = nltk.sent_tokenize(sentences.strip())
tagged = [nltk.word_tokenize(sent) for sent in tagged]
tagged = [nltk.pos_tag(sent) for sent in tagged]

print tagged

Возвращает этот вложенный список:

[[('Call', 'NNP'), ('me', 'PRP'), ('Ishmael', 'NNP'), ('.', '.')], [('Some', 'DT'), ('years', 'NNS'), ('ago', 'RB'), ('-', ':'), ('never', 'RB'), ('mind', 'VBP'), ('how', 'WRB'), ('long', 'JJ'), ('precisely', 'RB'), ('-', ':'), ('having', 'VBG'), ('little', 'RB'), ('or', 'CC'), ('no', 'DT'), ('money', 'NN'), ('in', 'IN'), ('my', 'PRP$'), ('purse', 'NN'), (',', ','), ('and', 'CC'), ('nothing', 'NN'), ('particular', 'JJ'), ('to', 'TO'), ('interest', 'NN'), ('me', 'PRP'), ('on', 'IN'), ('shore', 'NN'), (',', ','), ('I', 'PRP'), ('thought', 'VBD'), ('I', 'PRP'), ('would', 'MD'), ('sail', 'VB'), ('about', 'IN'), ('a', 'DT'), ('little', 'RB'), ('and', 'CC'), ('see', 'VB'), ('the', 'DT'), ('watery', 'NN'), ('part', 'NN'), ('of', 'IN'), ('the', 'DT'), ('world', 'NN'), ('.', '.')]]

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

Пример вывода:

<headline>Article headline</headline>
<body>Call me Ishmael...</body>
<pos_tags>[[('Call', 'NNP'), ('me', 'PRP'), ('Ishmael', 'NNP')...</pos_tags>

Ответы [ 2 ]

3 голосов
/ 13 сентября 2012

NLTK имеет стандартный формат файла для тегового текста.Это выглядит так:

Звоните / NNP me / PRP Ishmael / NNP ./.

Вы должны использовать этот формат, так как он позволяет читать файлы сNLTK TaggedCorpusReader и другие подобные классы, и получить полный спектр функций чтения корпуса.Забавно, что в NLTK нет функции высокого уровня для записи помеченного корпуса в этом формате, но это, вероятно, потому, что это довольно тривиально:

for sent in tagged:
    print " ".join(word+"/"+tag for word, tag in sent)

(NLTK действительно обеспечивает nltk.tag.tuple2str(), но он обрабатывает только одно слово - проще набрать word+"/"+tag).

Если вы сохраняете текст с тегами в одном или нескольких файлах fileN.txt в этом формате, вы можете прочитать его обратнос nltk.corpus.reader.TaggedCorpusReader следующим образом:

mycorpus = nltk.corpus.reader.TaggedCorpusReader("path/to/corpus", "file.*\.txt")
print mycorpus.fileids()
print mycorpus.sents()[0]
for sent in mycorpus.tagged_sents():
    <etc>

Обратите внимание, что метод sents() дает вам текст без тегов, хотя и немного странно разнесенный.Нет необходимости включать в файл версии с тегами и без тегов, как в вашем примере.

TaggedCorpusReader не поддерживает заголовки файлов (для заголовка и т. Д.), Но если вам это действительно нужно, вы можете создать свой собственный класс, который читает метаданные файла, а затем обрабатывает остальное, как TaggedCorpusReader.

1 голос
/ 07 апреля 2011

Кажется, что использование pickle.dumps и вставка его вывода в ваш текстовый файл, возможно, с помощью оболочки для тегов для автоматической загрузки, удовлетворит ваши требования.

Можете ли вы быть более точным в отношении того, как должен выглядеть вывод текста? Вы стремитесь к чему-то более понятному человеку?

РЕДАКТИРОВАТЬ: добавить код

from xml.dom.minidom import Document, parseString
import nltk

sentences = "Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world."

tagged = nltk.sent_tokenize(sentences.strip())
tagged = [nltk.word_tokenize(sent) for sent in tagged]
tagged = [nltk.pos_tag(sent) for sent in tagged]

# Write to xml string
doc = Document()

base = doc.createElement("Document")
doc.appendChild(base)

headline = doc.createElement("headline")
htext = doc.createTextNode("Article Headline")
headline.appendChild(htext)
base.appendChild(headline)

body = doc.createElement("body")
btext = doc.createTextNode(sentences)
headline.appendChild(btext)
base.appendChild(body)

pos_tags = doc.createElement("pos_tags")
tagtext = doc.createTextNode(repr(tagged))
pos_tags.appendChild(tagtext)
base.appendChild(pos_tags)

xmlstring = doc.toxml()

# Read back tagged

doc2 = parseString(xmlstring)
el = doc2.getElementsByTagName("pos_tags")[0]
text = el.firstChild.nodeValue
tagged2 = eval(text)

print "Equal? ", tagged == tagged2
...