【问题标题】:Word2Vec Skipgrams - Should couples span sentences?Word2Vec Skipgrams - 夫妻应该跨越句子吗?
【发布时间】:2025-12-19 10:50:12
【问题描述】:

背景

我正在尝试使用负采样训练 Skip-gram word2vec 模型。据我了解,我需要生成一对(目标、上下文)和一个标签,其中 0 = 不在上下文中,1 = 在上下文中。

我不确定的:

我们应该逐句制作skipgram对吗?还是我们应该将句子扁平化为一个大句子并从中生成skipgrams? 换句话说,生成的情侣是否应该跨越句子?

下面两个代码 sn-ps 之间的唯一区别是其中一个生成跨越两个句子的对,如下所示:

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]]))

【问题讨论】:

    标签: python keras word2vec word-embedding


    【解决方案1】:

    通常这两种方式都无关紧要。

    即使库/API 谈论“句子”,它们实际上是指“文本”,可能是多个句子。

    最糟糕的情况是,如果您最终遇到一些跨越没有本质关系的文本的上下文,那就是它会给训练增加一点噪音......这可能需要更多的训练才能在其他非噪音上达到最优上下文。但通常运行在一起的文本实际上是相关的,来自相同的原始来源,所以这样的上下文可能仍然捕捉到真正有用的模式,因此与较小的文本片段相比是一个净正面的。

    您可以尝试这两种方法,并相互对结果进行评分,看看其中一种方法是否更适合您的语料库和结束任务。

    【讨论】:

    • 谢谢我一直在尝试这两种方法,它们似乎给出了相对相似的结果