Python中通用的文本相似度計(jì)算方法詳解
一、最長公共子序列
最長公共子序列(Longest Common Subsequence,LCS)是指兩個或多個序列中共同出現(xiàn)的一段連續(xù)序列,它在多個序列中都保持相同的順序和連續(xù)性。在計(jì)算機(jī)科學(xué)中,尋找最長公共子序列是一個經(jīng)典問題,通常通過動態(tài)規(guī)劃算法解決。
動態(tài)規(guī)劃算法解決最長公共子序列問題的步驟如下:
初始化狀態(tài)數(shù)組:創(chuàng)建一個二維數(shù)組dp,其大小為(m+1)×(n+1),其中m和n分別是兩個序列的長度。dp[i][j]表示序列1的前i個字符與序列2的前j個字符的最長公共子序列的長度。
填充狀態(tài)數(shù)組:遍歷兩個序列,對于每一對字符,如果它們相同,則dp[i][j] = dp[i-1][j-1] + 1;如果不同,則dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
找到最長公共子序列:dp數(shù)組的最后一個元素dp[m][n]就是兩個序列的最長公共子序列的長度??梢酝ㄟ^回溯的方式找到具體的子序列。
python代碼如下:
## 最長公共子序列計(jì)算最長公共子串------------------- def LCS(str_a, str_b): if len(str_a) == 0 or len(str_b) == 0: return 0 dp = [0 for _ in range(len(str_b) + 1)] for i in range(1, len(str_a) + 1): left_up = 0 dp[0] = 0 for j in range(1, len(str_b) + 1): left = dp[j-1] up = dp[j] if str_a[i-1] == str_b[j-1]: dp[j] = left_up + 1 else: dp[j] = max([left, up]) left_up = up return dp[len(str_b)] #轉(zhuǎn)換最長公共子序列為0-1之間的數(shù)值,結(jié)果越接近1,相似度越大 def LCS_Score(str_a, str_b): return np.round(LCS(str_a, str_b)*2/(len(str_a)+len(str_b)),2) #LCS_Score(str_a, str_b) ## 對dataframe的2列按照最長公共子序列計(jì)算相似度 ## df: 數(shù)據(jù)來源變量 ## col_name1、col_name2:用于計(jì)算相似度的2個列名 ## simarity_score_name: 返回的相似度結(jié)果的列名 ## 返回?cái)?shù)據(jù)框,則simarity_score_name是用該計(jì)算方法對2列文本相似度的計(jì)算結(jié)果 def df_simarity_lcs(df , col_name1 , col_name2 , simarity_score_name): df[simarity_score_name] = list(map(lambda str_a, str_b:LCS_Score(str_a, str_b),df[col_name1],df[col_name2])) return df
二、Jaccard相似度(Jaccard Similarity)
基于集合的交集與并集的比值來計(jì)算相似度。
適用于短文本或關(guān)鍵詞列表的比較。
## 采用集合的方法計(jì)算2個集合的相似度 def similarity(a, b): try: return len(a & b) / len(a | b) except ZeroDivisionError: return -1e-4 ## 采用集合的方法計(jì)算一個數(shù)據(jù)框中2個列的文本相似度 ## df: 數(shù)據(jù)來源變量 ## col_name1、col_name2:用于計(jì)算相似度的2個列名 ## simarity_score_name: 返回的相似度結(jié)果的列名 ## 返回?cái)?shù)據(jù)框,則simarity_score_name是用該計(jì)算方法對2列文本相似度的計(jì)算結(jié)果 #對dataframe的2列按照集合的方法計(jì)算相似度 def df_simarity_jh(df , col_name1 , col_name2 , simarity_score_name): df[simarity_score_name] = list(map(lambda str_a, str_b:similarity(set(str_a), set(str_b)),df[col_name1],df[col_name2])) return df
三、余弦相似度(Cosine Similarity)
通過計(jì)算兩個文本向量在空間中的夾角余弦值來評估它們的相似度。
通常與詞袋模型(BOW)或TF-IDF結(jié)合使用。
## vec1, vec2:待計(jì)算的向量 ## 返回2個向量的相似度 def cosine_simi(vec1, vec2): from scipy import spatial return 1 - spatial.distance.cosine(vec1, vec2) ## 對dataframe的2列按照最長公共子序列計(jì)算相似度 ## df: 數(shù)據(jù)來源變量 ## col_name1、col_name2:用于計(jì)算相似度的2個列名 ## simarity_score_name: 返回的相似度結(jié)果的列名 ## 返回?cái)?shù)據(jù)框,則simarity_score_name是用該計(jì)算方法對2列文本相似度的計(jì)算結(jié)果 def df_simarity_cosine(df , col_name1 , col_name2 , simarity_score_name): df[simarity_score_name] = list(map(lambda str_a, str_b:cosine_simi(str_a, str_b),df[col_name1],df[col_name2])) return df
四、方法補(bǔ)充
除了上文的方法,小編還為大家整理了一些其他Python文件相似度計(jì)算的方法,希望對大家有所幫助
TF-IDF
TF-IDF是一種統(tǒng)計(jì)方法,用于評估單詞在文檔集中的重要性。它可以將文本表示為向量,進(jìn)而計(jì)算余弦相似度。
from sklearn.feature_extraction.text import TfidfVectorizer def calculate_tfidf_cosine_similarity(text1, text2): vectorizer = TfidfVectorizer() corpus = [text1, text2] vectors = vectorizer.fit_transform(corpus) similarity = cosine_similarity(vectors) return similarity[0][1] text1 = "I love Python programming" text2 = "Python programming is great" tfidf_cosine_similarity = calculate_tfidf_cosine_similarity(text1, text2) print(tfidf_cosine_similarity)
Word2Vec
Word2Vec是一種將單詞表示為向量的模型,可以捕捉單詞之間的語義關(guān)系。使用預(yù)訓(xùn)練的詞向量模型,可以計(jì)算文本之間的相似度。
import gensim.downloader as api from gensim import matutils import numpy as np def calculate_word2vec_similarity(text1, text2): model = api.load("word2vec-google-news-300") tokens1 = text1.split() tokens2 = text2.split() vec1 = np.mean([model[token] for token in tokens1 if token in model], axis=0) vec2 = np.mean([model[token] for token in tokens2 if token in model], axis=0) return matutils.cosine(vec1, vec2) text1 = "I love Python programming" text2 = "Python programming is great" word2vec_similarity = calculate_word2vec_similarity(text1, text2) print(word2vec_similarity)
Doc2Vec
Doc2Vec是一種將文檔表示為向量的模型,可以捕捉文檔之間的語義關(guān)系。與Word2Vec類似,可以使用預(yù)訓(xùn)練的Doc2Vec模型計(jì)算文本之間的相似度。
from gensim.models import Doc2Vec from gensim.models.doc2vec import TaggedDocument def calculate_doc2vec_similarity(text1, text2): corpus = [TaggedDocument(text1.split(), ["text1"]), TaggedDocument(text2.split(), ["text2"])] model = Doc2Vec(corpus, vector_size=100, window=5, min_count=1, workers=4) vec1 = model.docvecs["text1"] vec2 = model.docvecs["text2"] return matutils.cosine(vec1, vec2) text1 = "I love Python programming" text2 = "Python programming is great" doc2vec_similarity = calculate_doc2vec_similarity(text1, text2) print(doc2vec_similarity)
這些方法可以根據(jù)具體需求進(jìn)行選擇和組合,為自然語言處理任務(wù)提供強(qiáng)大的文本相似度計(jì)算能力。在實(shí)際應(yīng)用中,可能會遇到多種場景,例如推薦系統(tǒng)、自動問答和文本聚類等。在這些場景中,選擇合適的文本相似度計(jì)算方法至關(guān)重要。
BERT
BERT(Bidirectional Encoder Representations from Transformers)是一種基于Transformer的預(yù)訓(xùn)練模型,用于捕捉上下文相關(guān)的單詞表示??梢酝ㄟ^BERT模型將文本表示為向量,然后計(jì)算余弦相似度。
from sentence_transformers import SentenceTransformer def calculate_bert_similarity(text1, text2): model = SentenceTransformer("bert-base-nli-mean-tokens") embeddings = model.encode([text1, text2]) similarity = cosine_similarity(embeddings) return similarity[0][1] text1 = "I love Python programming" text2 = "Python programming is great" bert_similarity = calculate_bert_similarity(text1, text2) print(bert_similarity)
到此這篇關(guān)于Python中通用的文本相似度計(jì)算方法詳解的文章就介紹到這了,更多相關(guān)Python文本相似度計(jì)算內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python監(jiān)控windows服務(wù)器的進(jìn)程和服務(wù)
這篇文章主要為大家詳細(xì)介紹了如何使用python監(jiān)控windows服務(wù)器的進(jìn)程和服務(wù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04動感網(wǎng)頁相冊 python編寫簡單文件夾內(nèi)圖片瀏覽工具
這篇文章主要為大家詳細(xì)介紹了動感網(wǎng)頁相冊的制作方法,即利用python編寫簡單文件夾內(nèi)圖片瀏覽工具,感興趣的小伙伴們可以參考一下2016-08-08Python如何將JavaScript轉(zhuǎn)換為json
文章介紹了如何使用Python的re模塊將JavaScript代碼轉(zhuǎn)換為JSON格式,首先,使用正則表達(dá)式匹配并替換JavaScript代碼中的數(shù)字,確保它們被雙引號括起來,然后,使用另一個正則表達(dá)式匹配并替換JavaScript代碼中的鍵值對,確保鍵和值都被雙引號括起來2025-02-02用Python進(jìn)行柵格數(shù)據(jù)的分區(qū)統(tǒng)計(jì)和批量提取
該教程其實(shí)源于web,我看到之后覺得很實(shí)用,于是自己又重復(fù)做了一遍,寫了詳細(xì)的注釋分享給大家,希望對大家的研究有幫助,本文講述了柵格的分區(qū)統(tǒng)計(jì),批量提取,深化理解遍歷循環(huán)等內(nèi)容2021-05-05Python中數(shù)據(jù)類轉(zhuǎn)換為JSON的方法詳解
這篇文章主要介紹了Python中數(shù)據(jù)類轉(zhuǎn)換為JSON的方法詳解的相關(guān)資料,需要的朋友可以參考下2023-09-09