《Comparing Sentence Similarity Methods》Yves Peirsman; May 2, 2018
原文链接:http://nlp.town/blog/sentence-similarity/
这篇文章对比了几种当时最流行的计算句子相似度的方法。这里是代码,代码超赞!
数据集
对比实验使用了两个测试集,一个STS Benchmark数据集,一个SICK data数据集。
方法
Baseline
- 表示方法:平均词嵌入
- 度量方法:余弦相似度
改进思路:去停用词;加权,比如tf-idf;
Word Mover's Distance
词移距离,论文:http://proceedings.mlr.press/v37/kusnerb15.pdf
Smooth Inverse Frequency
- 加权,权重*词向量,权重=a/(a+p(w)),a是一个常数,通常是0.001,p(w)是词在语料集中的频率;
- 移除第一主成分,比如but、just等;
论文:https://openreview.net/forum?id=SyK00v5xx
from sklearn.decomposition import TruncatedSVD
def remove_first_principal_component(X):
svd = TruncatedSVD(n_components=1, n_iter=7, random_state=0)
svd.fit(X)
pc = svd.components_
XX = X - X.dot(pc.transpose()) * pc
return XX
def run_sif_benchmark(sentences1, sentences2, model, freqs={}, use_stoplist=False, a=0.001):
total_freq = sum(freqs.values())
embeddings = []
# SIF requires us to first collect all sentence embeddings and then perform
# common component analysis.
for (sent1, sent2) in zip(sentences1, sentences2):
tokens1 = sent1.tokens_without_stop if use_stoplist else sent1.tokens
tokens2 = sent2.tokens_without_stop if use_stoplist else sent2.tokens
tokens1 = [token for token in tokens1 if token in model]
tokens2 = [token for token in tokens2 if token in model]
weights1 = [a/(a+freqs.get(token,0)/total_freq) for token in tokens1]
weights2 = [a/(a+freqs.get(token,0)/total_freq) for token in tokens2]
embedding1 = np.average([model[token] for token in tokens1], axis=0, weights=weights1)
embedding2 = np.average([model[token] for token in tokens2], axis=0, weights=weights2)
embeddings.append(embedding1)
embeddings.append(embedding2)
embeddings = remove_first_principal_component(np.array(embeddings))
sims = [cosine_similarity(embeddings[idx*2].reshape(1, -1),
embeddings[idx*2+1].reshape(1, -1))[0][0]
for idx in range(int(len(embeddings)/2))]
return sims
预训练
- Facebook‘s InferSent
- Google Sentence Encoder
- 没有使用Transformer模型
结果
Baseline
- w2v比glove效果好
- 去停用词和tf-idf加权不稳定
Word Mover's Distance
- 效果不明显
Smooth Inverse Frequency
- 比平均词嵌入效果好
Pre-trained encoders
- 使用Pearson correlation coefficient评估,效果和SIF差不多;
- 使用Spearman correlation评估,google sentence encoder表现较好;
结论
句子相似度是一个复杂的事物。句子的含义不仅和句子中的词有关,也和词的组合方式有关。语义相似度和句子相似度也有较大的差异,目前句子嵌入方法也只是刚刚从表面起步。
- 通常w2v比GloVe更好;
- SIF通常比简单的平均词嵌入效果好;
- 如果使用预训练方法,Google Sentence Encoder比InferSent效果好;
找我内推: 字节跳动各种岗位
作者:
ZH奶酪(张贺)
邮箱:
cheesezh@qq.com
出处:
http://www.cnblogs.com/CheeseZH/
*
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。