基于无监督聚类的工单修复方案分类技术咨询及现有方案优化需求
基于无监督聚类的工单修复方案分类技术咨询及现有方案优化需求
看起来你已经踩对了「未知类别下做工单聚类」的第一步——用TF-IDF+KMeans做无监督聚类,但卡在了「只有零散关键词,没法对应到「软件升级」「数据库优化」这类业务可读的分类标签」这个核心痛点上对吧?我结合你的现有代码,给你梳理下怎么把技术结果落地成业务可用的分类:
一、先解决「关键词无上下文」的问题:优化TF-IDF,让关键词带语境
你注释掉的spaCy分词+N-gram配置其实才是能保留上下文的关键!单个词比如「upgrade」太模糊,但短语「software upgrade」直接就能对应业务标签。我把这部分代码恢复并优化下:
import spacy from sklearn.feature_extraction.text import TfidfVectorizer # 提前安装依赖:pip install spacy && python -m spacy download en_core_web_sm nlp = spacy.load("en_core_web_sm") def spacy_tokenizer(text): # 自定义分词:只保留有实际意义的名词、动词、形容词,过滤停用词和标点 tokens = nlp(text) return [token.lemma_.lower() for token in tokens if not token.is_stop and not token.is_punct and token.pos_ in ["NOUN", "VERB", "ADJ"]] # 优化后的TF-IDF:用自定义分词+1-2词的N-gram,保留业务短语 vectorizer = TfidfVectorizer( input='content', tokenizer=spacy_tokenizer, ngram_range=(1,2), # 同时提取单个词和2词短语,保留「software upgrade」这类语境 stop_words='english', max_features=1000 ) X = vectorizer.fit_transform(comments) feature_names = vectorizer.get_feature_names_out()
这么改之后,你的关键词会从「upgrade」「database」变成「software upgrade」「database optimize」这类带语境的短语,一眼就能看出来对应什么业务场景。
二、给KMeans聚类结果加「业务解释」的实操步骤
光有关键词还不够,必须结合真实工单内容才能把聚类映射成业务标签,我给你在现有代码后面加两步关键操作:
1. 先从每个聚类里抽代表性工单,读懂聚类的业务含义
# 假设你的工单文本存在df的comments列中 for cluster_num in range(n_clusters): print(f"\n=== 聚类 {cluster_num} 代表性工单 ===") # 从每个聚类里随机挑5-10条完整工单,快速扫一遍就懂这个聚类的核心内容 sample_notes = df[df['Cluster'] == cluster_num]['comments'].sample(5, random_state=42).tolist() for idx, note in enumerate(sample_notes): print(f"工单{idx+1}: {note[:200]}...") # 只显示前200字避免太长
比如你发现聚类0的样本全是「升级到v2.3版本解决了连接超时」「安装补丁修复了内存泄漏」,那这个聚类就可以直接命名为「软件升级修复」,瞬间就有业务意义了。
2. 优化关键词提取,优先展示有业务价值的短语
把你原来的关键词提取函数改一下,优先保留2词短语,过滤掉无意义的单个词:
def get_top_keywords_per_cluster(kmeans_model, feature_names, n_terms=15): order_centroids = kmeans_model.cluster_centers_.argsort()[:, ::-1] cluster_keywords = [] for i in range(kmeans_model.n_clusters): # 先拿足够多的关键词,再优先筛选带空格的短语 all_keywords = [feature_names[ind] for ind in order_centroids[i, :n_terms*2]] phrase_keywords = [kw for kw in all_keywords if " " in kw] # 如果短语不够15个,再补单个关键词凑数 if len(phrase_keywords) < n_terms: single_keywords = [kw for kw in all_keywords if " " not in kw] phrase_keywords += single_keywords[:n_terms - len(phrase_keywords)] cluster_keywords.append(phrase_keywords[:n_terms]) return cluster_keywords # 按原来的逻辑赋值,现在的关键词会是带语境的短语 cluster_keywords = get_top_keywords_per_cluster(kmeans, feature_names, n_terms=15) df['Cluster Topics'] = df['Cluster'].map(lambda x: ", ".join(cluster_keywords[x])) df['Cluster Main Topic'] = df['Cluster'].map(lambda x: cluster_keywords[x][0])
这样你得到的「Cluster Main Topic」会是「software upgrade」「database optimization」这类直接能当业务标签的短语,而不是单个模糊的词。
三、从「聚类」到「业务分类」的收尾建议
- 人工校验+命名:最终的分类标签必须贴合业务,所以先给每个聚类人工起个业务名字(比如把cluster 0命名为「软件升级修复」),然后映射到数据框里:
# 举个例子,你根据聚类的代表性工单和关键词,自定义业务标签映射 cluster_to_label = { 0: "软件升级修复", 1: "数据库性能优化", 2: "系统配置调整", 3: "网络问题排查", 4: "Bug补丁修复" } df['Business Label'] = df['Cluster'].map(cluster_to_label)
- 调整聚类数量:你现在设的
n_clusters=5可能不够贴合业务,可以用「肘部法则」选最优值:画KMeans的inertia(簇内平方和)随聚类数变化的曲线,找曲线突然变平缓的那个点(比如n=3或n=6),这样聚类结果会更精准。 - 进阶:用LDA主题模型辅助:如果KMeans的硬聚类还是不够灵活,可以试试LDA主题模型,它能给出每个工单属于多个主题的概率,而且主题的关键词会更有语义连贯性(新手可以先把上面的优化做完,效果已经够用了)。
其实你现在的思路完全没问题,只是缺了「把技术结果和业务内容结合」的那一步,先从「看代表性工单」入手,很快就能把冰冷的聚类编号转化成有业务价值的分类标签啦!




