1. 程式人生 > >NLP文字相似度(TF-IDF)

NLP文字相似度(TF-IDF)

 我們在比較事物時,往往會用到“不同”,“一樣”,“相似”等詞語,這些詞語背後都涉及到一個動作——雙方的比較。只有通過比較才能得出結論,究竟是相同還是不同。但是萬物真的有這麼極端的區分嗎?在我看來不是的,生活中通過“相似度”這詞來描述可能會更加準確。比如男人和女人,雖然生理器官和可能思想有些不同,但也有相同的地方,那就是都是人,就是說相似度不為0;比如石頭與小草,它們對於虛擬類都是一種實體類,相似度也不為0;兩個句子詞和詞的順序都一致,相似度就是1。一個概念可以應用到不同於相同的兩個方面的定義。可真謂方便至極了。  

    

    在生活中,資訊檢索、文件複製檢測等領域都應用到“文字相似度”。可能有人覺得文字是文字,其實不盡然,文字相似度的應用更廣,除了文字的匹配,還可以是圖片,音訊等,因為他們的實質都是在計算機中都是以二進位制的方式存在的。

    

    相似度,實質就是計算個體間相程度。什麼是個體?對於語句,個體就是語句,對於圖片,個體就是圖片。

    

    先介紹最常用最簡單的方法:餘弦相似度。

    餘弦相似度就是通過一個向量空間中兩個向量夾角的餘弦值作為衡量兩個個體之間差異的大小。把1設為相同,0設為不同,那麼相似度的值就是在0~1之間,所有的事物的相似度範圍都應該是0~1,如果不是0~1的話,就不是我們應該研究的事了,那是神經學家和生物學家的事了。餘弦相似度的特點是餘弦值接近1,夾角趨於0,表明兩個向量越相似。看下圖,

                  技術分享圖片

    三角形越扁平,證明兩個個體間的距離越小,相似度越大;反之,相似度越小。但是,文字的相似度計算只是針對字面量來計算的,也就是說只是針對語句的字元是否相同,而不考慮它的語義,那是另外一個研究方向來著。比如,句子1:你真好看:。句子2:你真難看。這兩句話相似度75%,但是它們的語義相差十萬八千里,可以說是完全相反。又比如,句子1:真好吃。句子2:很美味。兩個句子相似度為0,但是語義在某個場景下是一致的。

    所以在實際中,沒有很完美的解決方案。每個公司會針對業務要求來調節相似度演算法,使其在某些場合能夠精確計算。

 

    計算兩個圖片的相似度,就是把圖片a,圖片b,對映為向量,然後通過這個公式來計算出相似度。在這裡,最最最重要的是“對映”這個過程,這個過程,如果在大資料的應用中,涉及到了對資料的分詞,去重,轉換,計算等步驟。

                                                                   技術分享圖片

                                          向量a和向量b是二維                                                                                                                                 拓展到n維的計算模型

 

    通過計算模型公式可以明確的求出餘弦相似度的值。那麼對於我們寫程式實現這個演算法,就是把兩個個體轉換為向量,然後通過這個公式求出最終解。

    比如向量a(x1, x2, x3, x4, x5),向量b(y1, y2, y3, y4, y5)。分子為(x1*y1)+(x2*y2)+(x3*y3)+(x4*y4)+(x5*y5),分母為sqrt(x1*x1+x2*x2+x3*x3+x4*x4+x5*x5)。

    下面通過實際例子來看如何由一個句子轉換為向量。

                                                                                    技術分享圖片

    由圖可知,兩個句子的相似度計算的步驟是:

    1.通過中文分詞,把完整的句子根據分詞演算法分為獨立的詞集合

    2.求出兩個詞集合的並集(詞包)

    3.計算各自詞集的詞頻並把詞頻向量化

    4.帶入向量計算模型就可以求出文字相似度

注意,詞包確定之後,詞的順序是不能修改的,不然會影響到向量的變化。

    以上是對兩個句子做相似度計算,如果是對兩篇文章做相似度計算,步驟如下:

    1.找出各自文章的關鍵詞併合成一個詞集合

    2.求出兩個詞集合的並集(詞包)

    3.計算各自詞集的詞頻並把詞頻向量化

    4.帶入向量計算模型就可以求出文字相似度

    句子的相似度計算只是文章相似度計算的一個子部分。文章的關鍵詞提取可以通過其他的演算法來實現,這裡先跳過,下一篇才介紹。

 

    到這裡出現一個關鍵的名詞——詞頻TF,詞頻是一個詞語在文章或句子中出現的次數。如果一個詞很重要,很明顯是應該在一個文章中出現很多次的,但是這也不是絕對的,比如“地”,“的”,“啊”等詞,它們出現的次數對一篇文章的中心思想沒有一點幫助,只是中文語法結構的一部分而已。這類詞也被稱為“停用詞”。所以,在計算一篇文章的詞頻時,停用詞是應該過濾掉的。

    但是僅僅過濾掉停用詞就能接近問題?也不一定的,比如如果想分析近期的十九屆中央紀委二次全會等新聞文章,很明顯出現“中國”這個詞語必定會出現在每篇文章,但是對於每個新聞的主幹思想有幫助嗎?對比“反腐反敗”,“人工智慧”“大資料”等詞語,“中國”這個詞語在文章中應該是次要的。

    因此進一步假設,如果某個詞比較少見(在我們準備的文章庫中的佔比比較少),但是它在這篇文章中多次出現,那麼它很可能反映了這篇文章的特性,正是我們所需要的關鍵詞。在此,在詞頻TF的基礎上又引出了反文件頻率IDF的概念。一般來說,在一篇文章或一個句子來說,對於每個詞都有不同的重要性,這也就是詞的權重。在詞頻的基礎上,賦予每一個詞的權重,進一步體現該詞的重要性。比如一篇報道中國農業養殖的新聞報道。最常見的詞(“的”、“是”、“在”)給予最小的權重,較常見的詞(“國內”、“中國”、“報道”)給予較小的權重,較少見的詞(“養殖”、“維基”)。所以刻畫能力強的詞語,權重應該是最高的。

    將TF和IDF進行相乘,就得到了一個詞的TF-IDF值,某個詞對文章重要性越高,該值越大,於是排在前面的幾個詞,就是這篇文章的關鍵詞。(在實際中,還要考慮詞的詞性等多維度的特性,動詞,名詞,形容詞的刻畫能力也是有所差別的;因社會熱點而詞的刻畫性爆發式提高(比如 打call))。

    下圖是詞頻的計算方法:

                                                                                            技術分享圖片

    詞頻標準化的目的是把所有的詞頻在同一維度上分析。詞頻的標準化有兩個標準,第一種情況,得出詞彙較小,不便於分析。一般情況下,第二個標準更適用,因為能夠使詞頻的值相對大點,便於分析。比如一本書出現一個詞語100次,但整本書10萬字,詞頻但是在一句話中出現5次,

    下面是反文件頻率的計算方法:

                            技術分享圖片

    針對這個公式,可能有人會有以下的疑問:

    1.為什麼+1?是為了處理分母為0的情況。假如所有的文章都不包含這個詞,分子就為0,所以+1是為了防止分母為0的情況。

    2.為什麼要用log函式?log函式是單調遞增,求log是為了歸一化,保證反文件頻率不會過大。

    3.會出現負數?肯定不會,分子肯定比分母大。

    

    TF-IDF = 計算的詞頻(TF)*計算的反文件頻率(IDF)。通過公式可以知道,TF-IDF與在該文件中出現的次數成正比,與包含該詞的文件數成反比。

 

    在知道TF-IDF後,先丟擲兩個小實踐:

1.利用TF-IDF計算相似文章:

    1)使用TF-IDF演算法,找出兩篇文章的關鍵詞

    2)每篇文章各取出若干個關鍵詞(比如20個),合併成一個集合,計算每篇文章對於這個集合中的詞的詞頻(為了避免文章長度的差異,可以使用相對詞頻)

    3)生成兩篇文章各自的詞頻向量

    4)計算兩個向量的餘弦相似度,值越大就表示越相似

    利用TF-IDF計算文章相似度,上面已經給出很詳細的流程了。這裡不再分析,下面來說說自動摘要技術。

    文章的資訊都包含在句子中,有些句子包含的資訊多,有些句子包含的資訊少。 "自動摘要"就是要找出那些包含資訊最多的句子。句子的資訊量用"關鍵詞"來衡量。如果包含的關鍵詞越多,就說明這個句子越重要。只要關鍵詞之間的距離小於“門檻值” ,它們就被認為處於同一個簇之中,如果兩個關鍵詞之間有5個以上的其他詞,就可以把這兩個關鍵詞分在兩個簇。下一步,對於每個簇,都計算它的重要性分值

                                                                                                             技術分享圖片

有時候,為了方便實際的操作可以化簡為不考慮簇的用法,

1)計算原始文字的詞頻,生成詞頻陣列 [(2, ‘你好‘), (10, ‘大資料‘), (4, ‘智慧‘), (100, ‘的‘)...]

2)過濾停用詞,得出新的詞頻陣列  [(2, ‘你好‘), (10, ‘大資料‘), (4, ‘智慧‘)...]

3)按照詞頻進行排序 [(2, ‘你好‘), (4, ‘智慧‘), (10, ‘大資料‘)...]

4)將文章分為句子

5)選擇關鍵詞首先出現的句子 (一般文章首段和最後一段,每段的首句和末句是比較重要的)

6)將選中的句子按照出現順序,組成摘要

 

   這樣做的優點是簡單快速,結果比較符合實際情況。缺點是單純以“詞頻”做衡量標準,不夠全面,詞性和詞的出現位置等因素沒有考慮到,而且有時重要的詞可能出現的次數並不多。這種演算法無法體現詞的位置資訊,出現位置靠前的詞與出現位置靠後的詞,都被視為重要性相同,這是不正確的。(一種解決方法是,對全文的第一段和每一段的第一句話,給予較大的權重。)