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是一种统计方法,用于评估一个词对于 ...
随机推荐
- qbittorrent搜索插件合集
qbittorrent搜索 qbittorrent搜索一个很有特色的功能: 这里收集整理了一些公开网站的插件(Plugins for Public sites),并连 源py文件一起分享. qbitt ...
- 并发编程--一堆锁,GIL,同步异步,Event事件
目录 一堆锁 死锁现象(*****) 递归锁 RLock (了解) 信号量 (了解) GIL(*****) 什么时GIL锁 为什么需要GIL锁 Cpython解释器与GC的问题 GIL锁带来的问题 多 ...
- jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jquery筛选方法
jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jq ...
- dubbo循序渐进 - 什么是RPC
RPC的核心并不在于使用什么协议.RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里.通过RPC能解耦服务,这才是使用RPC的真正目的.RPC的原理 ...
- Nginx中的break和last
rewrite中的break和last 两个指令用法相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的链接是否继续被nginx配置执行(主要是rewrite.return指令). 示 ...
- jQuery函数与对象(一)
一.jQuery函数jQuery函数的两种表现形式:1.jQuery()2.$()说明:在jQuery中使用jQuery()与$()是等价的,一般情况下均使用$() jQuery函数中可以存放的四种参 ...
- 文件转base64处理或转换blob对象链接
一.文件转base64,代码: axios({ method: 'get', url: apiPath.common.downloaddUrl, responseType: 'blob'}).then ...
- HTML5 新增文本标签
一.mark 标记文本 <mark> 标签定义带有记号的文本,表示页面中需要突出显示或高亮显示的信息. 通常在引用原文的时候使用 mark 元素,目的是引起当前用户的注意. 语法格式: & ...
- OCR6:Custom Traineddata
参考:https://groups.google.com/forum/#!msg/tesseract-ocr/MSYezIbckvs/kO1VoNKMDMQJ V4版本代码示例 : import py ...
- python中print用法
print用法 参考文档:https://blog.csdn.net/sinat_28576553/article/details/81154912 目录 一.print()函数概述 二.变量的输出 ...