zabbix-agent 安装
2026/7/17 6:39:00
CiteSpace关键词聚类分析实战:AI辅助下的高效解读与可视化
第一次把CiteSpace跑完,看到那张五颜六色的“关键词聚类时间线”时,我的表情是:这谁看得懂?
痛点总结:
于是我把目光投向AI:既然大模型擅长读文本、图神经网络擅长玩关系,能不能让它们替我“读图”?
整体思路一句话:先用NLP给每个聚类生成“人话标题”,再用图神经网络(GNN)把关系图增强成可交互的“知识地图”。
.txt关键词列表下面代码全部开源依赖,Python≥3.8,CPU也能跑。
pip install pandas sentence-transformers openai torch torchvision torchaudio \ torch-geometric plotly pyvisCiteSpace导出“Project”后,在path/to/project/cluster里能看到cluster_0.txt、cluster_1.txt……每行是关键词+频次。
from pathlib import Path import pandas as pd cluster_dir = Path("path/to/project/cluster") clusters = {} for file in cluster_dir.glob("cluster_*.txt"): cid = int(file.stem.split("_")[1]) lines = file.read_text(encoding="utf-8").splitlines() kw = [l.split("\t")[0] for l in lines if l.strip()] clusters[cid] = kwfrom sentence_transformers import SentenceTransformer from openai import OpenAI st = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") client = OpenAI() def generate_label(kw_list, topK=10): text = ";".join(kw_list[:topK]) prompt = f"用8个汉字概括以下关键词代表的研究主题:{text}" res = client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) return res.choices[0].message.content.strip() labels = {cid: generate_label(kws) for cid, kws in clusters.items()}import torch from torch_geometric.data import Data from torch_geometric.nn import GraphSAGE import numpy as np # 1. 节点列表:所有关键词去重 all_kw = sorted({kw for v in clusters.values() for kw in v}) kw2id = {w: i for i, w in enumerate(all_kw)} embeds = st.encode(all_kw, convert_to_numpy=False).cpu() # 2. 边:共现>5的聚类内关键词 edge_index, edge_weight = [], [] for cid, kws in clusters.items(): for i, w1 in enumerate(kws): for w2 in kws[i+1:]: edge_index.append([kw2id[w1], kw2id[w2]]) edge_weight.append(1) # 可换成真实共现次数 edge_index = torch.tensor(edge_index, dtype=torch.long).t().t().contiguous() edge_weight = torch.tensor(edge_weight, dtype=torch.float) # 3. 训练二分类:同一聚类=1,跨聚类=0 y = [] for e in edge_index.t(): c1 = next((c for c, lst in clusters.items() if all_kw[e[0]] in lst), -1) c2 = next((c for c, lst in clusters.items() if all_kw[e[1]] in lst), -1) y.append(1.0 if c1 == c2 else 0.0) y = torch.tensor(y).unsqueeze(1) data = Data(x=embeds, edge_index=edge_index.t().contiguous(), y=y) class Model(torch.nn.Module): def __init__(self, hidden=64): super().__init__() self.gnn = GraphSAGE(data.x.shape[1], hidden, 2) self.fc = torch.nn.Linear(hidden, 1) def forward(self, x, edge_index): x = self.gnn(x, edge_index).relu() return torch.sigmoid(self.fc(x)) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = Model().to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.01) criterion = torch.nn.BCEWithLogitsLoss() for epoch in range(100): model.train() optimizer.zero_grad() out = model(data.x.to(device), data.edge_index.to(device)) loss = criterion(out, data.y.to(device)) loss.backward() optimizer.step()model.eval() with torch.no_grad(): prob = model(data.x.to(device), data.edge_index.to(device)).cpu().numpy().flatten() edge_conf = dict(zip(range(edge_index.shape[0]), prob))用PyVis快速搭一个可拖拽的网页,边透明度按GNN置信度调整。
from pyvis.network import Network import random g = Network(height="800px", width="100%", bgcolor="#ffffff", font_color="black") # 加节点 for kw, i in kw2id.items(): cid = next((c for c, lst in clusters.items() if kw in lst), 0) g.add_node(i, label=kw, group=cid) # 加边 for idx, (u, v) in enumerate(edge_index): conf = edge_conf[idx] g.add_edge(u, v, value=float(conf), title=f"conf={conf:.2f}", color=f"rgba(100,100,100,{conf})") # 透明度=置信度 # 物理引擎调参 g.barnes_hut(gravity=-8000, central_gravity=0.3, spring_length=50) g.show("ai_enhanced_cluster.html")浏览器打开ai_enhanced_cluster.html,拖动任意节点,边线越实表示GNN越确信“它俩该在一起”;虚线则是“可合并的冗余”。配合左上角“group”筛选,可一键只显示某个聚类。
数据清洗
模型参数
标签幻觉
甚至,把节点换成“B站弹幕关键词”,你就能做“番剧聚类热点”——科研方法破圈,有时候只差一个脑洞。
带着问题去动手,你的下一篇论文,也许就从这张AI画的“彩虹糖”开始。