句子相似度及R語言實現
本次不講原理,單純用R語言計算句子相似度。
方式一:機械相似性
兩個文字內容上的相關程度,比如“你好嗎”和“你好”的相似性,純粹代表著內容上字元是否完全共現。——基於Jaccard相似係數計算句子相似度
Jaccard 係數指:句子A的分詞詞語與句子B的分詞詞語交集的大小與句子A的分詞詞語與句子B的分詞詞語並集的大小的比值。有點拗口,其實就是兩個句子的分詞詞語的交集比並集。
【圖片來源:百度百科】
R語言:基於textreuse包: 由於 資料保密 性 ,所以部分內容打碼了。
程式碼解析:tokenize_words()是一個分詞的函式。
jaccard_similarity()計算兩組詞語的相似度。從相似度結果上看,x與y都是談論到母親生病住院,z也講到住院,但並不是母親生病住院。且x與z、y與z的相似度不應該是相等的,應該是y與z的相似度要高於x與z的相似度,因為x的重點有兩個,一是母親生病住院,二是情緒低落,y的重點僅是母親住院,z也是與住院有關,但不是母親住院。所以xz、yz兩者的相似值間會很近,但我認為y與z的相似度應該高一點 (個人觀點)。
library(textreuse)#比較文字相似度dir "C:/Users/yuan/Documents/test" #基於tm包建立語料庫corpus"Civil procedure"),tokenizer=tokenize_ngrams, n=comparisons#將該矩陣轉換成對的資料幀pairwise_candidates(comparisons)#比較句子相似度x "句子1"))y "句子2"))z "句子3"))jaccard_similarity(x , y) ##相似程度jaccard_similarity(x , z) jaccard_similarity(y , z)
補充:進行文字相似度計算時,保證文本里面要大於兩行,否則會報錯的。 (我也不清楚為什麼)若想比較句子或詞語差異性可採用jaccard_dissimilarity函式。若想比較文章間相似度,最好是將檔案儲存為同一型別, 不要一個txt檔案 ,一個 word檔案或其他檔案。
方式二:基於詞向量餘弦值相似度
基於word2vec模型訓練詞向量,再計算句子餘弦值作為句子相似度。當然,如果僅是為了學習的可以直接使用別人訓練好的詞向量,若用於某領域的,可以找找該方向的詞向量,或者自己訓練吧!word2vec有兩種模型。CBOW (Continuous Bag-Of-Words,即連續的詞袋模型)和Skip-Gram。通過word2vec訓練詞向量,可以把對文字內容的處理簡化為K維向量空間中的向量運算,再基於向量空間上的相似度可以用來表示文字語義上的相似度。同時,對於word2vec訓練出來的詞向量也可以用來做其他的分析,比如:聚類、近似詞等。由於不講原理,所以想了解word2vec實現原理的自行去百度瞭解。
前面也說了資料保密性,所以就不展示資料結構了。大概講一下我的資料!存在ecxel表中,每一行就是一個句子。
#釋放記憶體rm(list = ls())gc()#載入所需的元件包library(readxl) #匯入資料library(jiebaR) #分詞library(tmcn.word2vec) #word2vec模型library(wordVectors) #word2vec模型:與tmcn.word2vec一樣的,功能上比其多一點。library(dplyr) #管道操作#讀取資料yq_datas #將句子轉為因子形式。docs as.character(sapply(yq_datas$`YQMS(獄情描述)`, str_replace_all, #啟動分詞器,進行分詞wk vector #worker啟動器引數說明#type:預設使用混合法的返回型別:mix(混合模型),mp(最大概率),hmm(隱式馬科夫模型),query(索引),tag(詞性標註),simhash(距離:求相似),keywords(關鍵詞);#dict:指定主詞典的路徑(使用預設,在jiebaRD包中dict檔案的jieba.dict.utf8檔案);#hmm:指定隱馬爾科夫模式的路徑(使用預設即可,也同目錄下的hmm_model.utf8檔案);#user:可以路徑的方式自定義屬於使用者自己的字典(可以自己指定路徑,也可以修改同目錄下的user.dict.utf8檔案);#idf:指定逆文件頻次的路徑(同目錄下idf.utf8檔案,一般是用於計算相似度和關鍵詞的);#stop_word:指定停止詞的路徑(也可以自己指定路徑,也可以修改同目錄下的stop_words.utf8檔案(用了很多次感覺該檔案時好時壞的,建議自己指定吧!));#topn:指定提取文件關鍵詞的個數;#encoding:指定輸入檔案的編碼;#lines:指定最大的讀取行數(檔案太大了可以根據這個分段進行分詞);#bylines:是否按行分詞,就是按行返回結果;其他的引數可以參考worker函式。#儲存分詞資料:將列表轉向量匯入檔案,再進行匯入空值進行換行,再繼續第二輪操作。con "C:/Users/yuan/Documents/R/win-library/3.6/tmcn.word2vec/examples/new_vector.txt",open=for(i in 1:length(vector)){ vect % unlist() write.table(vect,file = con,quote = FALSE,eol = " ",row.names = FALSE,col.names = FALSE) nul "" write.table(nul,file = con,quote = FALSE,eol = "\n",row.names = FALSE,col.names = FALSE)}close(con)#基於word2vec模型訓練詞向量化model = train_word2vec(system.file("examples", "new_vector.txt", package = "tmcn.word2vec"),vectors = 500,min_count = 2)model[["醫院"]]#train_word2vec函式引數說明:#train_file:已經分好詞的txt檔案路徑(詞語之間由空格隔開),是一個訓練資料檔案。#output_file:word2vec模型訓練好的詞向量儲存檔案地址。#vectors:輸出的向量維數,預設是100個,也可以設定大一點,太大了記憶體消耗大,處理速率低。#threads:訓練模型用的執行緒數,預設是1,也可以通過parallel包的detectCores()函式檢視當前電腦可用核數,然後選擇跑幾個執行緒。#classes:對詞語聚類的個數,預設是0,採用K均值進行聚類。#window:表示當前詞與預測詞在一個句子中的最大距離是多少。#cbow :word2vec訓練模型選擇,1是CBOW加層次的網路結構(連續詞袋模型),0(預設)是Skip-gram模型,具體是如何實現的可以檢視相關資料。#min_count:可以對字典做截斷,把詞頻少於min_count次數的詞語丟棄, 預設值為5。#iter:迭代次數,預設為5。#force:是不是要覆蓋原有的模型。其他引數檢視word2vec函式#計算句子相似度vector_similarity function(x,y){ wk_vec #啟動分詞器 sentence_vector function(vec) #查詢對應詞的詞向量,不存在的詞設其值為0{ words #對傳入的形參分詞 sum_word_vec 0 for(i in 1:length(words)) #計算句子總詞向量 { word if(word %in% row.names(model)) word_vecelse word_vec 0 sum_word_vec } sum_word_vec #計算句子均值詞向量 return(sum_word_vec) } vecx vecy #cos cos return(cos)}vector_similarity(x,y)vector_similarity(x,z)vector_similarity(y,z)
其結果和我設想是一致的,y與z的相似度要大於x與z的相似度。步驟:1、匯入資料;2、使用jiebaR包分詞(採用預設引數),需要注意設定引數:bylines = T,否則它不會按行返回結果;3、將分詞儲存後傳給word2vec模型訓練詞向量;4、基於詞向量計算句子的總詞向量;5、計算兩組句子總詞向量的餘弦值作為句子的相似度。
注:
1、關於分詞後的list結構資料儲存到txt檔案的方法:1:開啟txt檔案;2、將列表的第一個元素轉為向量形式;3、將向量形式的分詞寫入檔案中,再寫入換行符;4、再將列表的第二個元素轉為向量寫入檔案,以此類推;5、關閉檔案。如果你們有什麼好的方法或者函式可以告訴一下我。
2、train_word2vec函式訓練詞向量,輸入檔案必須是放在tmcn.word2vec包中的examples資料夾,放在其他位置都無法讀取到,不清楚是電腦攔截了,還是其他的原因。若知道原因的,可以告訴我,非常感謝!
3、全部函式基本都是使用預設引數,後期優化可以從引數入手了,詞語權重等等,最後本人不擅長自然語言處理方向的分析,若在分析過程中有錯誤的歡迎指正!
————————————————
版權宣告:本文為CSDN博主「weixin_39860919」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/weixin_39860919/article/details/112413273