又是Kmeans, 这次是文章聚类

基本想法是把本博客的所有文章重新分个类, 感觉博客内容有点多了 , 人工标注时有些文章放在那个类里面不太好决定, 想看看 文章聚类算法的结果如何.

首先,博客的内容,已经被爬下来了,放在mongodb中 . 其次,利用python 的jieba分词 , 可以很容易的实现分词功能. 得到每篇文章的词频表 , 在每篇文章词频表的基础上汇总得到所有文章的词频表. 在词频表中把出现频率非常高的词列为停用词去掉. 然后对每篇文章构建一个词频向量. 以此向量为基础 , 利用R的kmeans来对文章进行聚类.

先说下大致情况,
一共644篇文章, 共出现14765个词,其中包含了一些没有去掉的数字. 前20高频词为:
函数 : 587
需要 : 419
文件 : 380
数据 : 301
没有 : 299
调用 : 242
参数 : 238
wordpress : 219
定义 : 217
php : 212
使用 : 203
页面 : 201
利用 : 200
问题 : 199
gl : 190
代码 : 190
每个 : 185
直接 : 182
方法 : 179
r : 175

生成的文档矩阵大小为644×14765 , 将这个矩阵读入R , 然后调用kmeans函数, 将文章分为15类:
R调用为:

res=kmeans(docMatrix, 15 , 200 , 10) 
>res
...
Within cluster sum of squares by cluster:
 [1]      0.000 114627.551  52850.277   4285.333   4923.500      0.000
 [7]      0.000      0.000      0.000      0.000   2639.500      0.000
[13]   9093.200  10609.077      0.000
 (between_SS / total_SS =  43.3 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      
> table(res$cluster)

  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 
  1 535  65   3   8   1   1   1   1   1   2   1  10  13   1 

从table(res$cluster)可以看出, 虽然我打算把文章分为15类,但是其中就有8个类只有一篇文章, 而有一个类的文章数达到了535篇, 基于这个结果, 感觉文章基本上没有被分开. 而上面的within cluster SS , 看到有些类里面的SS是零(一篇文章的类) , 有些类的SS则非常大. 需要进一步的去看到底kmeans干了些什么, 什么时候迭代结束.

这里可能的问题, 分类的个数的问题, 15只是一个随便选取的个数, 也许会有其他的分类数更好. 关于聚类的优度定义为组间平方和/总的平方和. 即 res$betweenss/res$totss , 这个值越接近于1, 表明组内成员越相近. 我们试着把分类数扩大到500 , 看看那个分类数的优度最高. R代码如下:

results=data.frame(gp=NULL,res=NULL)
for( k in seq(60,500,10)){
        print(k)
    res=kmeans(dd,center=k)
        rt = res$betweenss/res$totss
    results=rbind(results,list(gp=k,res=rt))
}

接下来等结果:



本文地址: http://www.bagualu.net/wordpress/archives/5094 转载请注明




发表评论

电子邮件地址不会被公开。 必填项已用*标注