Kmeans文档聚类算法实现之python
实现文档聚类的总体思想:
- 将每个文档的关键词提取,形成一个关键词集合N;
- 将每个文档向量化,可以参看计算余弦相似度那一章;
- 给定K个聚类中心,使用Kmeans算法处理向量;
- 分析每个聚类中心的相关文档,可以得出最大的类或者最小的类等;
将已经分好词的文档提取关键词,统计词频:
# 计算每个文档的关键词和词频
# 关键词统计和词频统计,以列表形式返回
def Count(resfile):
t = {}
infile = open(resfile, 'r', encoding='utf-8')
i = 0
f = infile.readlines()
count = len(f)
# print(count)
infile.close()
s = open(resfile, 'r', encoding='utf-8')
while i < count:
line = s.readline()
line = line.rstrip('\n')
# print(line)
words = line.split(" ")
# print(words)
for word in words:
if word != "" and t.__contains__(word):
num = t[word]
t[word] = num + 1
elif word != "":
t[word] = 1
i = i + 1
# 按键值降序
dic = sorted(t.items(), key=lambda t: t[1], reverse=True)
s.close()
# 返回的是一篇文档的词项统计表,形式为[(word:出现次数)]
return dic
上面的count函数统计的一篇文档的词频,如果每篇文档都需要统计则需要调用这个count函数,每调用一次就返回一个dict,给一个文档集统计词频的参考代码如下(假设有500篇文档):
def readfile():
f = open("res.txt", "w", encoding="utf-8")
# mergeword 用来记录所有文档的词项集合,不重复,其长度是用来作为文档向量维度
mergeword = []
everyDocumentDict = []
for i in range(500):
filedir = "D:/PythonCodingLover/PythonPro/DailyStudy/互联网项目二/CNS/"+ "CNS" +str(i)+"_C.txt"
# 将每个文档的字典写入res.txt中
dict = Count(filedir)
# everyDocumentDict记录的是每篇文档的词项统计
everyDocumentDict.append(dict)
# print(type(dict))
for j in range(len(dict)):
if dict[j][0] not in mergeword:
mergeword.append(dict[j][0]) f.close()
# 返回文档集的词项集
return mergeword,everyDocumentDict
上面两部分可以实现将文档集里的关键词,担心是否正确可以使用简单的测试代码,如下:
# 测试文档集关键词是否正确
mergeword ,eveKeywordOfCount= readfile()
print(type(eveKeywordOfCount))
print(len(eveKeywordOfCount))
print(len(mergeword))
将每篇文档向量化,便于后面的文档聚类:
下面这个函数将所有的文档向量一起返回,而不是一篇文档向量;
# 现在有了500个文档的总关键词和每篇文档的词项统计,所以我们现在要做的是将每篇文档向量化,维度是len(mergeword)
# 注意EveDocCount的结构是[[(),()],[(),()]],里面记录的列表是每个文档的词项统计,而括号里面的是keyword:词频 print("-------------------文档向量化开始操作-----------------")
def VectorEveryDoc(EveDocCount,mergeword):
# vecOfDoc列表记录的是每篇文档向量化后的向量列表,共有500个元素
vecOfDoc = []
# vecDoc列表记录的是一篇文档的向量模型,向量化后添加到vecOfDoc
vectorLenth = len(mergeword)
# 下面开始将500文档向量化
i = 0 while i < 500:
# EveDocCount[i]记录的是第几篇文档的词项统计
vecDoc = [0] * vectorLenth
# 测试是正确的
# print(EveDocCount[i])
for ch in range(len(EveDocCount[i])):
# termFrequence 是词项对应的频数
termFrequence = EveDocCount[i][ch][1]
# keyword是词项
keyword = EveDocCount[i][ch][0]
# 下面开始具体的向量化
j = 0
while j < vectorLenth:
if keyword == mergeword[j]:
# 这里是J 而不是 I ,写错了就很容易出错了
vecDoc[j] = termFrequence
break
else:
j = j + 1
vecOfDoc.append(vecDoc)
i = i+ 1
# 返回500个文档的文档向量
return vecOfDoc print("-------------------文档向量化操作结束-----------------")
向量化结束之后,便需要计算余弦距离(也可以使用其他距离,例如欧几里得距离):
说明:一个文档集的关键词可能有很多,为了方便后面的计算,引入科学计算包numpy,示例代码如下:
# 导入科学计算包
import numpy as np
而后将500个文档向量传给numpy的数组,构造矩阵,示例代码如下:
resultVec = VectorEveryDoc(eveKeywordOfCount,mergeword)
vecDate = np.array(resultVec)
之后便计算余弦相似度,这里和前面写的余弦距离相似度计算类似,不同的是使用了nmupy数组,注意其中的矩阵乘法,示例代码如下:
# 计算余弦距离
def CalConDis(v1,v2):
lengthVector = len(v1)
# 计算出两个向量的乘积
# 将v2变换,转置矩阵v2
v2s =v2.T
B = np.dot(v1,v2s)
# 计算两个向量的模的乘积
v1s = v1.T
A1 = np.dot(v1,v1s)
A2 = np.dot(v2,v2s)
A = math.sqrt(A1) * math.sqrt(A2)
# print('相似度 = ' + str(float(B) / A))
resdis = format(float(B) / A,".3f")
return float(resdis)
Kmeans聚类算法实现文档聚类:
随机产生K个聚类中心点:
# 随机选取中心点,dateSet是m * n矩阵,K是要指定的聚类的个数
def createRandomCent(dateSet,k):
# 返回整个矩阵的列的列数
n = np.shape(dateSet)[1]
# 创建一个k * n 的零矩阵
centroids = np.mat(np.zeros((k, n)))
# 随机产生k个中心点
for j in range(n):
minJ = min(dateSet[:, j])
rangeJ = float(max(dateSet[:, j]) - minJ)
centroids[:, j] = np.mat(minJ + rangeJ * np.random.rand(k, 1))
# 返回随机产生的k个中心点
return centroids
Kmeans算法按照随机产生的聚类中心开始聚类,返回的一个矩阵:
countclu = 1
# 具体的Kmeans算法实现
# dateset是指500个文档的向量集合(500 * length),dis用的是余弦距离,k是给定的k个聚类中心,createCent是随机生成的K个初始中心
def dfdocKmeansCluster(dateset,k,discos = CalConDis,createCent = createRandomCent):
# docCount 记录的总共有多少个样本,既矩阵的行数
docCount = np.shape(dateset)[0]
# 在构建一个500 * 2的0矩阵,用来存放聚类信息
docCluster = np.mat(np.zeros((docCount,2))) # 初始化K个聚类中心
centerOfCluster = createCent(dateset,k)
# clusterFlag用来判定聚类是否结束
clusterFlag = True
while clusterFlag:
clusterFlag = False
for each in range(docCount):
# 将最大余弦距离初始化成一个负数
maxCosDis = -100
# 文档索引
minIndex = -1
# 找到每篇文档距离最近的中心
for i in range(k):
# 计算每个文档到中心点的余弦相似度,
global countclu
countclu = countclu+ 1
print("已经聚类第" + str(countclu) + "次")
distcosOfDocToDoccenter = discos(centerOfCluster[i, :], dateset[each, :])
# 选择余弦距离最大的一个中心
if distcosOfDocToDoccenter > maxCosDis: maxCosDis = distcosOfDocToDoccenter
minIndex = i
if docCluster[each, 0] != minIndex:
# 如果没到最优方案则继续聚类
clusterFlag = True
# 第1列为所属中心,第2列为余弦距离
docCluster[each, :] = minIndex, maxCosDis
# 打印随机产生的中心点
print(centerOfCluster) # 更改聚类中心点
for cent in range(k):
ptsInClust = dateset[np.nonzero(docCluster[:, 0].A == cent)[0]]
centerOfCluster[cent, :] = np.mean(ptsInClust, axis=0)
# 返回K个中心点,
return centerOfCluster,docCluster
这里返回的一个500*2的矩阵,第一列是聚类中心,第二列是和中心的余弦距离,索引就是文档编号;
如果需要得出具体的类有几篇文档等问题,则需要对返回的矩阵进行分析(注意是numpy矩阵);
程序到了这里。就基本上结束了;
Kmeans文档聚类算法实现之python的更多相关文章
- 相似文档查找算法之 simHash 简介及其 java 实现 - leejun_2005的个人页面 - 开源中国社区
相似文档查找算法之 simHash 简介及其 java 实现 - leejun_2005的个人页面 - 开源中国社区 相似文档查找算法之 simHash 简介及其 java 实现
- AutoPy首页、文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区
AutoPy首页.文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区 AutoPy是一个简单跨平台的 Python GUI工具包,可以控制鼠标,键盘,匹配颜色和屏幕上的位图.使用纯A ...
- k-means和iosdata聚类算法在生活案例中的运用
引言:聚类是将数据分成类或者簇的过程,从而使同簇的对象之间具有很高的相似度,而不同的簇的对象相似度则存在差异.聚类技术是一种迭代重定位技术,在我们的生活中也得到了广泛的运用,比如:零件分组.数据评价. ...
- 【机器学习】:Kmeans均值聚类算法原理(附带Python代码实现)
这个算法中文名为k均值聚类算法,首先我们在二维的特殊条件下讨论其实现的过程,方便大家理解. 第一步.随机生成质心 由于这是一个无监督学习的算法,因此我们首先在一个二维的坐标轴下随机给定一堆点,并随即给 ...
- 用Python做SVD文档聚类---奇异值分解----文档相似性----LSI(潜在语义分析)
转载请注明出处:电子科技大学EClab——落叶花开http://www.cnblogs.com/nlp-yekai/p/3848528.html SVD,即奇异值分解,在自然语言处理中,用来做潜在语义 ...
- (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现
前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...
- 聚类算法总结以及python代码实现
一.聚类(无监督)的目标 使同一类对象的相似度尽可能地大:不同类对象之间的相似度尽可能地小. 二.层次聚类 层次聚类算法实际上分为两类:自上而下或自下而上.自下而上的算法在一开始就将每个数据点视为一个 ...
- 相似文档查找算法之 simHash及其 java 实现
传统的 hash 算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法.产生的两个签名,如果相等,说明原始内容在一定概 率 下是相等的:如果不相等,除了说明原始内容不相等外 ...
- TF-IDF词频逆文档频率算法
一.简介 1.RF-IDF[term frequency-inverse document frequency]是一种用于检索与探究的常用加权技术. 2.TF-IDF是一种统计方法,用于评估一个词对于 ...
随机推荐
- C#读写设置修改调整UVC摄像头画面-焦点
有时,我们需要在C#代码中对摄像头的焦点进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...
- Web API 授权筛选器
方式一.全局认证 public static class WebApiConfig { public static void Register(HttpConfiguration config) { ...
- [译] Ruby如何访问Excel文件
Parsing Excel Files with Ruby BY: MATT NEDRICH 翻译:佣工7001 本文中,我将会评判几种Ruby语言访问Excel文件的库.我将要讨论针对不同格式 ...
- Elasticsearch 、 Logstash以及Kibana 分布式日志
搭建ELK日志分析平台(上)—— ELK介绍及搭建 Elasticsearch 分布式集群 ELK简介: ELK是三个开源软件的缩写,分别为:Elasticsearch . Logstash以及Kib ...
- mockjs的基本使用入门
相信很多前端同学都有一个困扰,就是没有后端数据的情况下感觉很多想法都不能动手去实现,这里介绍一个模拟后端数据的工具,可以一定程度上解决我们的困扰. 很多人或多或少的都听说过mockjs,都知道是一个模 ...
- iOS UILanel 一些小实用
UILabel *lab=[[UILabel alloc]initWithFrame:self.view.bounds]; //合并 lab.text=[NSString stringWithForm ...
- sparkContext的初始化过程
SparkContext 初始化的过程主要的核心:1) 依据 SparkContext 的构造方法中的参数 SparkConf 创建一个SparkEnv2) 初始化,Spark UI,以便 Spark ...
- FFMPEG 命令行工具- ffplay
ffplay 简介 ffplay是ffmpeg工程中提供的播放器,功能相当的强大,凡是ffmpeg支持的视音频格式它基本上都支持.甚至连VLC不支持的一些流媒体都可以播放,但是它的缺点是其不是图形化界 ...
- python之提升程序性能的解决方案
Python在性能方面不卓越,但是使用一些小技巧,可以提高Python程序的性能,避免不必要的资源浪费. 1. 使用局部变量 尽可能使用局部变量替代全局变量,可以是程序易于维护并且有助于提高性能节约成 ...
- go build -tags 的使用
go build 使用tag来实现编译不同的文件 go-tooling-workshop 中关于go build的讲解可以了解到go bulid的一些用法,这篇文章最后要求实现一个根据go bulid ...