去年团队想利用公司的智能机器人搭建智能客服,第一步就是需要收集整理线上用户反馈数据,对数据分类后作为机器人的训练数据,因此也有机会在业务中简单实践聚类算法。
K - Means 是聚类问题中最为常用的算法之一,原理相对简单,也成为我们首先尝试的方法。
K - Means
K - Means 的核心思想是”物以类聚,人以群分“,算法本身是把 N 个多维的观察点,通过不断的迭代计算,更加合理的划分到 K 个集合中。
算法大致描述如下:
- 初始化计算模型,确定
K
值,表示将多维观察点划分为K
个集合 - 为
K
个集合选择初始质心 - 计算每个观察点到
K
个质心的距离,将观察点划分到距离最近的集合里 - 为
K
个集合选择新的质心,以获得更好的聚类效果 - 重复步骤 3 ~ 步骤 5,直到集合的质点趋于稳定,或达到最大迭代次数
结合业务需求,在过程中有两个特征需要关注:
K
值。该值决定了最终反馈问题被分成几类,而在业务场景下,无法很明确的推断出K
,需要不断测试找到最佳的值- 多维观察点。我们的原始数据是用户反馈问题,其本质是文本内容,需要找到合适的方式,将文本转化为多维向量
TF - IDF
我们有提到,要使用K - Means 对反馈问题进行聚类,就需要找到一个方法把文本转化为多维向量,这个过程就是文本特征向量化,够抽取文本中的特征,并以多维向量的方式描述文本内容。关于文本特征向量化的方法有很多,我们采用的是比较简单的TF - IDF。
TF - IDF (Term Frequency – Inverse Document Frequency),其中 TF 是词频,描述词汇在文档中出现的评率;IDF 是逆文本频率指数,描述一个词语的区分能力和重要性,词语在不同文档中出现的越少,IDF 值越大,重要性越高。
问题聚类
基于 K - Means 和 TF - IDF,我们对反馈问题进行聚类。代码比较简单,大致逻辑如下:
1 |
|
通过不断的对K
值进行调整,同时不断优化训练数据集,最终达到的效果如下:
红框的上下是得到的两个不同分类,分类内的问题都是相似的。
从最终效果上来看,大部分分类内的问题都是有关联的,但是也存在问题:
(1)部分分类也呈现出问题之间无太大关联的情况,原因可能是K
值偏大,或是受到切词算法、文本特征向量化算法本身的缺陷导致。
(2)部分分类内部问题高度相似,但也掺杂部分无关问题,原因是无关问题中包含了部分关键字,和当前分类高度契合,所以被划入进来。
分类主题
找到了分类,还有一个问题,是怎么得出这个分类的主题。
想到的方法也很简单,就是找到这个分类中每个问题的关键词,然后看哪个关键词更多。那么问题就转变为如何找到关键词,我的方法依旧是使用 TF - IDF,基于当前分类,找到每个问题中 TF - IDF 最高的 3 ~ 5 个词,结果如下:
基本可以总结出分类中的关键信息,截图中的分类主题是“找回密码”。同时,从图中也可以发现一些问题,就是主题关键词中,出现了“怎么”,该次可能也是出现 TF - IDF 值较高的词汇,针对这个问题,也有对应的方法可以解决:
(1)通过无用词过滤,把常见却无效的词过滤掉,避免这类常见词因 TF - IDF 值而影响整体结果。
(2)再进行一次 K - Means ,将找到的关键词进行再进行一次聚类,只分为2个类,找到其中分值最高的一个分类作为主题关键词
为什么这么做呢,我有对分类里找到的关键词得分进行观察,发现从分值上可以看出一批是高分,一批是低分,即高关联词汇组和低关联词汇组,所以想再做一次分组,来找出高分词汇。
存在的问题
基于上面的方法,我们完成了反馈问题的聚类和主题分析,但是从最终结果来看,其实问题还是很多的:
- 数据清洗
在整个过程中,耗费时间最多的是数据清洗,需要把反馈问题中的无效数据进行过滤,包括特殊字符、表情等。同时,出于安全与合规的考虑,需要移除反馈问题中的人名、手机号、地理位置等等。
- 切词
在使用 TF - IDF 之前,需要对反馈问题进行分词,我使用的是开源的分词库jieba
,可以实现基础的分词,但是分词结果并不能直接使用。
首先,分词结果中包含停用词,该类词汇本身并无含义,需要过滤掉,以避免停用词影响分析。其次,各个产品都有其自身的关键词,例如对于腾讯而言,QQ、阅文、微视、腾讯云是关键词。
K
值
在训练过程中,K
值也是反复测试调整过多轮的。如果K
值过大,则可能导致相同含义的问题被氛围了多组;如果K
值过小,则可能分类里的不相关问题会偏多。