python - 需要帮助创建适当的模型来预测两个句子之间的语义相似性

标签 python machine-learning nlp data-modeling word2vec

我是机器学习领域的新手,正在尝试创建一个模型来预测两个句子之间的语义相似性。 我正在使用以下方法:

1.使用gensim包中的word2vec模型对相关句子中出现的每个单词进行向量化

2.计算每个句子/文档中所有单词的平均向量

import numpy as np
from scipy import spatial

index2word_set = set(model.wv.index2word)

def avg_feature_vector(sentence, model, num_features, index2word_set):
    words = sentence.split()
    feature_vec = np.zeros((num_features, ), dtype='float32')
    n_words = 0
    for word in words:
        if word in index2word_set:
            n_words += 1
            feature_vec = np.add(feature_vec, model[word])
    if (n_words > 0):
        feature_vec = np.divide(feature_vec, n_words)
    return feature_vec

3.接下来计算这两个平均向量之间的余弦相似度

s1_afv = avg_feature_vector('this is a sentence', model=model, 
num_features=300, index2word_set=index2word_set)
s2_afv = avg_feature_vector('this is also sentence', model=model, 
num_features=300, index2word_set=index2word_set)
sim = 1 - spatial.distance.cosine(s1_afv, s2_afv)
print(sim)

引用stackoverflow问题: How to calculate the sentence similarity using word2vec model of gensim with python

以下挑战需要帮助:

因为我想创建一个模型来预测两个句子之间的语义相似性,所以我不太确定:

1.哪种模型最适合这个问题

2.接下来更重要的是如何训练该模型?

我应该创建一个矩阵,其中每行包含两个句子: sen1 和 sen2,我将对它们进行矢量化并计算余弦相似度(按照上述方法)

然后对于训练数据:

X_Train:sen1和sen2的平均向量及其余弦相似度值

y_Train(prediction):一组二进制值(如果余弦相似度 > 0.7,则为 1 或相似值,否则为 0)

我很困惑我的方法是否正确以及如何以工作代码库的形式采用正确的方法。

互联网和在线 Material 是我学习 ML 的唯一老师;因此请求您的指导,帮助我消除理解上的差距,并帮助我为我的问题提出一个良好的工作模型。

最佳答案

您的总体做法是合理的。句子中词向量的平均值通常可以作为句子的粗略摘要向量。 (还有许多其他可能的技术可能会做得更好,但这是一个很好的简单开始。)

您可以使用其他人预先训练的词向量,但如果您有来自您的域的大量文本训练集,那么这些词向量可能会效果更好。您应该寻找有关如何使用 gensim 训练您自己的词向量的教程。例如,其中包含一个演示 Jupyter 笔记本 word2vec.ipynb,位于其 docs/notebooks 目录中,您也可以在以下位置在线查看:

https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/word2vec.ipynb

您当前的 avg_feature_vector() 函数存在许多问题。特别是:

  • 如果您传入model,它已经包含固定的index2word列表,以及一个已经确定的维度数 - 所以没有需要冗余地传递这些

  • 您正在循环模型中的所有单词,而不仅仅是句子中的单词,因此不能仅根据句子进行计算

  • 有更好、更 Pythonic 的方法来执行您尝试的各种数组数学运算 - 包括在 numpy 库中一个简单的 mean() 函数这将使您免于创建平均值的加法/除法

您可能想要解决这些问题,作为练习,但您也可以在词向量模型上使用实用方法。特别是,看看 n_similarity() - 它专门采用两组单词,自动对每组进行平均,然后报告相似性值(更接近 1.0 表示更相似,更接近 -1.0两个集合之间的最不相似)。请参阅:

https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.Word2VecKeyedVectors.n_similarity

因此,如果您在 sent1sent2 中有两个句子(作为字符串),以及一组词向量(要么是您刚刚训练的,要么是从其他地方)在kv_model中,您可以通过以下方式获得句子的相似度:

kv_model.n_similarity(sent1.split(), sent2.split())

(如果模型无法识别任何单词标记,您可能仍然会收到错误。)

您是否实际上为不同的句子创建平均向量并将它们存储在某个列表/字典/数据帧/等中,或者只是记住某处的成对相似性,将取决于您下一步想要做什么。

并且,在掌握了这种简单的文本相似性度量的基础知识后,您可以研究其他技术。例如,使用词向量比较两个文本的另一种方法(但不是通过简单平均值)称为“词移动器距离”。 (不过计算速度要慢一些。)

出于比较的目的,另一种将文本折叠成单个向量的技术在 gensim 中作为 Doc2Vec 提供 - 它的工作原理很像 Word2Vec 而且还创建每个较长文本的向量,而不仅仅是每个单词的向量。

关于python - 需要帮助创建适当的模型来预测两个句子之间的语义相似性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52724444/

相关文章:

python - 有没有一种简单的方法可以告诉 SpaCy 在使用 .similarity 方法时忽略停用词?

python - 控制 Scikit Learn 中逻辑回归的阈值

python - 如何从fastapi中的另一个api调用一个api?

python - Python Flask:获取和发布方法的不同render_template可能吗?

python - 在 MPII 人体姿势数据集上训练 Keras 分类器

c# - 使用 LINQ 进行简单的语言识别

python - 无论元素顺序如何,获取列表中元组的数量

machine-learning - 为什么 Weka 的实验器没有显示全部 10 次折叠的结果?

python-3.x - 断言错误: Mismatch between dataset size and units in output layer

java - SAT4J 求解器的输入 CNF