1. 程式人生 > >lucene計算文字相似度演算法

lucene計算文字相似度演算法

Leveraging term vectors
        所謂term vector, 就是對於documents的某一field,如title,body這種文字型別的, 建立詞頻的多維向量空間.每一個詞就是一維, 這維的值就是這個詞在這個field中的頻率.

        如果你要使用term vectors, 就要在indexing的時候對該field開啟term vectors的選項:

        Field options for term vectors
        TermVector.YES – record the unique terms that occurred, and their counts, in each document, but do not store any positions or offsets information.
        TermVector.WITH_POSITIONS – record the unique terms and their counts, and also the positions of each occurrence of every term, but no offsets.
        TermVector.WITH_OFFSETS – record the unique terms and their counts, with the offsets (start & end character position) of each occurrence of every term, but no positions.
        TermVector.WITH_POSITIONS_OFFSETS – store unique terms and their counts, along with positions and offsets.
        TermVector.NO – do not store any term vector information.
        If Index.NO is specified for a field, then you must also specify TermVector.NO.

        這樣在index完後, 給定這個document id和field名稱, 我們就可以從IndexReader讀出這個term vector(前提是你在indexing時建立了terms vector):
        TermFreqVector termFreqVector = reader.getTermFreqVector(id, "subject");
        你可以遍歷這個TermFreqVector去取出每個詞和詞頻, 如果你在index時選擇存下offsets和positions資訊的話, 你在這邊也可以取到.

        有了這個term vector我們可以做一些有趣的應用:


        1) Books like this


        比較兩本書是否相似,把書抽象成一個document檔案, 具有author, subject fields. 那麼現在就通過這兩個field來比較兩本書的相似度.
author這個field是multiple fields, 就是說可以有多個author, 那麼第一步就是比author是否相同,
String[] authors = doc.getValues("author");
BooleanQuery authorQuery = new BooleanQuery(); // #3
for (int i = 0; i < authors.length; i++) { // #3
    String author = authors[i]; // #3
    authorQuery.add(new TermQuery(new Term("author", author)), BooleanClause.Occur.SHOULD); // #3
}
authorQuery.setBoost(2.0f);


        最後還可以把這個查詢的boost值設高, 表示這個條件很重要, 權重較高, 如果作者相同, 那麼就很相似了.
        第二步就用到term vector了, 這裡用的很簡單, 單純的看subject field的term vector中的term是否相同,


TermFreqVector vector = // #4
reader.getTermFreqVector(id, "subject"); // #4
BooleanQuery subjectQuery = new BooleanQuery(); // #4
for (int j = 0; j < vector.size(); j++) { // #4
    TermQuery tq = new TermQuery(new Term("subject", vector.getTerms()[j]));
    subjectQuery.add(tq, BooleanClause.Occur.SHOULD); // #4
}

        2) What category?


        這個比上個例子高階一點, 怎麼分類了,還是對於document的subject, 我們有了term vector.
所以對於兩個document, 我們可以比較這兩個文章的term vector在向量空間中的夾角, 夾角越小說明這個兩個document越相似.
那麼既然是分類就有個訓練的過程, 我們必須建立每個類的term vector作為個標準, 來給其它document比較.
這裡用map來實現這個term vector, (term, frequency), 用n個這樣的map來表示n維. 我們就要為每個category來生成一個term vector, category和term vector也可以用一個map來連線.建立這個category的term vector, 這樣做:


        遍歷這個類中的每個document, 取document的term vector, 把它加到category的term vector上.
 

private void addTermFreqToMap(Map vectorMap, TermFreqVector termFreqVector) {
    String[] terms = termFreqVector.getTerms();
    int[] freqs = termFreqVector.getTermFrequencies();
    for (int i = 0; i < terms.length; i++) {
        String term = terms[i];
        if (vectorMap.containsKey(term)) {
            Integer value = (Integer) vectorMap.get(term);
            vectorMap.put(term, new Integer(value.intValue() + freqs[i]));
        } else {
            vectorMap.put(term, new Integer(freqs[i]));
        }
   }
}
 

        首先從document的term vector中取出term和frequency的list, 然後從category的term vector中取每一個term, 把document的term frequency加上去.OK了

        有了這個每個類的category, 我們就要開始計算document和這個類的向量夾角了


        cos = A*B/|A||B|
        A*B就是點積, 就是兩個向量每一維相乘, 然後全加起來.


        這裡為了簡便計算, 假設document中term frequency只有兩種情況, 0或1.就表示出現或不出現
 

private double computeAngle(String[] words, String category) {
    // assume words are unique and only occur once
    Map vectorMap = (Map) categoryMap.get(category);
    int dotProduct = 0;
    int sumOfSquares = 0;
    for (int i = 0; i < words.length; i++) {
        String word = words[i];
        int categoryWordFreq = 0;
        if (vectorMap.containsKey(word)) {
            categoryWordFreq = ((Integer) vectorMap.get(word)).intValue();
        }
        dotProduct += categoryWordFreq; // optimized because we assume frequency in words is 1
        sumOfSquares += categoryWordFreq * categoryWordFreq;
    }
    double denominator;
    if (sumOfSquares == words.length) {
        // avoid precision issues for special case
        denominator = sumOfSquares; // sqrt x * sqrt x = x
    } else {
        denominator = Math.sqrt(sumOfSquares) *
        Math.sqrt(words.length);
    }
    double ratio = dotProduct / denominator;
    return Math.acos(ratio);
}
 

        這個函式就是實現了上面那個公式還是比較簡單的.

        3) MoreLikeThis

        對於找到比較相似的文件,lucene還提供了個比較高效的介面,MoreLikeThis介面

        對於上面的方法我們可以比較每兩篇文件的餘弦值,然後對餘弦值進行排序,找出最相似的文件,但這個方法的最大問題在於計算量太大,當文件數目很大時,幾乎是無法接受的,當然有專門的方法去優化餘弦法,可以使計算量大大減少,但這個方法精確,但門檻較高。

        這個介面的原理很簡單,對於一篇文件中,我們只需要提取出interestingTerm(即tf×idf高的詞),然後用lucene去搜索包含相同詞的文件,作為相似文件,這個方法的優點就是高效,但缺點就是不準確,這個介面提供很多引數,你可以配置來選擇interestingTerm。

MoreLikeThis mlt = new MoreLikeThis(ir);

Reader target = ...

// orig source of doc you want to find similarities to

Query query = mlt.like( target);

Hits hits = is.search(query);

       用法很簡單,這樣就可以得到,相似的文件

       這個介面比較靈活,你可以不直接用like介面,而是用

retrieveInterestingTerms(Reader r)

       這樣你可以獲得interestingTerm,然後怎麼處理就根據你自己的需要了。


相關推薦

lucene計算文字相似演算法

Leveraging term vectors         所謂term vector, 就是對於documents的某一field,如title,body這種文字型別的, 建立詞頻的多維向量空間.每一個詞就是一維, 這維的值就是這個詞在這個field中的頻率.    

DSSM演算法-計算文字相似

轉載請註明出處: http://blog.csdn.net/u013074302/article/details/76422551 導語 在NLP領域,語義相似度的計算一直是個難題:搜尋場景下query和Doc的語義相似度、feeds場景下Doc和Doc的語義相似度、機器翻譯場景下A句

python實現機器學習中的各種距離計算文字相似演算法

在自然語言處理以及機器學習的分類或者聚類中會涉及到很多距離的使用,各種距離的概念以及適用範圍請自行百度或者參考各種距離 import numpy as np import math # 依賴包numpy、python-Levenshtein、scipy

用gensim doc2vec計算文字相似,Python可以跑通的程式碼

Python3.7版本,轉載自:https://blog.csdn.net/juanjuan1314/article/details/75124046 wangyi_title.txt檔案下載地址:連結:https://pan.baidu.com/s/1uL75P13t98YHMqgv3Kx7T

計算文字相似方法大全-簡單說

本編文章是方法論-主要給大家介紹原理思路 簡單講解 基於關鍵詞的空間向量模型的演算法,將使用者的喜好以文件描述並轉換成向量模型,對商品也是這麼處理,然後再通過計算商品文件和使用者偏好文件的餘弦相似度。 文字相似度計算在資訊檢索、資料探勘、機器翻譯、文件複製檢測等領域

用gensim doc2vec計算文字相似

最近開始接觸gensim庫,之前訓練word2vec用Mikolov的c版本程式,看了很久才把程式看明白,在gensim庫中,word2vec和doc2vec只需要幾個介面就可以實現,實在是方便。python,我越來越愛你了。 這個程式很簡單,直接上程式了。 # codin

文字相似演算法

在向量空間模型中,文字泛指各種機器可讀的記錄。用D(Document)表示,特徵項(Term,用t表示)是指出現在文件D中且能夠代表該文件內容的基本語言單位,主要是由詞或者短語構成,文字可以用特徵項集表示為D(T1,T2,…,Tn),其中Tk是特徵項,1<=k<=

simhash計算文字相似

轉自http://www.lanceyan.com/tech/arch/simhash_hamming_distance_similarity.html 通過 採集系統 我們採集了大量文字資料,但是文字中有很多重複資料影響我們對於結果的分析。分析前我們需要對這些資料去除

幾種文字相似演算法的C++實現

1、最小編輯距離 namespace levenshtein { bool compare_char_(char c1, char c2) { return c1 == c2; } size_t ins_(char c) { return 1; } size_t d

計算文字相似-java實現

原始碼: Computeclass.java: /** * @author Caiyong * @version 1.0 * * */ package pack; import java.text.NumberFormat; import java.ut

解析TF-IDF演算法原理:關鍵詞提取,自動摘要,文字相似計算

Abstract:TF-IDF演算法是一種常用的詞頻統計方法,常被用於關鍵詞提取、文字摘要、文章相似度計算等。 TF-IDF的演算法思路 TF詞頻(Text Frequency):統計出現次數最多的詞 IDF逆文件頻率(Inverse Document Frequ

計算句子文字相似-編輯距離計算

本文轉載於:https://juejin.im/post/5b237b45f265da59a90c11d6 編輯距離,英文叫做 Edit Distance,又稱 Levenshtein 距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數,如果它們的距離越大,說明它們越是不同。

文字相似bm25演算法的原理以及Python實現(jupyter notebook)

今天我們一起來學習一下自然語言處理中的bm25演算法,bm25演算法是常見的用來計算query和文章相關度的相似度的。其實這個演算法的原理很簡單,就是將需要計算的query分詞成w1,w2,…,wn,然後求出每一個詞和文章的相關度,最後將這些相關度進行累加,最終就可以的得到文字相似度計算

nlp中文字相似計算問題

文章的目的:文字相似度計算一直是nlp中常見的問題,本文的目標是總結並對比文字相似度計算方法。當然文字的相似度計算會有進一步的應用,比如文字的分類、聚類等。 文章結構:本文先介紹最直接的字面距離相似度度量,而後介紹語義主題層面的度量,最後介紹目前一些新的相似度計算方法。 一、字面距

基於神經網路的文字相似計算【醫療大資料】

任務描述 問句匹配是自然語言處理的最基本任務之一,是自動問答,聊天機器人,資訊檢索,機器翻譯等各種自然語言處理任務基礎。問句匹配的主要目的是判斷兩個問句之間的語義是否等價。判別標準主要根據主句(即提問者)所蘊含的意圖來判斷兩個語句是否等價,而不直接判斷兩個語句是否表達相

Doc2Vec計算句子文件向量、求文字相似

注:本文主要是記錄自己常用的關於Doc2Vec的簡單程式程式碼。因此不做過多的解釋,直接寫出程式碼,如有問題可以討論交流。 一、doc2vec求文件向量 import sys import numpy as np import gensim from gensim.mod

Python 文字挖掘:使用gensim進行文字相似計算

index = similarities.MatrixSimilarity(corpus_tfidf)#把所有評論做成索引 sims = index[vec_tfidf]#利用索引計算每一條評論和商品描述之間的相似度 similarity = list(sims)#把相似度儲存成陣列,以便寫入txt 文件

word2vec詞向量訓練及中文文字相似計算

本文是講述如何使用word2vec的基礎教程,文章比較基礎,希望對你有所幫助!官網C語言下載地址:http://word2vec.googlecode.com/svn/trunk/官網Python下載地址:http://radimrehurek.com/gensim/mod

文字相似計算的幾個距離公式(歐氏距離、餘弦相似、Jaccard距離、編輯距離)

本文主要講一下文字相似度計算的幾個距離公式,主要包括:歐氏距離、餘弦相似度、Jaccard距離、編輯距離。 距離計算在文字很多場景下都可以用到,比如:聚類、K近鄰、機器學習中的特徵、文字相似度等等。接下來就一一介紹一下: 假設兩個文字X=(x1, x2, x3,...xn)

文字相似-bm25演算法原理及實現

原理BM25演算法,通常用來作搜尋相關性平分。一句話概況其主要思想:對Query進行語素解析,生成語素qi;然後,對於每個搜尋結果D,計算每個語素qi與D的相關性得分,最後,將qi相對於D的相關性得分進行加權求和,從而得到Query與D的相關性得分。BM25演算法的一般性公式如下:其中,Q表示Query,qi