Python根据字符串语义相似度计算的多种实现算法

作者:

文章目录
  • 如果需要基于字符的相似度而非语义,可以使用 Levenshtein 距离。 先安装模块: pip install Levenshtein 案例代码: import Levenshtein def levenshtein_similarity(text1, text2): # 计算 Levenshtein 距离 distance = Levenshtein.distance(text1, text2) # 计算相似度并保留一位小数 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
  • Sentence Transformers 可以将文本转换为语义向量,然后通过余弦相似度计算文本之间的相似度。 使用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]) # 转换为0-1范围并保留一位小数 similarity = float(np.clip(cosine_score.item(), 0.0, 1.0)) return round(similarity, 1) # 示例 print(semantic_similarity_sbert(“我喜欢吃苹果”, “我爱吃水果”)) # 输出类似: 0.8
  • spaCy 是一个强大的自然语言处理库,可以通过预训练模型来计算两个文本的语义相似度。 需要先安装: 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) # 计算语义相似度并保留一位小数 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
  • 使用 Word Mover’s Distance (WMD),WMD 是一种基于词向量的距离度量,可以用来计算文本之间的语义差异,通过转换为相似度。 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范围内并保留一位小数 return round(max(0.0, min(1.0, similarity)), 1) # 示例 print(semantic_similarity_spacy(“今天天气很好”, “明天的天气不错”)) # 输出类似: 0.7
  • 使用Google的Universal Sentence Encoder需要先安装: pip install tensorflow-hub tensorflow-text 注意: 首次使用需要下载模型(约900MB) import tensorflow_hub as hub import tensorflow_text as text # 必须导入 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范围内并保留一位小数 return round(max(0.0, min(1.0, similarity)), 1) # 示例 print(semantic_similarity_use(“这只猫很可爱”, “那只猫咪非常漂亮”)) # 输出类似: 0.8
  • 使用BERT-as-Service计算语义相似度需要先安装: pip install bert-serving-server bert-serving-client 并下载预训练模型运行服务端 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范围内并保留一位小数 return round(max(0.0, min(1.0, similarity)), 1) # 示例 # print(semantic_similarity_bert(“他正在跑步”, “他在运动”)) # 输出类似: 0.9
  • 这是一种基于词频的相似度计算方法。 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和余弦相似度计算文本相似度 基于词频统计,不是真正的语义相似度,但可以作为基线方法 “”” vectorizer = TfidfVectorizer() tfidf_matrix = vectorizer.fit_transform([str1, str2]) # 计算余弦相似度 similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0] # 确保在0-1范围内并保留一位小数 return round(max(0.0, min(1.0, similarity)), 1) # 示例 print(semantic_similarity_tfidf(“深度学习”, “神经网络”)) # 输出类似: 0.6
  • 结巴分词、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位小数)””” 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 = “第十八条 【商标代理】外国人或者外国企业在中国申请商标注册和办理其他商标事宜的,应当委托国家认可的具有商标代理资格的组织代理。” str2 = “第十八条 申请商标注册或者办理其他商标事宜,可以自行办理,也可以委托依法设立的商标代理机构办理。” print(f”相似度: {ss.combined_similarity(str1, str2)}”)
  • Levenshtein:基于字符的相似度而非语义,简单快速,但不是真正的语义相似度 Sentence-BERT:轻量级,效果好,支持多语言,推荐使用 spaCy:中等大小,适合英文,中文需要大模型 TF-IDF:简单快速,但不是真正的语义相似度 USE:Google官方模型,效果好但模型较大  BERT-as-Service:需要额外服务,适合生产环境 博主自创算法:结合了结巴分词、TF-IDF的余弦相似度、标准化编辑距离,效果好,运行速度块,并且还可以自行修改占比。
  • 中文处理需要确保使用支持中文的模型 语义相似度计算通常需要较多的计算资源 对于生产环境,建议使用Sentence-BERT或USE 首次使用某些方法需要下载大型预训练模型 选择哪种方法取决于你的具体需求、计算资源和语言要求。 以上就是Python根据字符串语义相似度计算的多种实现算法的详细内容,更多关于Python字符串语义相似度算法的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python+fuzzywuzzy计算两个字符串之间的相似度 Python中的字符串相似度 python库TextDistance量化文本之间的相似度算法探究 Python计算序列相似度的算法实例 python OpenCV计算图片相似度的5种算法
  • 目录
    • 方法1:计算 Levenshtein 距离 (基于字符的相似度)
    • 方法2:使用Sentence-BERT预训练模型
    • 方法3:使用spaCy进行语义相似度比较
    • 方法4:使用spaCy和词向量
    • 方法5:使用Universal Sentence Encoder (USE)
    • 方法6:使用BERT-as-Service
    • 方法7:使用TF-IDF和余弦相似度(基于词频统计)
    • 方法8:博主自创算法
    • 综合比较
    • 注意事项

    以下是几种基于语义的字符串相似度计算方法,每种方法都会返回0.0到1.0之间的相似度分数(保留一位小数)。

    如果需要基于字符的相似度而非语义,可以使用 Levenshtein 距离。

    先安装模块:

    pip install Levenshtein
    

    案例代码:

    import Levenshtein
    
    def levenshtein_similarity(text1, text2):
        
        # 计算 Levenshtein 距离
        distance = Levenshtein.distance(text1, text2)
        # 计算相似度并保留一位小数
        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
    

    Sentence Transformers 可以将文本转换为语义向量,然后通过余弦相似度计算文本之间的相似度。

    使用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])
        
        # 转换为0-1范围并保留一位小数
        similarity = float(np.clip(cosine_score.item(), 0.0, 1.0))
        return round(similarity, 1)
    
    # 示例
    print(semantic_similarity_sbert("我喜欢吃苹果", "我爱吃水果"))  # 输出类似: 0.8
    

    spaCy 是一个强大的自然语言处理库,可以通过预训练模型来计算两个文本的语义相似度。

    需要先安装:

    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)
        # 计算语义相似度并保留一位小数
        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
    

    使用 Word Mover’s Distance (WMD),WMD 是一种基于词向量的距离度量,可以用来计算文本之间的语义差异,通过转换为相似度。

    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范围内并保留一位小数
        return round(max(0.0, min(1.0, similarity)), 1)
    
    # 示例
    print(semantic_similarity_spacy("今天天气很好", "明天的天气不错"))  # 输出类似: 0.7
    

    使用Google的Universal Sentence Encoder需要先安装:

    pip install tensorflow-hub tensorflow-text
    

    注意: 首次使用需要下载模型(约900MB)

    import tensorflow_hub as hub
    import tensorflow_text as text  # 必须导入
    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范围内并保留一位小数
        return round(max(0.0, min(1.0, similarity)), 1)
    
    # 示例
    print(semantic_similarity_use("这只猫很可爱", "那只猫咪非常漂亮"))  # 输出类似: 0.8
    

    使用BERT-as-Service计算语义相似度
    需要先安装:

    pip install bert-serving-server bert-serving-client
    

    并下载预训练模型运行服务端

    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范围内并保留一位小数
        return round(max(0.0, min(1.0, similarity)), 1)
    
    # 示例
    # print(semantic_similarity_bert("他正在跑步", "他在运动"))  # 输出类似: 0.9
    

    这是一种基于词频的相似度计算方法。

    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和余弦相似度计算文本相似度
        基于词频统计,不是真正的语义相似度,但可以作为基线方法
        """
        vectorizer = TfidfVectorizer()
        tfidf_matrix = vectorizer.fit_transform([str1, str2])
        
        # 计算余弦相似度
        similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
        
        # 确保在0-1范围内并保留一位小数
        return round(max(0.0, min(1.0, similarity)), 1)
    
    # 示例
    print(semantic_similarity_tfidf("深度学习", "神经网络"))  # 输出类似: 0.6
    

    结巴分词、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位小数)"""
            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 = "第十八条 【商标代理】外国人或者外国企业在中国申请商标注册和办理其他商标事宜的,应当委托国家认可的具有商标代理资格的组织代理。"
        str2 = "第十八条 申请商标注册或者办理其他商标事宜,可以自行办理,也可以委托依法设立的商标代理机构办理。"
        print(f"相似度: {ss.combined_similarity(str1, str2)}")
    
    

    • Levenshtein:基于字符的相似度而非语义,简单快速,但不是真正的语义相似度
    • Sentence-BERT:轻量级,效果好,支持多语言,推荐使用
    • spaCy:中等大小,适合英文,中文需要大模型
    • TF-IDF:简单快速,但不是真正的语义相似度
    • USE:Google官方模型,效果好但模型较大 
    • BERT-as-Service:需要额外服务,适合生产环境
    • 博主自创算法:结合了结巴分词、TF-IDF的余弦相似度、标准化编辑距离,效果好,运行速度块,并且还可以自行修改占比。

    1. 中文处理需要确保使用支持中文的模型
    2. 语义相似度计算通常需要较多的计算资源
    3. 对于生产环境,建议使用Sentence-BERT或USE
    4. 首次使用某些方法需要下载大型预训练模型

    选择哪种方法取决于你的具体需求、计算资源和语言要求。

    以上就是Python根据字符串语义相似度计算的多种实现算法的详细内容,更多关于Python字符串语义相似度算法的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • Python+fuzzywuzzy计算两个字符串之间的相似度
    • Python中的字符串相似度
    • python库TextDistance量化文本之间的相似度算法探究
    • Python计算序列相似度的算法实例
    • python OpenCV计算图片相似度的5种算法

    站内搜索