我正在尝试在 .txt 文件的语料库上运行 word2vec(在 gensim 中实现的跳过语法模型,默认窗口大小为 5)。我使用的迭代器看起来像这样:
class Corpus(object):
"""Iterator for feeding sentences to word2vec"""
def __init__(self, dirname):
self.dirname = dirname
def __iter__(self):
word_tokenizer = TreebankWordTokenizer()
sent_tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
text = ''
for root, dirs, files in os.walk(self.dirname):
for file in files:
if file.endswith(".txt"):
file_path = os.path.join(root, file)
with open(file_path, 'r') as f:
text = f.read().decode('utf-8')
sentences = sent_tokenizer.tokenize(text)
for sent in sentences:
yield word_tokenizer.tokenize(sent)
在这里,我使用 nltk 包中的 punkt 分词器(它使用无监督算法来检测句子边界)将文本拆分为句子。但是,当我将其替换为一个简单的line.split()
即仅将每个句子视为一行并拆分单词时,我得到的时间效率比使用 nltk 解析器快 1.5 倍。'with open' 中的代码如下所示:
with open(file_path, 'r') as f:
for line in f:
line.decode('utf-8')
yield line.split()
我的问题是,对于 word2vec 算法来说,输入实际句子的句子有多重要(我试图用 punkt tokenizer 做的事情)?算法中的每个单词是否足以接收位于一行上的周围单词的上下文(在跨多行的句子的情况下,这些单词可能不一定是实际句子)而不是单词的上下文这个词在一个句子中可能有好几行。此外,窗口大小在其中起到什么样的作用。例如,当窗口大小设置为 5 时,Sentences 迭代器产生的句子大小是否不再起作用?那么只有窗口大小会决定上下文词吗?在那种情况下,我应该只使用line.split()
而不是尝试使用 punkt 标记器检测实际的句子边界吗?
我希望我能够充分描述这个问题,我非常感谢任何关于此的意见、指示或帮助。