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进行。
代码如下,详见注释和后面的学习笔记推荐:
# coding=utf-8 """ Created on 2016-01-16 @author: Eastmount 输入:打开 All_BHSpider_Result.txt 对应1000个文本 001~400 5A景区 401~600 动物 601~800 人物 801~1000 国家 输出:BHTfidf_Result.txt tfidf值 聚类图形 1000个类标 参数:weight权重 这是一个重要参数 """ import time import re import os import sys import codecs import shutil import numpy as np import matplotlib import scipy import matplotlib.pyplot as plt from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfTransformer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import HashingVectorizer if __name__ == "__main__": ######################################################################### # 第一步 计算TFIDF #文档预料 空格连接 corpus = [] #读取预料 一行预料为一个文档 for line in open('01_All_BHSpider_Content_Result.txt', 'r').readlines(): #print line corpus.append(line.strip()) #print corpus #参考: http://blog.csdn.net/abcjennifer/article/details/23615947 #vectorizer = HashingVectorizer(n_features = 4000) #将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频 vectorizer = CountVectorizer() #该类会统计每个词语的tf-idf权值 transformer = TfidfTransformer() #第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵 tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) #获取词袋模型中的所有词语 word = vectorizer.get_feature_names() #将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重 weight = tfidf.toarray() #打印特征向量文本内容 print 'Features length: ' + str(len(word)) resName = "BHTfidf_Result.txt" result = codecs.open(resName, 'w', 'utf-8') for j in range(len(word)): result.write(word[j] + ' ') result.write('\r\n\r\n') #打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重 for i in range(len(weight)): #print u"-------这里输出第", i, u"类文本的词语tf-idf权重------" for j in range(len(word)): #print weight[i][j], result.write(str(weight[i][j]) + ' ') result.write('\r\n\r\n') result.close() ######################################################################## # 第二步 聚类Kmeans print 'Start Kmeans:' from sklearn.cluster import KMeans clf = KMeans(n_clusters=4) #景区 动物 人物 国家 s = clf.fit(weight) print s ''' print 'Start MiniBatchKmeans:' from sklearn.cluster import MiniBatchKMeans clf = MiniBatchKMeans(n_clusters=20) s = clf.fit(weight) print s ''' #中心点 print(clf.cluster_centers_) #每个样本所属的簇 label = [] #存储1000个类标 4个类 print(clf.labels_) i = 1 while i <= len(clf.labels_): print i, clf.labels_[i-1] label.append(clf.labels_[i-1]) i = i + 1 #用来评估簇的个数是否合适,距离越小说明簇分的越好,选取临界点的簇个数 958.137281791 print(clf.inertia_) ######################################################################## # 第三步 图形输出 降维 from sklearn.decomposition import PCA pca = PCA(n_components=2) #输出两维 newData = pca.fit_transform(weight) #载入N维 print newData #5A景区 x1 = [] y1 = [] i=0 while i<400: x1.append(newData[i][0]) y1.append(newData[i][1]) i += 1 #动物 x2 = [] y2 = [] i = 400 while i<600: x2.append(newData[i][0]) y2.append(newData[i][1]) i += 1 #人物 x3 = [] y3 = [] i = 600 while i<800: x3.append(newData[i][0]) y3.append(newData[i][1]) i += 1 #国家 x4 = [] y4 = [] i = 800 while i<1000: x4.append(newData[i][0]) y4.append(newData[i][1]) i += 1 #四种颜色 红 绿 蓝 黑 plt.plot(x1, y1, 'or') plt.plot(x2, y2, 'og') plt.plot(x3, y3, 'ob') plt.plot(x4, y4, 'ok') plt.show()
其中以世界国家为例,label1数目为198,同时识别出的个体数=198(世界国家)+2(动物)=200,故:
准确率=198/200=0.990
其中动物里面有两个聚类到了世界国家中。而召回率我以人物明星为例,因为知道测试集中601~800这200个数据对应人物明星,故测试集中存在个体数为200,而正确识别数目为185个,故:
召回率=185/200=0.925
最后计算F值即可。同时可以计算宏平均聚类准确率(Macro-Prec)和宏平均召回率(Macro-Rec)。
5 总结及推荐学习资料