[python] Kmeans文本聚类算法+PAC降维+Matplotlib显示聚类图像 – Eastmount的专栏 – 博客频道 – CSDN.NET

  • A+
所属分类:其他杂项
本文信息本文由方法SEO顾问发表于2016-06-1418:03:21,共 6543 字,转载请注明:[python] Kmeans文本聚类算法+PAC降维+Matplotlib显示聚类图像 – Eastmount的专栏 – 博客频道 – CSDN.NET_【方法SEO顾问】

0 前言

本文主要讲述以下几点:

        1.通过scikit-learn计算文本内容的tfidf并构造N*M矩阵(N个文档
M个特征词)

        2.调用scikit-learn中的K-means进行文本聚类;
        3.使用PAC进行降维处理,每行文本表示成两维数据;
        4.最后调用Matplotlib显示聚类效果图。
文章更详细的内容参考:http://blog.csdn.net/eastmount/article/details/50473675
由于涉及到了我的毕业设计,一些更深入的内容和详细的信息,我这里就不再详细叙述了,毕竟还要查重和未发表。但其中一些算法的实现步骤是很清晰的。
最后希望文章对你有所帮助,尤其是那些正在学习文本相似度计算或文本聚类的初学者。

1 输入
文本输入是读取本地的01_All_BHSpider_Content_Result.txt文件,里面包括1000行数据,其中001~400行为景区、401~600为动物、601~800为人物明星、801~1000为国家地理文本内容(百度百科摘要信息)。
该内容可以自定义爬虫进行爬取,同时分词采用Jieba进行。


免费下载包括代码py文件和01_All_BHSpider_Content_Result.txt。

下载地址:http://download.csdn.net/detail/eastmount/9410810

2 源代码

代码如下,详见注释和后面的学习笔记推荐:

[python] view plain copy

ico_fork.svg

  1. # coding=utf-8    
  2. """  
  3. Created on 2016-01-16 @author: Eastmount 
  4. 输入:打开 All_BHSpider_Result.txt 对应1000个文本 
  5.      001~400 5A景区 401~600 动物 601~800 人物 801~1000 国家 
  6. 输出:BHTfidf_Result.txt tfidf值 聚类图形 1000个类标 
  7. 参数:weight权重 这是一个重要参数 
  8. """    
  9.     
  10. import time            
  11. import re            
  12. import os    
  13. import sys  
  14. import codecs  
  15. import shutil  
  16. import numpy as np  
  17. import matplotlib  
  18. import scipy  
  19. import matplotlib.pyplot as plt  
  20. from sklearn import feature_extraction    
  21. from sklearn.feature_extraction.text import TfidfTransformer    
  22. from sklearn.feature_extraction.text import CountVectorizer  
  23. from sklearn.feature_extraction.text import HashingVectorizer   
  24.   
  25. if __name__ == "__main__":  
  26.       
  27.     #########################################################################  
  28.     #                           第一步 计算TFIDF  
  29.       
  30.     #文档预料 空格连接  
  31.     corpus = []  
  32.       
  33.     #读取预料 一行预料为一个文档  
  34.     for line in open('01_All_BHSpider_Content_Result.txt''r').readlines():  
  35.         #print line  
  36.         corpus.append(line.strip())  
  37.     #print corpus  
  38.   
  39.     #参考: http://blog.csdn.net/abcjennifer/article/details/23615947  
  40.     #vectorizer = HashingVectorizer(n_features = 4000)  
  41.       
  42.     #将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频  
  43.     vectorizer = CountVectorizer()  
  44.   
  45.     #该类会统计每个词语的tf-idf权值  
  46.     transformer = TfidfTransformer()  
  47.   
  48.     #第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵  
  49.     tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))  
  50.   
  51.     #获取词袋模型中的所有词语    
  52.     word = vectorizer.get_feature_names()  
  53.       
  54.     #将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重  
  55.     weight = tfidf.toarray()  
  56.   
  57.     #打印特征向量文本内容  
  58.     print 'Features length: ' + str(len(word))  
  59.     resName = "BHTfidf_Result.txt"  
  60.     result = codecs.open(resName, 'w''utf-8')  
  61.     for j in range(len(word)):  
  62.         result.write(word[j] + ' ')  
  63.     result.write('\r\n\r\n')  
  64.   
  65.     #打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重    
  66.     for i in range(len(weight)):  
  67.         #print u"-------这里输出第", i, u"类文本的词语tf-idf权重------"    
  68.         for j in range(len(word)):  
  69.             #print weight[i][j],  
  70.             result.write(str(weight[i][j]) + ' ')  
  71.         result.write('\r\n\r\n')  
  72.   
  73.     result.close()  
  74.   
  75.   
  76.     ########################################################################  
  77.     #                               第二步 聚类Kmeans  
  78.   
  79.     print 'Start Kmeans:'  
  80.     from sklearn.cluster import KMeans  
  81.     clf = KMeans(n_clusters=4)   #景区 动物 人物 国家  
  82.     s = clf.fit(weight)  
  83.     print s  
  84.   
  85.     ''''' 
  86.     print 'Start MiniBatchKmeans:' 
  87.     from sklearn.cluster import MiniBatchKMeans 
  88.     clf = MiniBatchKMeans(n_clusters=20) 
  89.     s = clf.fit(weight) 
  90.     print s 
  91.     '''  
  92.   
  93.     #中心点  
  94.     print(clf.cluster_centers_)  
  95.       
  96.     #每个样本所属的簇  
  97.     label = []               #存储1000个类标 4个类  
  98.     print(clf.labels_)  
  99.     i = 1  
  100.     while i <= len(clf.labels_):  
  101.         print i, clf.labels_[i-1]  
  102.         label.append(clf.labels_[i-1])  
  103.         i = i + 1  
  104.   
  105.     #用来评估簇的个数是否合适,距离越小说明簇分的越好,选取临界点的簇个数  958.137281791  
  106.     print(clf.inertia_)  
  107.   
  108.   
  109.     ########################################################################  
  110.     #                               第三步 图形输出 降维  
  111.   
  112.     from sklearn.decomposition import PCA  
  113.     pca = PCA(n_components=2)             #输出两维  
  114.     newData = pca.fit_transform(weight)   #载入N维  
  115.     print newData  
  116.   
  117.     #5A景区  
  118.     x1 = []  
  119.     y1 = []  
  120.     i=0  
  121.     while i<400:  
  122.         x1.append(newData[i][0])  
  123.         y1.append(newData[i][1])  
  124.         i += 1  
  125.   
  126.     #动物  
  127.     x2 = []  
  128.     y2 = []  
  129.     i = 400  
  130.     while i<600:  
  131.         x2.append(newData[i][0])  
  132.         y2.append(newData[i][1])  
  133.         i += 1  
  134.   
  135.     #人物  
  136.     x3 = []  
  137.     y3 = []  
  138.     i = 600  
  139.     while i<800:  
  140.         x3.append(newData[i][0])  
  141.         y3.append(newData[i][1])  
  142.         i += 1  
  143.   
  144.     #国家  
  145.     x4 = []  
  146.     y4 = []  
  147.     i = 800  
  148.     while i<1000:  
  149.         x4.append(newData[i][0])  
  150.         y4.append(newData[i][1])  
  151.         i += 1  
  152.   
  153.     #四种颜色 红 绿 蓝 黑  
  154.     plt.plot(x1, y1, 'or')  
  155.     plt.plot(x2, y2, 'og')  
  156.     plt.plot(x3, y3, 'ob')  
  157.     plt.plot(x4, y4, 'ok')  
  158.     plt.show()  
  159.       

3 输出结果

采用Kmeans中设置类簇数为4,分别表示景区、动物、明星和国家。

其中运行结果如下图所示,包括17900维tfidf特征向量:

聚类输出结果如下图所示:其中"红-景区 绿-动物 蓝-人物 黑-国家"。由于数据集比较小,文本聚类效果还是很明显的,而LDA算法是计算每个主题分布的算法,推荐你也去学习下。

4 性能评估

这里我想结合文本聚类简单叙述下最常用的评估方法

        正确率 Precision = 正确识别的个体总数 /  识别出的个体总数

        召回率 Recall = 正确识别的个体总数 /  测试集中存在的个体总数

        F值 F-measure = 正确率 * 召回率 * 2 / (正确率 + 召回率)

由于"clf.labels_"会返回聚类每个样本所属的簇,比如1000行数据,就会返回1000个label值。同时,clf = KMeans(n_clusters=4)设置了类簇为4,故每个值对应在0、1、2、3中的一个,统计结果如下:

其中以世界国家为例,label1数目为198,同时识别出的个体数=198(世界国家)+2(动物)=200,故:
        准确率=198/200=0.990
其中动物里面有两个聚类到了世界国家中。而召回率我以人物明星为例,因为知道测试集中601~800这200个数据对应人物明星,故测试集中存在个体数为200,而正确识别数目为185个,故:
        召回率=185/200=0.925
最后计算F值即可。同时可以计算宏平均聚类准确率(Macro-Prec)和宏平均召回率(Macro-Rec)。

5 总结及推荐学习资料

代码中有几个问题我没有实现,包括:

        (1) 使用HashingVectorizer(n_features = n)设置维数,如何选择更合理的特征;

        (2) 调用plt.legend([plot1, plot2, plot3, plot4], (u'景区', u'动物', u'明星', u'国家') )

报错"AttributeError: 'NoneType' object has no attribute 'tk'";

        (3) sklearn其它聚类算法以及设置聚类中心点。

但是对那些刚接触Python聚类算法的同学 ,这篇文章还是有一定帮助的!同时也是我自己的在线笔记,仅仅提供了一条基础介绍,希望你能从这篇文章入门,从而实现你自己做的东西。最近总是深夜编码,生活太忙太充实,写篇博客放松下心情也不错~

最后推荐一些相关资料:

        用Python开始机器学习(10:聚类算法之K均值)
-lsldd大神

        应用scikit-learn做文本分类(特征提取
KNN SVM 聚类) - Rachel-Zhang大神
 

        Scikit
Learn: 在python中机器学习(KNN SVMs K均) - yyliu大神 开源中国

       【机器学习实验】scikit-learn的主要模块和基本使用
- JasonDing大神

        Scikit-learn学习笔记
中文简介(P30-Cluster) - 百度文库
 

        使用sklearn做kmeans聚类分析
- xiaolitnt

        使用sklearn
+ jieba中文分词构建文本分类器 - MANYU GOU大神

        sklearn学习(1)
数据集(官方数据集使用) - yuanyu5237大神

        scikit-learn使用笔记与sign
prediction简单小结 - xupeizhi

        http://scikit-learn.org/stable/modules/clustering.html#clustering

        基于K-Means的文本聚类(强推基础介绍)
- freesum

        Python图表绘制:matplotlib绘图库入门 - 360图书

        Stanford机器学习---第十讲. 数据降维 - Rachel-Zhang大神

        聚类算法初探(七)聚类分析的效果评测 - 皮果提大神

        python使用matplotlib绘图 -- barChart

        Python-Matplotlib安装及简单使用 (绘制柱状图)

        scikit-learn中PCA的使用方法 - wphh (推荐阅读)

        使用 PCA 进行降维处理——基于 sklearn 库 - Guo'Blog

(By:Eastmount 2016-01-20 深夜5点   http://blog.csdn.net//eastmount/ )

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: