Gensim Word2Vec模型通过增加时期数而变得更糟

问题描述 投票:0回答:1

我正在由约35.000个句子组成的数据集上构建Word2Vec模型,总共约500.000个单词。我基本上是这样构建模型的:

def train_w2v_model(df, epochs):
    w2v_model = Word2Vec(min_count=int(nb_words*MIN_FREQUENCY_OF_TAGS),
                                 window=100,
                                 size=int(params['embedding_size']),
                                 sample=0,
                                 workers=cores-1,
                                 batch_words=100)
    vocab = df['sentences'].apply(list)
    w2v_model.build_vocab(vocab)
    w2v_model.train(vocab, total_examples=w2v_model.corpus_count, total_words=w2v_model.corpus_total_words, epochs=epochs, compute_loss=True)
    return w2v_model.get_latest_training_loss()

我试图为这样的模型找到正确的时期数:

print(train_w2v_model(1))
=>> 86898.2109375
print(train_w2v_model(100))
=>> 5025273.0

我发现结果非常违反直觉。我不了解增加纪元数可能会导致性能降低。这似乎不是对函数get_latest_training_loss的误解,因为我仅用1个历元就更好地观察了函数most_similar的结果:

100个纪元:

w2v_model.wv.most_similar(['machine_learning'])
=>> [('salesforce', 0.3464601933956146),
 ('marketing_relationnel', 0.3125850558280945),
 ('batiment', 0.30903393030166626),
 ('go', 0.29414454102516174),
 ('simulation', 0.2930642068386078),
 ('data_management', 0.28968319296836853),
 ('scraping', 0.28260597586631775),
 ('virtualisation', 0.27560457587242126),
 ('dataviz', 0.26913416385650635),
 ('pandas', 0.2685554623603821)]

1个纪元:

w2v_model.wv.most_similar(['machine_learning'])
=>> [('data_science', 0.9953729510307312),
 ('data_mining', 0.9930223822593689),
 ('big_data', 0.9894922375679016),
 ('spark', 0.9881765842437744),
 ('nlp', 0.9879133701324463),
 ('hadoop', 0.9834049344062805),
 ('deep_learning', 0.9831978678703308),
 ('r', 0.9827396273612976),
 ('data_visualisation', 0.9805369973182678),
 ('nltk', 0.9800992012023926)]

关于它为何如此表现的任何见解?我本以为增加纪元数肯定会对training损失产生积极的影响。

python machine-learning nlp gensim word2vec
1个回答
0
投票

首先,至少通过gensim-3.8.1(2019年9月),报告跑步训练损失,有点不成熟。这只是所有时期的所有损失的总和-因此一直在增加-而不是可能减少的每个时期的损失。 fix that still needs a little work是一个长期未决的订单,但在添加之前,已报告的数字需要与早期数字进行额外比较,以检测各个时期之间的减少。

但也要注意:即使是每个周期的损失也不是直接用于外部目的模型质量/性能的度量。这只是培训是否仍在帮助其内部优化任务的指标。

[其次,如果实际上在外部评估下该模型变得越来越差(例如most_similar()结果是否与人工估计相符时),则需要进行更多的培训,这通常表明过度拟合正在发生。也就是说,(可能过大)模型正在存储(可能过小)训练数据的特征,从而以不再笼统地关注更大的领域来实现其内部优化目标。

500K总单词对于word2vec训练集来说是很小的,但是如果您还打算只训练一个小词汇量(因此每个单词仍然有很多示例)并且使用小尺寸的向量,则可以使用。

尚不清楚您计算出的min_count是什么,但请注意,通过缩小模型来增加它可以对抗过度拟合。但也请注意,在训练过程中出现次数少于该阈值的单词将被完全忽略,从而使有效训练数据量变小。

[类似地,不清楚您正在使用什么embedding_size,但是尝试为小的词汇量制作“很大”的向量非常容易拟合,因为向量有很多“空间”来记住训练细节。较小的向量会在模型上施加某种“压缩”,从而导致学习更可能泛化。 (我非常粗略的经验法则,就是根本没有严格地建立起来,就是永远不要使用比预期词汇量的平方根大的密集嵌入量。因此,使用10K令牌时,不得超过100维向量。)

[其他观察结果,可能与您的问题无关,但可能与您的目标有关:

  • window=100是非典型的,并且似乎远远大于您的平均文本大小(〜14个单词)–如果目的是所有标记都应影响所有其他标记,而无需考虑距离(也许是因为源数据本来就是无序的) ),这是适当的,并且您可能会大得多(例如100万)。另一方面,如果令牌的直接邻居比同一文本中的其他邻居更相关,则较小的窗口将很有意义。

  • 没有充分的理由使用batch_words=100 –它只会减慢训练速度,并且如果实际上您有任何大于100个字的文本,则会人为地将它们分解(从而使巨人无法获得任何好处[ C0]值以上)。 (将其保留为默认值。)

  • window方法将仅使用train()total_examples,但不能同时使用两者-因此,您只需指定一个

    ] >>
  • [看起来好像您可能正在使用类别建议而不是纯自然语言,您可能还想修改total_words参数的非默认值–请参阅文档注释和参考文件有关该参数的ns_exponent,以获取更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.