Можно ли использовать XMLCorpusReader NLTK в многофайловом корпусе?

Я пытаюсь использовать NLTK делать какую-то работу на Аннотированный корпус New York Times, который содержит файл XML для каждой статьи (в текстовом формате новостной индустрии NITF).

Я могу без проблем разобрать отдельные документы так:

from nltk.corpus.reader import XMLCorpusReader
reader = XMLCorpusReader('nltk_data/corpora/nytimes/1987/01/01', r'0000000.xml')

Но мне нужно работать над всем корпусом. Я пытался сделать это:

reader = XMLCorpusReader('corpora/nytimes', r'.*')

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

len(reader.words())

возвращается

raise TypeError('Expected a single file identifier string')
TypeError: Expected a single file identifier string

Как прочитать этот корпус в NLTK?

Я новичок в NLTK, поэтому любая помощь приветствуется.


person NAD    schedule 26.07.2011    source источник


Ответы (3)


Я не эксперт NLTK, поэтому может быть более простой способ сделать это, но наивно я бы посоветовал вам использовать модуль Python glob. Он поддерживает расширение шаблона пути в стиле Unix.

from glob import glob
texts = glob('nltk_data/corpora/nytimes/*')

Таким образом, вы получите имена файлов, соответствующие указанному выражению, в форме списка. Затем, в зависимости от того, сколько из них вы хотите/нужно открыть одновременно, вы можете сделать:

from nltk.corpus.reader import XMLCorpusReader
for item_path in texts:
    reader = XMLCorpusReader('nltk_data/corpora/nytimes/', item_path)

Как предлагает @waffle paradox:, вы также можете сократить этот список texts в соответствии со своими конкретными потребностями.

person machine yearning    schedule 26.07.2011

Вот решение, основанное на машинном стремлении и комментариях парадокса вафли. Создайте список статей, используя glob, и передайте их XMLCorpusReader в виде списка:

from glob import glob
import re
years = glob('nltk_data/corpora/nytimes_test/*')
year_months = []
for year in years:
    year_months += glob(year+'/*')
    print year_months
days = []
for year_month in year_months:
    days += glob(year_month+'/*')
articles = []
for day in days:
    articles += glob(day+'/*.xml')
file_ids = []
for article in articles:
    file_ids.append(re.sub('nltk_data/corpora/nytimes_test','',article))
reader = XMLCorpusReader('nltk_data/corpora/nytimes_test', articles)
person NAD    schedule 27.07.2011

Да, вы можете указать несколько файлов. (от: http://nltk.googlecode.com/svn/trunk/doc/api/nltk.corpus.reader.xmldocs.XMLCorpusReader-class.html)

Проблема здесь в том, что я подозреваю, что все ваши файлы содержатся в файловой структуре в соответствии со строками corpora/nytimes/year/month/date. XMLCorpusReader не выполняет рекурсивный обход каталогов за вас. то есть с вашим кодом выше, XMLCorpusReader('corpora/nytimes', r'.*'), XMLCorpusReader видит только файлы xml в corpora/nytimes/ (т. е. ни один, поскольку есть только папки), а не в каких-либо подпапках, которые может содержать corpora/nytimes. Кроме того, вы, вероятно, хотели использовать *.xml в качестве второго параметра.

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

person waffle paradox    schedule 26.07.2011
comment
Спасибо Вафельный Парадокс. Это очень полезно. - person NAD; 27.07.2011