計算文檔與文檔的類似度

最近幫不少本科畢業生作文本數據分析,常常遇到的一個需求是計算文檔類似度。算法

思路:機器學習

  1. 抽取語料(全部文檔)中的詞語,構建詞典(詞語與數字對應起來)。ide

  2. 根據構建的詞典對每一個文檔進行從新編碼(將文檔轉化爲向量)。函數

  3. 使用餘弦計算類似度

下面的corpus是我在知乎live隨便找到的幾個評論,拿來當作測試的例子。好像數據不怎麼好玩,你們跟着一塊兒湊合湊合吧。學習

corpus = ['老師講的很好很全面乾貨不少',
        '講述的很好乾貨滿滿',
        '滿滿的乾貨很實用',
        '感謝老師無私的分享啦',
        '真水呵呵噠']

構建詞典-學習語料特徵
其實在機器學習裏,學習語料的全部詞語並將其轉化爲數字,這一步驟叫作特徵化。強烈推薦對數據科學感興趣的童鞋學學scikit-learn庫,人工智能我們小白可能還玩不轉,可是調用封裝好的機器學習算法,淺顯的玩玩機器學習仍是沒啥難度的。測試

在scikit-learn中,涉及到文本數據特徵化的類有sklearn.feature_extraction.text.CountVectorizer 和sklearn.feature_extraction.text.TfidfVectorizer 。咱們先以常見的詞頻統計做爲特徵抽取的方式開始探索,因爲scikit默認使用英文空格做爲分詞符號,因此處理中文數據前咱們要分詞並以空格間隔開來。編碼

from sklearn.feature_extraction.text import CountVectorizer
import jieba
corpus = [' '.join(jieba.lcut(doc))
          for doc in corpus]corpus
['老師 講 的 很 好 很 全面 乾貨 不少',
 '講述 的 很 好 乾貨 滿滿',
 '滿滿的 乾貨 很 實用',
 '感謝 老師 無私 的 分享 啦',
 '真水 呵呵 噠']
wordcounter = CountVectorizer()

#學習特徵(構建詞典)fit  並轉化爲特徵矩陣。
matrix=wordcounter.fit_transform(corpus)
print(matrix.toarray())

#查看下特徵與詞語對應關係
print(wordcounter.get_feature_names())
[[1 0 0 0 1 1 0 0 0 0 0 1 0]
 [0 0 0 0 1 0 0 0 1 0 0 0 1]
 [0 0 0 1 1 0 0 0 0 1 0 0 0]
 [0 1 0 0 0 0 1 1 0 0 0 1 0]
 [0 0 1 0 0 0 0 0 0 0 1 0 0]]
['全面', '分享', '呵呵', '實用', '乾貨', 
'不少', '感謝', '無私', '滿滿', '滿滿的', 
'真水', '老師', '講述']

計算類似度
這裏使用scikit提供的cosine-similarity函數。人工智能

from sklearn.metrics.pairwise import cosine_similarity

cosine_similarity(matrix)
array([[1.        , 0.28867513, 0.28867513, 0.25      , 0.        ],
       [0.28867513, 1.        , 0.33333333, 0.        , 0.        ],
       [0.28867513, 0.33333333, 1.        , 0.        , 0.        ],
       [0.25      , 0.        , 0.        , 1.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 1.        ]])
咱們看到這個矩陣是沿着對角線對稱的,因此咱們只須要看第一行。

第一個評論與第一個評論之間的類似度爲1
第一個評論與第二個評論的類似度爲0.28867513
第一個評論與第三個評論的類似度爲0.28867513
第一個評論與第四個評論的類似度爲0.25
第一個評論與第四個評論的類似度爲0

高中數學知識cos類似性計算公式
本覺得本身對這裏很熟悉,結果本身寫cos計算公式時竟然出錯了。粘貼到這裏,幫助你們回憶高中知識。(a和b是向量)code

計算文檔與文檔的類似度

#cos類似性計算orm

def cosVector(x,y):
    result1=0.0
    result2=0.0
    result3=0.0
    for i in range(len(x)):
        result1 +=x[i]*y[i]   #sum(a*b)
        result2 +=x[i]**2     #sum(a*a)
        result3 +=y[i]**2     #sum(b*b)

    return str(result1/((result2*result3)**0.5))
vect1 = [1,0,1]
vect2 = [0,1,0]
vect3 = [1,1,1]

print("vect1與vect2類似度爲:", cosVector(vect1, vect2))
print("vect1與vect3類似度爲:", cosVector(vect1, vect3))
print("vect2與vect3類似度爲:", cosVector(vect2, vect3))
vect1與vect2類似度爲: 0.0
vect1與vect3類似度爲: 0.8164965809277261
vect2與vect3類似度爲: 0.5773502691896258
相關文章
相關標籤/搜索