Python根據(jù)字符串語義相似度計算的多種實現(xiàn)算法
以下是幾種基于語義的字符串相似度計算方法,每種方法都會返回0.0到1.0之間的相似度分數(shù)(保留一位小數(shù))。
方法1:計算 Levenshtein 距離 (基于字符的相似度)
如果需要基于字符的相似度而非語義,可以使用 Levenshtein 距離。
先安裝模塊:
pip install Levenshtein
案例代碼:
import Levenshtein
def levenshtein_similarity(text1, text2):
# 計算 Levenshtein 距離
distance = Levenshtein.distance(text1, text2)
# 計算相似度并保留一位小數(shù)
max_len = max(len(text1), len(text2))
similarity = round(1 - (distance / max_len), 1) if max_len > 0 else 1.0
return similarity
# 示例用法
text1 = "kitten"
text2 = "sitting"
print(levenshtein_similarity(text1, text2)) # 輸出為 0.5
方法2:使用Sentence-BERT預(yù)訓(xùn)練模型
Sentence Transformers 可以將文本轉(zhuǎn)換為語義向量,然后通過余弦相似度計算文本之間的相似度。
使用Sentence-BERT模型計算語義相似度,需要先安裝:
pip install sentence-transformers
案例代碼:
from sentence_transformers import SentenceTransformer, util
import numpy as np
def semantic_similarity_sbert(str1, str2):
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
# 編碼句子
embeddings = model.encode([str1, str2])
# 計算余弦相似度
cosine_score = util.cos_sim(embeddings[0], embeddings[1])
# 轉(zhuǎn)換為0-1范圍并保留一位小數(shù)
similarity = float(np.clip(cosine_score.item(), 0.0, 1.0))
return round(similarity, 1)
# 示例
print(semantic_similarity_sbert("我喜歡吃蘋果", "我愛吃水果")) # 輸出類似: 0.8
方法3:使用spaCy進行語義相似度比較
spaCy 是一個強大的自然語言處理庫,可以通過預(yù)訓(xùn)練模型來計算兩個文本的語義相似度。
需要先安裝:
pip install spacy
英語模型,需要先安裝:
python -m spacy download en_core_web_md
中文模型:
python -m spacy download zh_core_web_lg
案例代碼:
import spacy
def spacy_similarity(text1, text2):
# 加載模型
nlp = spacy.load('zh_core_web_lg')
doc1 = nlp(text1)
doc2 = nlp(text2)
# 計算語義相似度并保留一位小數(shù)
similarity = round(doc1.similarity(doc2), 1)
return similarity
# 示例用法
text1 = "The cat sits on the mat."
text2 = "A cat is resting on a mat."
print(spacy_similarity(text1, text2)) # 輸出可能為 0.8
方法4:使用spaCy和詞向量
使用 Word Mover’s Distance (WMD),WMD 是一種基于詞向量的距離度量,可以用來計算文本之間的語義差異,通過轉(zhuǎn)換為相似度。
import spacy
import numpy as np
def semantic_similarity_spacy(str1, str2):
"""
使用spaCy的詞向量計算語義相似度
"""
nlp = spacy.load("zh_core_web_lg")
doc1 = nlp(str1)
doc2 = nlp(str2)
# 計算余弦相似度
similarity = doc1.similarity(doc2)
# 確保在0-1范圍內(nèi)并保留一位小數(shù)
return round(max(0.0, min(1.0, similarity)), 1)
# 示例
print(semantic_similarity_spacy("今天天氣很好", "明天的天氣不錯")) # 輸出類似: 0.7
方法5:使用Universal Sentence Encoder (USE)
使用Google的Universal Sentence Encoder需要先安裝:
pip install tensorflow-hub tensorflow-text
注意: 首次使用需要下載模型(約900MB)
import tensorflow_hub as hub
import tensorflow_text as text # 必須導(dǎo)入
import numpy as np
def semantic_similarity_use(str1, str2):
"""
"""
module = hub.load("https://tfhub.dev/google/universal-sentence-encoder-multilingual/3")
# 編碼句子
embeddings = module([str1, str2])
# 計算余弦相似度
similarity = np.inner(embeddings[0], embeddings[1]) / (
np.linalg.norm(embeddings[0]) * np.linalg.norm(embeddings[1])
)
# 確保在0-1范圍內(nèi)并保留一位小數(shù)
return round(max(0.0, min(1.0, similarity)), 1)
# 示例
print(semantic_similarity_use("這只貓很可愛", "那只貓咪非常漂亮")) # 輸出類似: 0.8
方法6:使用BERT-as-Service
使用BERT-as-Service計算語義相似度
需要先安裝:
pip install bert-serving-server bert-serving-client
并下載預(yù)訓(xùn)練模型運行服務(wù)端
from bert_serving.client import BertClient
import numpy as np
def semantic_similarity_bert(str1, str2):
"""
"""
bc = BertClient()
# 編碼句子
embeddings = bc.encode([str1, str2])
# 計算余弦相似度
similarity = np.dot(embeddings[0], embeddings[1]) / (
np.linalg.norm(embeddings[0]) * np.linalg.norm(embeddings[1])
)
# 確保在0-1范圍內(nèi)并保留一位小數(shù)
return round(max(0.0, min(1.0, similarity)), 1)
# 示例
# print(semantic_similarity_bert("他正在跑步", "他在運動")) # 輸出類似: 0.9
方法7:使用TF-IDF和余弦相似度(基于詞頻統(tǒng)計)
這是一種基于詞頻的相似度計算方法。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
def semantic_similarity_tfidf(str1, str2):
"""
使用TF-IDF和余弦相似度計算文本相似度
基于詞頻統(tǒng)計,不是真正的語義相似度,但可以作為基線方法
"""
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform([str1, str2])
# 計算余弦相似度
similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
# 確保在0-1范圍內(nèi)并保留一位小數(shù)
return round(max(0.0, min(1.0, similarity)), 1)
# 示例
print(semantic_similarity_tfidf("深度學(xué)習(xí)", "神經(jīng)網(wǎng)絡(luò)")) # 輸出類似: 0.6
方法8:博主自創(chuàng)算法
結(jié)巴分詞、TF-IDF的余弦相似度、標準化編輯距離相似度:
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import Levenshtein
class SemanticSimilarity:
def __init__(self):
self.vectorizer = TfidfVectorizer()
def tokenize(self, text):
"""中文分詞處理"""
return ' '.join(jieba.lcut(text))
def tfidf_cosine(self, str1, str2):
"""基于TF-IDF的余弦相似度(0-1)"""
corpus = [self.tokenize(str1), self.tokenize(str2)]
tfidf = self.vectorizer.fit_transform(corpus)
return max(0.0, min(1.0, cosine_similarity(tfidf[0], tfidf[1])[0][0]))
def edit_similarity(self, str1, str2):
"""標準化編輯距離相似度(0-1)"""
distance = Levenshtein.distance(str1, str2)
max_len = max(len(str1), len(str2))
return max(0.0, min(1.0, 1 - (distance / max_len))) if max_len > 0 else 1.0
def combined_similarity(self, str1, str2):
"""綜合語義相似度(保留1位小數(shù))"""
tfidf_score = self.tfidf_cosine(str1, str2)
edit_score = self.edit_similarity(str1, str2)
return round(0.6 * tfidf_score + 0.4 * edit_score, 1)
if __name__ == '__main__':
ss = SemanticSimilarity()
str1 = "第十八條 【商標代理】外國人或者外國企業(yè)在中國申請商標注冊和辦理其他商標事宜的,應(yīng)當委托國家認可的具有商標代理資格的組織代理。"
str2 = "第十八條 申請商標注冊或者辦理其他商標事宜,可以自行辦理,也可以委托依法設(shè)立的商標代理機構(gòu)辦理。"
print(f"相似度: {ss.combined_similarity(str1, str2)}")
綜合比較
- Levenshtein:基于字符的相似度而非語義,簡單快速,但不是真正的語義相似度
- Sentence-BERT:輕量級,效果好,支持多語言,推薦使用
- spaCy:中等大小,適合英文,中文需要大模型
- TF-IDF:簡單快速,但不是真正的語義相似度
- USE:Google官方模型,效果好但模型較大
- BERT-as-Service:需要額外服務(wù),適合生產(chǎn)環(huán)境
- 博主自創(chuàng)算法:結(jié)合了結(jié)巴分詞、TF-IDF的余弦相似度、標準化編輯距離,效果好,運行速度塊,并且還可以自行修改占比。
注意事項
- 中文處理需要確保使用支持中文的模型
- 語義相似度計算通常需要較多的計算資源
- 對于生產(chǎn)環(huán)境,建議使用Sentence-BERT或USE
- 首次使用某些方法需要下載大型預(yù)訓(xùn)練模型
選擇哪種方法取決于你的具體需求、計算資源和語言要求。
以上就是Python根據(jù)字符串語義相似度計算的多種實現(xiàn)算法的詳細內(nèi)容,更多關(guān)于Python字符串語義相似度算法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Python?Tkinter?復(fù)選框?->Checkbutton
這篇文章主要介紹了關(guān)于Python?Tkinter復(fù)選框Checkbutton,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
Ubuntu中安裝指定Python版本方法詳解(理論上各版本通用)
現(xiàn)在基于linux的發(fā)行版本有很多,有centos,ubuntu等,一般基于linux的衍生系統(tǒng)至少都安裝了Python2版本,但是現(xiàn)在Python已經(jīng)是3.x版本大行其道了,這篇文章主要給大家介紹了關(guān)于Ubuntu中安裝指定Python版本方法的相關(guān)資料,理論上各版本通用,需要的朋友可以參考下2023-06-06
Flask創(chuàng)建并運行數(shù)據(jù)庫遷移的實現(xiàn)過程
Flask創(chuàng)建并運行數(shù)據(jù)庫遷移的過程是一個涉及多個步驟的操作,旨在幫助開發(fā)者在開發(fā)過程中管理數(shù)據(jù)庫模式的變化,而不需要手動地刪除和重建數(shù)據(jù)庫表,從而避免數(shù)據(jù)丟失,以下是一個詳細的步驟說明,需要的朋友可以參考下2024-09-09
Sublime?Text4?配置?Python3?環(huán)境、代碼提示、編譯報錯的解決方案
這篇文章主要介紹了Sublime?Text4?配置?Python3?環(huán)境、代碼提示、編譯報錯教程,通過圖文并茂的形式給大家介紹了配置自動代碼提示的方法,需要的朋友可以參考下2022-01-01

