从文本文件中随机选择句子,查找Coresponding ID号

时间:2016-03-22 20:44:13

标签: python regex random linguistics

我正在帮助我的一位教授进行一项研究项目,该项目涉及从一组20个文本文件中随机抽取一千个句子。这是来自当代美国英语语料库的所有数据,如果有人熟悉使用它。在这些文本文件中,数据的排列如下:

  

Blockquote ## 4000348我必须首先这样说:为了准备这个讲座,我阅读(或在某些情况下重读)Sidney Hook的一些着作。我只是为了给Sidney Hook的演讲而给我一个正确的起点。但相反,我发现自己注入了一系列与不同环境,不同场合相关的想法。

   ## 4000349我想我最为人所知的是我的智慧和学习,但事实上我的成名来自于我是一位知名的保守派,同时也是耶鲁大学的院长。这就是我被任命的消息出现在“华尔街日报”和“国家评论”中的原因,这种情况通常不会发生在耶鲁大学的院长身上,并且在这种情况下对他们没有多大帮助。

  BLOCKQUOTE>

因此,有数百个段落,每个段落以一个前面带有“##”的六位数字开头。该数字对应于句子的来源。我需要从这些文件中提取随机句子,并获得六位数字来识别它们的来源。理想情况下,我会得到类似的东西:

  

Blockquote ## 4000348我只是为了给Sidney Hook的演讲而给我一个正确的起点

   ## 4000349我想我最为人所知的是我的智慧和学习,但实际上我的名气来自于我是一位知名的保守派,同时也是耶鲁大学的院长。

我已经成功地从文件中获取随机句子(在stackoverflow处有一些善意的帮助)但是我不知道如何将数字附加到它们上(例如,如果我从段落的中间,我怎么能从段落的开头得到数字)。任何人都可以帮我想办法吗?这是我到目前为止的代码,它成功地提取了句子。

"Got to here", then runs

2 个答案:

答案 0 :(得分:4)

也许您可以使用正则表达式提取每个段落及其源ID,然后从段落中提取句子,类似于您此刻的操作方式。这应该可以帮助你抓住这段话:

# with open... etc.
for source_id, paragraph in re.findall(r"(##\d+)([^#]+)", f.read()):
    sentences += [(source_id, sentence) for sentence in re.findall(r".*?[\.\!\?]+", paragraph)]

现在,sentences应该是('##123', 'A sentence.')之类的元组列表,您可以像以前一样对其进行采样。

答案 1 :(得分:2)

一般情况下,为了避免一次性将(可能很大的)文件加载到内存中,您可以使用a reservoir sampling algorithm - 只需传递一个迭代器,该迭代器产生带标签(带有## - 数字)的句子:

#!/usr/bin/env python
import re
import nltk  # $ pip install nltk

def paragraphs(file):
    """Yield blank-line separated paragraphs labeled with ##-numbers."""
    lines = []
    for line in file:
        if line.strip():
            lines.append(line)
        elif lines:  # blank line, the end of a non-empty paragraph
            paragraph = ''.join(lines)
            numbers = re.findall(r'##([0-9]+)', paragraph)  # only ASCII-digits
            assert len(numbers) == 1  # only one ##-number per paragraph
            yield int(numbers[0]), paragraph
            del lines[:]

def sentences(filenames):
    for filename in filenames:
        with open(filename) as file:
            for number, paragraph in paragraphs(file):
                for sentence in nltk.sent_tokenize(paragraph):
                    yield number, sentence

filenames = ('w_acad_%d.txt' % n for n in range(1990, 2013))
print(reservoir_sample(sentences(filenames), 2000))

其中reservoir_sample() is defined here

nltk.sent_tokenize()可能是比r".*?[\.\!\?]+"正则表达式更强大的解决方案。