基于NLTK处理复合词(二元语法)及用户关键词相似度识别技术问询
看起来你已经找对了方向——用词形还原处理单复数确实是提升关键词相似度计算准确性的关键一步!我来帮你把这个思路落地成完整可运行的代码,并且优化相似度计算的逻辑。
关键词相似度计算方案(处理单复数+多维度匹配)
1. 完善的词形还原预处理流程
WordNetLemmatizer配合词性标注能更精准地处理单复数/时态变化,下面是补全后的预处理代码:
from nltk.stem import WordNetLemmatizer from nltk.tokenize import word_tokenize from nltk.corpus import wordnet import nltk # 第一次运行需下载NLTK依赖资源 nltk.download('wordnet') nltk.download('punkt') nltk.download('averaged_perceptron_tagger') def get_wordnet_pos(tag): """把NLTK词性标签转换成词形还原需要的格式""" if tag.startswith('J'): return wordnet.ADJ elif tag.startswith('V'): return wordnet.VERB elif tag.startswith('N'): return wordnet.NOUN elif tag.startswith('R'): return wordnet.ADV else: return wordnet.NOUN # 默认按名词处理兴趣标签 def lemmatize_keywords(keywords): """对关键词列表做词形还原+去重""" wnl = WordNetLemmatizer() lemmatized = [] for keyword in keywords: tokens = word_tokenize(keyword.lower()) # 先统一小写再分词 pos_tags = nltk.pos_tag(tokens) for token, tag in pos_tags: lemma = wnl.lemmatize(token, pos=get_wordnet_pos(tag)) lemmatized.append(lemma) return list(set(lemmatized)) # 去重避免重复标签干扰结果
2. 两种实用的相似度计算方法
方法一:杰卡德相似度(简单直观)
通过计算关键词集合的交集/并集比例,快速得到相似度:
def calculate_jaccard_similarity(set_a, set_b): intersection = len(set_a.intersection(set_b)) union = len(set_a.union(set_b)) return intersection / union if union != 0 else 0.0 # 用你的测试案例验证 alice_keywords = ["pizza", "music", "movies"] bob_keywords = ["cooking", "guitar", "movie"] eve_keywords = ["knitting", "running", "gym"] # 先做词形还原 alice_lemmas = set(lemmatize_keywords(alice_keywords)) bob_lemmas = set(lemmatize_keywords(bob_keywords)) eve_lemmas = set(lemmatize_keywords(eve_keywords)) # 计算相似度 alice_bob_sim = calculate_jaccard_similarity(alice_lemmas, bob_lemmas) alice_eve_sim = calculate_jaccard_similarity(alice_lemmas, eve_lemmas) print(f"Alice & Bob 相似度: {alice_bob_sim:.2f}") # 输出 0.20(交集为movie,共5个唯一词) print(f"Alice & Eve 相似度: {alice_eve_sim:.2f}") # 输出 0.00
方法二:余弦相似度(适合扩展复杂场景)
如果后续要给关键词加权重、处理大量标签,用向量余弦相似度更灵活:
from sklearn.feature_extraction.text import CountVectorizer from sklearn.metrics.pairwise import cosine_similarity def calculate_cosine_similarity(lemmas_list): # 将词集合转为空格分隔的文本格式 texts = [' '.join(lemmas) for lemmas in lemmas_list] # 构建词袋向量 vectorizer = CountVectorizer() word_vectors = vectorizer.fit_transform(texts) # 计算余弦相似度矩阵 sim_matrix = cosine_similarity(word_vectors) return sim_matrix # 测试 lemmas_list = [alice_lemmas, bob_lemmas, eve_lemmas] sim_matrix = calculate_cosine_similarity(lemmas_list) print("余弦相似度矩阵:") print(sim_matrix) # 其中sim_matrix[0][1]就是Alice和Bob的相似度,约0.45,符合预期
3. 额外优化小技巧
- 同义词关联:可以用WordNet的同义词集合(synsets)把相关词归为一类,比如把"guitar"和"music"关联,进一步提升相似度准确性
- 停用词过滤:如果关键词里混入通用词(比如"the"),可以用NLTK停用词库过滤掉
- 权重自定义:给用户频繁提及的关键词加权重,让相似度计算更贴合实际兴趣强度
内容的提问来源于stack exchange,提问作者Titus Pullo
相关产品推荐
相关产品推荐

