• 《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效果好;
  • 相关阅读:
    【转】自旋锁及其衍生锁
    【转】 android 4.4 Step Counter Sensor计步器的使用
    【转】ListView与RadioButton组合——自定义单选列表
    【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法
    【转】Android 带checkbox的listView 实现多选,全选,反选 -- 不错
    【转】linux 原子整数操作详解
    计算机科学界名言
    计算机科学界名言
    益智小游戏(app)
    益智小游戏(app)
  • 原文地址:https://www.cnblogs.com/CheeseZH/p/13272282.html
Copyright © 2020-2023  润新知