赞
踩
(纯属为了记录自己学习的点滴过程,引用资料都附在参考列表)
聚类(cluster analysis )指的是将给定对象的集合划分为不同子集的过程,目标是使得每个子集内部的元素尽量相似,不同子集间的元素尽量不相似。
对多个文档,在文档颗粒上进行聚类;
文本聚类的基本流程分为特征提取和向量聚类两步, 如果能将文档表示为向量,就可以对其应用聚类算法。这种表示过程称为特征提取,而一旦将文档表示为向量,剩下的算法就与文档无关了。这种抽象思维无论是从软件工程的角度,还是从数学应用的角度都十分简洁有效。
词袋(bag-of-words )是信息检索与自然语言处理中最常用的文档表示模型,它将文档想象为一个装有词语的袋子, 通过袋子中每种词语的计数等统计量将文档表示为向量。比如下面的例子:
人 吃 鱼。
美味 好 吃!
统计词频后如下:
人=1
吃=2
鱼=1
美味=1
好=1
文档经过该词袋模型得到的向量表示为[1,2,1,1,1],这 5 个维度分别表示这 5 种词语的词频。
一般选取训练集文档的所有词语构成一个词表,词表之外的词语称为 oov,不予考虑。一旦词表固定下来,假设大小为 N。则任何一个文档都可以通过这种方法转换为一个N维向量。比如“人 吃 大 鱼”这个文档,它的词频统计为:
人=1
吃=1
鱼=1
美味=0
好=0
那么它的词袋向量就是[1,1,1,0,0],其中后两个维度上的词语没有出现,所以都是0。而“大”这个词属于OOV,散落在词袋之外,所以不影响词袋向量。
词袋模型不考虑词序,也正因为这个原因,词袋模型损失了词序中蕴含的语义,比如,对于词袋模型来讲,“人吃鱼”和“鱼吃人”是一样的,这就荒谬了,但在实际工程中,词袋模型依然是一个很难打败的基线模型。
词袋中的统计量
详细推导见《统计学习方法》;
《统计学习方法》中只介绍了自下而上的聚合层次聚类,没有介绍自上而下的分裂层次聚类,而本节实现中使用的是分裂层次聚类。
该聚类模块可以接受任意文本作为文档,而不需要用特殊分隔符隔开单词。
# -*- coding:utf-8 -*- from pyhanlp import * ClusterAnalyzer = JClass('com.hankcs.hanlp.mining.cluster.ClusterAnalyzer') if __name__ == '__main__': analyzer = ClusterAnalyzer() analyzer.addDocument("赵一", "流行, 流行, 流行, 流行, 流行, 流行, 流行, 流行, 流行, 流行, 蓝调, 蓝调, 蓝调, 蓝调, 蓝调, 蓝调, 摇滚, 摇滚, 摇滚, 摇滚") analyzer.addDocument("钱二", "爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲") analyzer.addDocument("张三", "古典, 古典, 古典, 古典, 民谣, 民谣, 民谣, 民谣") analyzer.addDocument("李四", "爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 爵士, 金属, 金属, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲, 舞曲") analyzer.addDocument("王五", "流行, 流行, 流行, 流行, 摇滚, 摇滚, 摇滚, 嘻哈, 嘻哈, 嘻哈") analyzer.addDocument("马六", "古典, 古典, 古典, 古典, 古典, 古典, 古典, 古典, 摇滚") print(analyzer.kmeans(3)) print(analyzer.repeatedBisection(3)) print(analyzer.repeatedBisection(1.0)) # 自动判断聚类数量k
运行结果:
[[王五, 赵一], [马六, 张三], [李四, 钱二]]
[[李四, 钱二], [王五, 赵一], [张三, 马六]]
[[李四, 钱二], [王五, 赵一], [张三, 马六]]
聚类任务常用的一种评测手段是沿用分类任务的
F
1
F_1
F1,将一些人工分类好的文档去掉标签交给聚类分析器,统计结果中有多少同类别的文档属于同一个簇。具体计算公式如下:
P
(
i
,
j
)
=
n
i
j
n
j
R
(
i
,
j
)
=
n
i
j
n
i
F
1
(
i
,
j
)
=
2
×
P
(
i
,
j
)
×
R
(
i
,
j
)
P
(
i
,
j
)
+
R
(
i
,
j
)
n
i
j
n_{ij}
nij:表示簇j中属于类别
i
i
i的文档;
n
j
n_j
nj:表示簇
j
j
j中文档总数;
n
i
n_i
ni:表示类别
i
i
i中文档总数;
对整个评测任务而言,它的综合
F
1
F_1
F1是所有类目上分值的加权平均,如下公式所述:
F
1
=
∑
i
n
i
n
max
j
(
F
1
(
i
,
j
)
)
F_1 = \sum\limits_{i}\frac{n_i}{n}\max\limits_j(F_1(i, j))
F1=i∑nnijmax(F1(i,j))
其中
n
=
∑
i
n
i
n = \sum\limits_i n_i
n=i∑ni。
本次评测选择搜狗实验室提供的文本分类语料的一个子集,我称它为“搜狗文本分类语料库迷你版”。该迷你版语料库分为5个类目,每个类目下1000 篇文章,共计5000篇文章。运行代码如下:
# -*- coding:utf-8 -*-
from pyhanlp import *
from tests.demos.demo_text_classification import sogou_corpus_path
ClusterAnalyzer = JClass('com.hankcs.hanlp.mining.cluster.ClusterAnalyzer')
if __name__ == '__main__':
for algorithm in "kmeans", "repeated bisection":
print("%s F1=%.2f\n" % (algorithm, ClusterAnalyzer.evaluate(sogou_corpus_path, algorithm) * 100))
运行结果:
... 加载中... [教育]...100.00% 1000 篇文档 [汽车]...100.00% 1000 篇文档 [健康]...100.00% 1000 篇文档 [军事]...100.00% 1000 篇文档 [体育]...100.00% 1000 篇文档 耗时 13399 ms 加载了 5 个类目,共 5000 篇文档 kmeans聚类中...耗时 83538 ms 完毕。 kmeans F1=72.22 ... 加载中... [教育]...100.00% 1000 篇文档 [汽车]...100.00% 1000 篇文档 [健康]...100.00% 1000 篇文档 [军事]...100.00% 1000 篇文档 [体育]...100.00% 1000 篇文档 耗时 9857 ms 加载了 5 个类目,共 5000 篇文档 repeated bisection聚类中...耗时 45148 ms 完毕。 repeated bisection F1=80.40
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。