我正在帮助我的一位教授进行一项研究项目,该项目涉及从一组20个文本文件中随机抽取一千个句子。这是来自当代美国英语语料库的所有数据,如果有人熟悉使用它。在这些文本文件中,数据的排列如下:
Blockquote ## 4000348我必须首先这样说:为了准备这个讲座,我阅读(或在某些情况下重读)Sidney Hook的一些着作。我只是为了给Sidney Hook的演讲而给我一个正确的起点。但相反,我发现自己注入了一系列与不同环境,不同场合相关的想法。
## 4000349我想我最为人所知的是我的智慧和学习,但事实上我的成名来自于我是一位知名的保守派,同时也是耶鲁大学的院长。这就是我被任命的消息出现在“华尔街日报”和“国家评论”中的原因,这种情况通常不会发生在耶鲁大学的院长身上,并且在这种情况下对他们没有多大帮助。
BLOCKQUOTE>
因此,有数百个段落,每个段落以一个前面带有“##”的六位数字开头。该数字对应于句子的来源。我需要从这些文件中提取随机句子,并获得六位数字来识别它们的来源。理想情况下,我会得到类似的东西:
Blockquote ## 4000348我只是为了给Sidney Hook的演讲而给我一个正确的起点
## 4000349我想我最为人所知的是我的智慧和学习,但实际上我的名气来自于我是一位知名的保守派,同时也是耶鲁大学的院长。
我已经成功地从文件中获取随机句子(在stackoverflow处有一些善意的帮助)但是我不知道如何将数字附加到它们上(例如,如果我从段落的中间,我怎么能从段落的开头得到数字)。任何人都可以帮我想办法吗?这是我到目前为止的代码,它成功地提取了句子。
"Got to here", then runs
答案 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".*?[\.\!\?]+"
正则表达式更强大的解决方案。