我正在尝试使用负采样训练Skip-gram word2vec模型。根据我的理解,我需要生成对(目标,上下文)和标签,其中0 =不在上下文中,而1 =在上下文中。
我们应该逐句制作make曲夫妇吗?还是应该将句子拼合为一个大句子,然后从中生成跳过词? 换句话说,生成的对应该跨句子吗?
下面两个代码段之间的唯一区别是,其中一个生成跨两个句子的对,如下所示:
data = ['this is some stuff.', 'I have a cookie.']
结果:
...SNIP...
[some, have]
[stuff, this]
[stuff, is]
[stuff, some]
[stuff, i]
[stuff, have]
[stuff, a]
[i, is]
[i, some]
[i, stuff]
[i, have]
[i, a]
[i, cookie]
[have, some]
[have, stuff]
...SNIP...
我们可以看到有几对跨句子的
或者我们可以有几对不跨句子的夫妻:
...SNIP...
[some, stuff]
[stuff, this]
[stuff, is]
[stuff, some]
[i, have]
[i, a]
[i, cookie]
[have, i]
[have, a]
[have, cookie]
...SNIP...
获取数据
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train',
remove=('headers', 'footers', 'quotes'))
初始化一些变量
vocabulary_size = 8
window_size = 3
neg_samples = 0.0
将句子分为一个大序列
sents = newsgroups_train.data
tokenizer = Tokenizer(num_words= vocabulary_size, lower=True, filters=filters)
tokenizer.fit_on_texts(sents)
word_index_inv = {v: k for k, v in tokenizer.word_index.items()}
sequences = tokenizer.texts_to_sequences(sents)
couples, labels = skipgrams(list(itertools.chain.from_iterable(sequences)), vocabulary_size=vocabulary_size, window_size=window_size, shuffle=False, negative_samples=neg_samples)
word_target, word_context = zip(*couples)
word_target = np.array(word_target, dtype="int32")
word_context = np.array(word_context, dtype="int32")
将数据集拆分为句子,然后根据每个句子生成配对。
sents = [nltk.sent_tokenize(s) for s in newsgroups_train.data]
sents = list(itertools.chain.from_iterable(sents))
tokenizer = Tokenizer(num_words= vocabulary_size, lower=True, filters=filters)
tokenizer.fit_on_texts(sents)
word_index_inv = {v: k for k, v in tokenizer.word_index.items()}
sequences = tokenizer.texts_to_sequences(sents)
couples = []
labels = []
for seq in sequences:
c,l = skipgrams(seq, vocabulary_size=vocabulary_size,
window_size=window_size, shuffle=False,
negative_samples=neg_samples)
couples.extend(c)
labels.extend(l)
word_target, word_context = zip(*couples)
word_target = np.array(word_target, dtype="int32")
word_context = np.array(word_context, dtype="int32")
打印出我们的文字
for couple in couples:
print('[{}, {}]'.format(word_index_inv[couple[0]], word_index_inv[couple[1]]))
答案 0 :(得分:1)
通常无论哪种方式都没关系。
即使库/ API谈论“句子”,它们实际上也意味着“文本”,它可能是多个句子。
最糟糕的情况是,如果在某些上下文中跨越了与文本没有本质关系的文本,那么这会给培训带来一点噪音...这可能需要更多的培训才能在其他非噪声方面达到最优上下文。但是,通常在一起运行的文本实际上是从相同的原始来源关联的,因此,此类上下文可能仍会捕获真正有用的模式,因此与较小的文本片段相比,它是净肯定的。
您可以同时尝试两种方法,并对结果进行评分,以查看语料和最终任务是否更好。