我试着在一组.txt文件上运行word2vec(使用gensim实现的skip-gram模型,窗口大小为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分词器做到这一点)有多重要?对于算法中的每个单词来说,接收到所在行周围单词的上下文是否足够(在跨越多行的情况下,这些单词可能不是实际的句子),而不是单词在跨越多行的句子中可能具有的上下文。此外,窗口大小在其中扮演什么角色?例如,当窗口大小设置为5时,由Sentences迭代器产生的句子大小是否不再起作用?那么只有窗口大小决定上下文单词吗?在这种情况下,我应该只使用
line.split()
而不是尝试使用punkt分词器检测实际的句子边界吗?希望我已经足够描述了这个问题,我真的很感激任何关于这个问题的意见、指针或帮助。