Python中关键词集合相似度计算及spaCy替代方案咨询
关键词列表相似度计算方案及spaCy替代方案
一、可靠的关键词列表相似度计算方法
针对语义一致但表述不同的关键词场景,推荐以下几种方法:
1. 预训练词向量集合匹配
利用Word2Vec、GloVe等预训练词向量模型,将每个关键词转化为向量后,计算两组向量集合的整体相似度:
- 核心逻辑:加载预训练词向量 → 过滤掉不在词表中的关键词 → 计算双向最大相似度的平均值(即db1中每个词匹配db2中最相似的词取平均,再反向计算取均值),或直接计算两组向量中心的余弦相似度。
- 示例代码(基于gensim):
from gensim.models import KeyedVectors from sklearn.metrics.pairwise import cosine_similarity import numpy as np # 加载预训练GloVe模型(需提前下载对应权重文件) word_vectors = KeyedVectors.load_word2vec_format('glove.6B.100d.txt', binary=False) def get_word_vector(word): try: return word_vectors[word.lower()] except KeyError: return None def calculate_list_similarity(list1, list2): vecs1 = [v for v in [get_word_vector(w) for w in list1] if v is not None] vecs2 = [v for v in [get_word_vector(w) for w in list2] if v is not None] if not vecs1 or not vecs2: return 0.0 # 双向最大相似度平均 sim_scores1 = [max(cosine_similarity([v1], vecs2)[0]) for v1 in vecs1] sim_scores2 = [max(cosine_similarity([v2], vecs1)[0]) for v2 in vecs2] return (np.mean(sim_scores1) + np.mean(sim_scores2)) / 2 # 示例调用 db1 = ["machine learning", "data mining"] db2 = ["ML", "data extraction"] print(calculate_list_similarity(db1, db2))
2. Sentence-BERT语义匹配
将每个关键词视为独立句子,用Sentence-BERT生成语义向量,这种方法对表述不同但语义一致的场景适配性极强:
- 核心逻辑:加载轻量级预训练模型 → 生成两组关键词的语义向量 → 计算集合层面的双向匹配相似度。
- 示例代码:
from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity import numpy as np model = SentenceTransformer('all-MiniLM-L6-v2') def calculate_sbert_similarity(list1, list2): vecs1 = model.encode(list1) vecs2 = model.encode(list2) sim_scores1 = [max(cosine_similarity([v1], vecs2)[0]) for v1 in vecs1] sim_scores2 = [max(cosine_similarity([v2], vecs1)[0]) for v2 in vecs2] return (np.mean(sim_scores1) + np.mean(sim_scores2)) / 2 # 示例调用 db1 = ["customer retention", "user engagement"] db2 = ["keeping customers", "user interaction"] print(calculate_sbert_similarity(db1, db2))
3. TF-IDF+余弦相似度
如果关键词存在部分重合,可先将两组关键词合并为语料,生成TF-IDF向量后计算相似度:
- 注意:该方法更依赖词频重合度,对语义差异大但表述不同的关键词效果有限。
- 示例代码:
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity def calculate_tfidf_similarity(list1, list2): corpus = [' '.join(list1), ' '.join(list2)] tfidf = TfidfVectorizer().fit_transform(corpus) return cosine_similarity(tfidf[0:1], tfidf[1:2])[0][0] # 示例调用 db1 = ["python", "data analysis"] db2 = ["python", "data analytics"] print(calculate_tfidf_similarity(db1, db2))
二、spaCy无法导入的替代方案
1. Sentence-BERT(优先推荐)
sentence-transformers库安装简单(执行pip install sentence-transformers即可),环境兼容性好,无需复杂的模型配置,直接支持语义向量生成与相似度计算,对关键词场景适配性强。
2. Gensim预训练词向量
通过gensim加载Word2Vec/GloVe预训练模型,安装命令为pip install gensim,模型可从公开数据集下载(如GloVe的6B维度模型),适合处理单个词的语义匹配。
3. NLTK WordNet同义词匹配
对于短关键词,可利用WordNet的同义词集合计算Jaccard相似度:
- 核心逻辑:对每个关键词获取同义词集合 → 计算两组同义词集合的交集与并集比例。
- 示例代码:
from nltk.corpus import wordnet import nltk nltk.download('wordnet') def get_synonyms(word): synonyms = set() for syn in wordnet.synsets(word.lower()): for lemma in syn.lemmas(): synonyms.add(lemma.name()) return synonyms def calculate_jaccard_similarity(list1, list2): all_syns1 = set() for w in list1: all_syns1.update(get_synonyms(w)) all_syns2 = set() for w in list2: all_syns2.update(get_synonyms(w)) if not all_syns1 or not all_syns2: return 0.0 intersection = len(all_syns1 & all_syns2) union = len(all_syns1 | all_syns2) return intersection / union # 示例调用 db1 = ["happy", "joyful"] db2 = ["glad", "cheerful"] print(calculate_jaccard_similarity(db1, db2))
内容的提问来源于stack exchange,提问作者codexxblack
相关产品推荐
相关产品推荐

