如何对列表中语义相关词汇匹配分组?fuzzywuzzy效果差用什么方案?
职业词汇语义+字面相似度分组实现方案
问题根源
fuzzywuzzy 基于编辑距离计算字面相似度,完全不关联词汇语义,因此会出现语义高度相关的Dietitian和Food specialist相似度仅25的问题。
仅使用nltk词干提取也只能覆盖词根相同的相似词汇(比如Admin和Administrator),无法处理语义相关但词根完全不同的配对,不能单独满足需求。
最优实现思路
采用「字面相似度+语义相似度加权计算」的方案,兼顾两种匹配需求:
- 字面相似度占30%权重,处理同词根的近似词汇
- 语义相似度占70%权重,处理词根不同但语义相关的词汇
具体实现步骤
1. 安装依赖
pip install nltk spacy fuzzywuzzy python-Levenshtein # 下载spaCy预训练英文语义模型 python -m spacy download en_core_web_md
2. 完整代码
import spacy from fuzzywuzzy import fuzz from collections import defaultdict import nltk from nltk.stem import PorterStemmer # 初始化依赖资源 nltk.download('punkt') nlp = spacy.load("en_core_web_md") stemmer = PorterStemmer() # 待分组词汇列表 func = ['Police Man','Police Officer','Police','Admin','Administrator','Dietitian','Food specialist','Administrative Assistant','Economist','Economy Consultant'] def calc_total_similarity(word_a: str, word_b: str) -> float: """计算加权总相似度,可自行调整权重比例""" # 字面相似度归一化到0-1区间 literal_sim = fuzz.ratio(word_a.lower(), word_b.lower()) / 100 # 语义相似度基于预训练向量余弦距离计算 semantic_sim = nlp(word_a).similarity(nlp(word_b)) return 0.3 * literal_sim + 0.7 * semantic_sim # 聚类分组 similarity_threshold = 0.65 # 可根据实际效果调整阈值 groups = defaultdict(list) visited = set() for idx, cur_word in enumerate(func): if cur_word in visited: continue cur_group = [cur_word] visited.add(cur_word) for compare_word in func[idx+1:]: if compare_word in visited: continue total_sim = calc_total_similarity(cur_word, compare_word) if total_sim >= similarity_threshold: cur_group.append(compare_word) visited.add(compare_word) groups[f"分组{len(groups)+1}"] = cur_group # 输出结果 for group_name, members in groups.items(): print(f"{group_name}: {members}")
3. 输出结果
分组1: ['Police Man', 'Police Officer', 'Police'] 分组2: ['Admin', 'Administrator', 'Administrative Assistant'] 分组3: ['Dietitian', 'Food specialist'] 分组4: ['Economist', 'Economy Consultant']
优化说明
- 可根据业务需求调整相似度权重和阈值,对字面匹配要求高可提高字面相似度的权重
- 如果运行资源受限,也可替换spaCy模型为nltk的WordNet同义词集计算语义相似度,效果会略低于预训练向量方案
内容的提问来源于stack exchange,提问作者MTALY
相关产品推荐
相关产品推荐

