基于Python的NLP动态关键词聚类 优化组织人员兴趣图谱
问题
我正在调查组织内人员的共同兴趣,希望优化现有流程,基于人员自述兴趣构建不同群体间共同/小众兴趣的加权图谱。目前已用Python实现了一个粗略的兴趣映射算法,步骤如下:
- 使用requests库从网络下载用户档案;
- 用Beautiful Soup从HTML中提取相关信息;
- 结合Spacy(en_core_web_sm)与LLM(distilroberta-base)分析文本关键词,通过Counter统计出现次数(流程为词形还原→分词→提取嵌入向量→余弦相似度计算距离→统计频次);
- 过滤无关关键词;
- 返回包含id和兴趣列表的字典;
- 遍历每个档案,得到有共同兴趣的id列表;
- 转换步骤6的输出,将兴趣作为id,共同id作为兴趣;
- 用plotly和streamlit绘制步骤6的输出图谱;
- 用plotly和streamlit绘制步骤7的输出图谱(已展示)。
现有流程可生成基于用户档案关键词的兴趣图谱,但存在两个核心问题:
- 人们用词习惯不同,同类主题需聚类(如
['climate', 'decarbonization']可归为一类,Python、R、Java可归为Programming); - 需支持动态增删用户。
我是HuggingFace新手,正在寻找合适的模型或工具来解决该问题。
示例步骤3输出:
{'id': 'chris', 'interests': {'Python':3, 'R':2, 'Java': 1} }
解决方案
一、解决同类兴趣聚类问题(基于HuggingFace工具)
1. 语义向量+聚类实现兴趣归一化
选轻量型语义模型all-MiniLM-L6-v2(属于sentence-transformers系列,适合短文本语义匹配,速度快易上手),结合聚类算法完成同类兴趣归组:
- 实现步骤:
- 收集所有用户的兴趣词去重,生成全局兴趣词列表;
- 用模型将每个兴趣词转换为语义向量;
- 用HDBSCAN聚类(无需提前指定聚类数,适配未知类别的兴趣词);
- 给聚类结果手动打统一标签(如包含Python/R/Java的聚类标为Programming)。
- 代码片段:
from sentence_transformers import SentenceTransformer from sklearn.cluster import HDBSCAN # 加载预训练模型 model = SentenceTransformer('all-MiniLM-L6-v2') # 全局去重兴趣词列表 interest_words = ['Python', 'R', 'Java', 'climate', 'decarbonization', 'machine learning'] # 生成语义向量 embeddings = model.encode(interest_words) # 聚类 clusterer = HDBSCAN(min_cluster_size=2) cluster_labels = clusterer.fit_predict(embeddings) # 聚类标签映射 cluster_to_label = { 0: 'Programming', 1: 'Climate Action', 2: 'AI/ML' } # 将原始兴趣词替换为聚类标签 def map_to_cluster(interest_dict): clustered_interests = {} for word, count in interest_dict.items(): idx = interest_words.index(word) label = cluster_to_label.get(cluster_labels[idx], word) clustered_interests[label] = clustered_interests.get(label, 0) + count return clustered_interests
2. 零样本分类直接归类兴趣
如果你能提前定义好组织内的兴趣大类,可用零样本分类模型facebook/bart-large-mnli,直接把零散兴趣词匹配到预设类别:
- 代码片段:
from transformers import pipeline # 加载零样本分类模型 classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") # 预设兴趣大类 candidate_labels = ['Programming', 'Climate Action', 'AI/ML', 'Other'] def normalize_interest(interest_word): result = classifier(interest_word, candidate_labels) return result['labels'][0] # 返回最匹配的类别
二、支持动态增删用户
1. 数据存储优化
把用户兴趣数据(原始词、聚类标签、频次)存在SQLite(Python自带,无需额外部署)或用Peewee(轻量ORM框架)管理,避免存在内存中丢失数据。增删用户时直接操作数据库即可。
2. 增量更新图谱
- 新增用户:无需重新遍历所有档案,仅将新用户的兴趣与现有用户做匹配,更新共同兴趣关系;
- 删除用户:从图谱中移除该用户节点及所有关联边,无需重新计算全局数据。
3. Streamlit动态交互
在Streamlit界面添加增删按钮(st.button),操作完成后调用st.experimental_rerun()触发图谱重新绘制。
内容的提问来源于stack exchange,提问作者CER
相关产品推荐
相关产品推荐

