今天開(kāi)源社區(qū)技術(shù)小伙伴問(wèn)到敏弃,如何判斷2個(gè)論文或者文章相似度。然后隨便了解了一下匠璧,記一下筆記
文章相似度對(duì)比屬于NLP(自然語(yǔ)言處理)入門(mén)基礎(chǔ)知識(shí)芽狗,涉及到的算法和思路如下
思路
1. 分詞
即將兩篇文章中涉及到的句子拆分為單詞或詞組
2. 清洗
將獲得的單詞狡蝶,詞組去掉停用詞 (停用詞比如符號(hào)庶橱,嗎,呀贪惹,的)等沒(méi)有意義的字或者詞
3. 計(jì)算權(quán)重
通過(guò)清洗完成后的詞苏章,計(jì)算詞在文章中出現(xiàn)的比重,即比重越高奏瞬,則表示該詞出現(xiàn)的頻率越高
4. 計(jì)算相似度
有了2遍文章各自詞的權(quán)重后枫绅,通過(guò)余弦相似度算法計(jì)算相似度
算法
涉及到的算法有如下
1. 分詞算法
分詞算法采用的是jieba分詞,將句子分為單詞
2. 計(jì)算權(quán)重
權(quán)重算法采用TF-IDF
TF-IDF是一種用于資訊檢索與文本挖掘的常用加權(quán)技術(shù)硼端,主要思想:如果一個(gè)單詞在該文章中出現(xiàn)的頻率(TF)高并淋,并且在其它文章中出現(xiàn)頻率很低,則認(rèn)為該單詞具有很好的區(qū)分能力珍昨,適合用來(lái)進(jìn)行分類(lèi)县耽。
詞頻(Term Frequency)表示單詞在該文章中出現(xiàn)的頻率。
詞頻(TF) = 單詞在該文章出現(xiàn)次數(shù)/當(dāng)前文章總單詞數(shù)
反問(wèn)檔頻率(Inverse Document Frequency)表示某一個(gè)特定單詞IDF可以由總文章數(shù)除以包含該單詞的文章數(shù)镣典,再將得到的商取對(duì)數(shù)得到兔毙。如果包含該單詞的文章越少,則IDF越大兄春,則表明該單詞具有很好的文章區(qū)分能力澎剥。
反問(wèn)檔頻率(IDF) = log(語(yǔ)料庫(kù)中文章總數(shù)/(包含該單詞的文章數(shù)+1))
在這里插入圖片描述
TF-IDF與一個(gè)詞在文檔中的出現(xiàn)次數(shù)成正比, 與包含該詞的文檔數(shù)成反比赶舆。
有了IDF的定義哑姚,我們就可以計(jì)算某一個(gè)詞語(yǔ)的TF-IDF值:
TF-IDF(x)=TF(x)*IDF(x),其中TF(x)指單詞x在當(dāng)前文章中的詞頻。
在這里插入圖片描述
TF-IDF算法的優(yōu)點(diǎn):簡(jiǎn)單快速芜茵,結(jié)果比較符合實(shí)際情況叙量。
TF-IDF算法的缺點(diǎn):?jiǎn)渭円?詞頻"衡量一個(gè)詞的重要性,不夠全面夕晓,有時(shí)重要的詞可能出現(xiàn)次數(shù)并不多宛乃。而且悠咱,這種算法無(wú)法體現(xiàn)詞的位置信息蒸辆,出現(xiàn)位置靠前的詞與出現(xiàn)位置靠后的詞征炼,都被視為重要性相同,這是不正確的躬贡。(一種解決方法是谆奥,對(duì)全文的第一段和每一段的第一句話(huà),給予較大的權(quán)重拂玻。)
TF-IDF的應(yīng)用場(chǎng)景:TF-IDF算法可用來(lái)提取文檔的關(guān)鍵詞酸些,關(guān)鍵詞在文本聚類(lèi)、文本分類(lèi)檐蚜、文獻(xiàn)檢索魄懂、自動(dòng)文摘等方面有著重要應(yīng)用。
2. 相似度算法
余弦相似性通過(guò)測(cè)量?jī)蓚€(gè)向量的夾角的余弦值來(lái)度量它們之間的相似性闯第。
相似性范圍從-1到1:
- -1意味著兩個(gè)向量指向的方向正好截然相反
- 1表示它們的指向是完全相同的
- 0通常表示它們之間是獨(dú)立的市栗,而在這之間的值則表示中間的相似性或相異性。
最常見(jiàn)的應(yīng)用就是計(jì)算文本相似度
測(cè)試代碼如下
# 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: # 以只讀方式打開(kāi)文件
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: # 分詞結(jié)果寫(xiě)入文件保存
f2.write(result)
f1.close()
f2.close()
cut(r"D:\python\test\nlp_test00.txt", r"D:\python\test\nlp_test0_0.txt") # 分別對(duì)文件調(diào)用cut方法分詞
cut(r"D:\python\test\nlp_test11.txt", r"D:\python\test\nlp_test1_1.txt")
# 將停用詞表從文件讀出咳短,并切分成一個(gè)數(shù)組備用
stopWords_dic = open(r'D:\python\test\chineseStopWords.txt', encoding='utf-8') # 從文件中讀入停用詞
stopWords_content = stopWords_dic.read()
stopWords_list = stopWords_content.splitlines() # 轉(zhuǎn)為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()
# 打印每類(lèi)文本的tf-idf詞語(yǔ)權(quán)重填帽,第一個(gè)for遍歷所有文本,第二個(gè)for便利某一類(lèi)文本下的詞語(yǔ)權(quán)重
for i in range(len(weight_list)):
print("-------第", i + 1, "段文本的詞語(yǔ)tf-idf權(quán)重------")
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個(gè)tf-idf詞語(yǔ)權(quán)重相似度
result= cosine_cal(weight_list[0],weight_list[1])
#相似度0到1之間
print(result)
chineseStopWords.txt 是停用詞文檔
nlp_test00.txt和nlp_test11.txt 分別是需要判刑的文章
運(yùn)行結(jié)果如圖 result 則是文本相似度