今天開源社區(qū)技術小伙伴問到,如何判斷2個論文或者文章相似度。然后隨便了解了一下,記一下筆記
文章相似度對比屬于NLP(自然語言處理)入門基礎知識,涉及到的算法和思路如下
思路
1. 分詞
即將兩篇文章中涉及到的句子拆分為單詞或詞組
2. 清洗
將獲得的單詞,詞組去掉停用詞 (停用詞比如符號,嗎,呀,的)等沒有意義的字或者詞
3. 計算權重
通過清洗完成后的詞,計算詞在文章中出現(xiàn)的比重,即比重越高,則表示該詞出現(xiàn)的頻率越高
4. 計算相似度
有了2遍文章各自詞的權重后,通過余弦相似度算法計算相似度
算法
涉及到的算法有如下
1. 分詞算法
分詞算法采用的是jieba分詞,將句子分為單詞
2. 計算權重
權重算法采用TF-IDF
TF-IDF是一種用于資訊檢索與文本挖掘的常用加權技術,主要思想:如果一個單詞在該文章中出現(xiàn)的頻率(TF)高,并且在其它文章中出現(xiàn)頻率很低,則認為該單詞具有很好的區(qū)分能力,適合用來進行分類。
詞頻(Term Frequency)表示單詞在該文章中出現(xiàn)的頻率。
詞頻(TF) = 單詞在該文章出現(xiàn)次數(shù)/當前文章總單詞數(shù)

反問檔頻率(Inverse Document Frequency)表示某一個特定單詞IDF可以由總文章數(shù)除以包含該單詞的文章數(shù),再將得到的商取對數(shù)得到。如果包含該單詞的文章越少,則IDF越大,則表明該單詞具有很好的文章區(qū)分能力。
反問檔頻率(IDF) = log(語料庫中文章總數(shù)/(包含該單詞的文章數(shù)+1))
在這里插入圖片描述

TF-IDF與一個詞在文檔中的出現(xiàn)次數(shù)成正比, 與包含該詞的文檔數(shù)成反比。
有了IDF的定義,我們就可以計算某一個詞語的TF-IDF值:
TF-IDF(x)=TF(x)*IDF(x),其中TF(x)指單詞x在當前文章中的詞頻。
在這里插入圖片描述

TF-IDF算法的優(yōu)點:簡單快速,結果比較符合實際情況。
TF-IDF算法的缺點:單純以"詞頻"衡量一個詞的重要性,不夠全面,有時重要的詞可能出現(xiàn)次數(shù)并不多。而且,這種算法無法體現(xiàn)詞的位置信息,出現(xiàn)位置靠前的詞與出現(xiàn)位置靠后的詞,都被視為重要性相同,這是不正確的。(一種解決方法是,對全文的第一段和每一段的第一句話,給予較大的權重。)
TF-IDF的應用場景:TF-IDF算法可用來提取文檔的關鍵詞,關鍵詞在文本聚類、文本分類、文獻檢索、自動文摘等方面有著重要應用。
2. 相似度算法
余弦相似性通過測量兩個向量的夾角的余弦值來度量它們之間的相似性。
相似性范圍從-1到1:
- -1意味著兩個向量指向的方向正好截然相反
- 1表示它們的指向是完全相同的
- 0通常表示它們之間是獨立的,而在這之間的值則表示中間的相似性或相異性。
最常見的應用就是計算文本相似度
測試代碼如下
# encoding=utf-8
import jieba
from scipy import spatial
from sklearn.feature_extraction.text import TfidfVectorizer
def cut(txt_name1, txt_name2):
with open(txt_name1, encoding = 'utf-8') as f1: # 以只讀方式打開文件
txt = f1.read()
txt_encode = txt.encode('utf-8')
txt_cut = jieba.cut(txt_encode) # 切詞
result = ' '.join(txt_cut)
# print(result)
with open(txt_name2, "w",encoding="utf-8") as f2: # 分詞結果寫入文件保存
f2.write(result)
f1.close()
f2.close()
cut(r"D:\python\test\nlp_test00.txt", r"D:\python\test\nlp_test0_0.txt") # 分別對文件調用cut方法分詞
cut(r"D:\python\test\nlp_test11.txt", r"D:\python\test\nlp_test1_1.txt")
# 將停用詞表從文件讀出,并切分成一個數(shù)組備用
stopWords_dic = open(r'D:\python\test\chineseStopWords.txt', encoding='utf-8') # 從文件中讀入停用詞
stopWords_content = stopWords_dic.read()
stopWords_list = stopWords_content.splitlines() # 轉為list備用
stopWords_dic.close()
with open(r"D:\python\test\nlp_test0_0.txt", encoding='utf-8') as f3:
res3 = f3.read()
with open(r"D:\python\test\nlp_test1_1.txt", encoding='utf-8') as f4:
res4 = f4.read()
corpus = [res3, res4]
# print(corpus)
vector = TfidfVectorizer(stop_words=stopWords_list)
tf_idf = vector.fit_transform(corpus)
# print(tf_idf)
word_list = vector.get_feature_names_out() # 獲取詞袋模型的所有詞
weight_list = tf_idf.toarray()
# 打印每類文本的tf-idf詞語權重,第一個for遍歷所有文本,第二個for便利某一類文本下的詞語權重
for i in range(len(weight_list)):
print("-------第", i + 1, "段文本的詞語tf-idf權重------")
for j in range(len(word_list)):
print(word_list[j], weight_list[i][j])
# 采用余弦相似度算法
def cosine_cal(v1, v2):
cos_sim = 1 - spatial.distance.cosine(v1, v2)
return cos_sim
## 判斷2個tf-idf詞語權重相似度
result= cosine_cal(weight_list[0],weight_list[1])
#相似度0到1之間
print(result)
chineseStopWords.txt 是停用詞文檔
nlp_test00.txt和nlp_test11.txt 分別是需要判刑的文章
運行結果如圖 result 則是文本相似度
