实现文档聚类的总体思想:

  1. 将每个文档的关键词提取,形成一个关键词集合N;
  2. 将每个文档向量化,可以参看计算余弦相似度那一章;
  3. 给定K个聚类中心,使用Kmeans算法处理向量;
  4. 分析每个聚类中心的相关文档,可以得出最大的类或者最小的类等;

将已经分好词的文档提取关键词,统计词频:

# 计算每个文档的关键词和词频
# 关键词统计和词频统计,以列表形式返回
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的更多相关文章

  1. 相似文档查找算法之 simHash 简介及其 java 实现 - leejun_2005的个人页面 - 开源中国社区

    相似文档查找算法之 simHash 简介及其 java 实现 - leejun_2005的个人页面 - 开源中国社区 相似文档查找算法之 simHash 简介及其 java 实现

  2. AutoPy首页、文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区

    AutoPy首页.文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区 AutoPy是一个简单跨平台的 Python GUI工具包,可以控制鼠标,键盘,匹配颜色和屏幕上的位图.使用纯A ...

  3. k-means和iosdata聚类算法在生活案例中的运用

    引言:聚类是将数据分成类或者簇的过程,从而使同簇的对象之间具有很高的相似度,而不同的簇的对象相似度则存在差异.聚类技术是一种迭代重定位技术,在我们的生活中也得到了广泛的运用,比如:零件分组.数据评价. ...

  4. 【机器学习】:Kmeans均值聚类算法原理(附带Python代码实现)

    这个算法中文名为k均值聚类算法,首先我们在二维的特殊条件下讨论其实现的过程,方便大家理解. 第一步.随机生成质心 由于这是一个无监督学习的算法,因此我们首先在一个二维的坐标轴下随机给定一堆点,并随即给 ...

  5. 用Python做SVD文档聚类---奇异值分解----文档相似性----LSI(潜在语义分析)

    转载请注明出处:电子科技大学EClab——落叶花开http://www.cnblogs.com/nlp-yekai/p/3848528.html SVD,即奇异值分解,在自然语言处理中,用来做潜在语义 ...

  6. (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现

    前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...

  7. 聚类算法总结以及python代码实现

    一.聚类(无监督)的目标 使同一类对象的相似度尽可能地大:不同类对象之间的相似度尽可能地小. 二.层次聚类 层次聚类算法实际上分为两类:自上而下或自下而上.自下而上的算法在一开始就将每个数据点视为一个 ...

  8. 相似文档查找算法之 simHash及其 java 实现

    传统的 hash 算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法.产生的两个签名,如果相等,说明原始内容在一定概 率 下是相等的:如果不相等,除了说明原始内容不相等外 ...

  9. TF-IDF词频逆文档频率算法

    一.简介 1.RF-IDF[term frequency-inverse document frequency]是一种用于检索与探究的常用加权技术. 2.TF-IDF是一种统计方法,用于评估一个词对于 ...

随机推荐

  1. Web负载均衡学习笔记之K8S内Ngnix微服务服务超时问题

    0x00 概述 本文是从K8S内微服务的角度讨论Nginx超时的问题 0x01 问题 在K8S内部署微服务后,发现部分微服务链接超时,Connection Time Out. 最近碰到了一个 Ngin ...

  2. HTML+CSS+JS综合练习(动态验证版)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Entity Framework 学习系列(1) - 认识理解Entity Framework

    目录 写在前面 什么是Entity Framework EF的优缺点 1.优点 2.缺点 如何理解ORM EF执行的原理 写在前面 在使用.net mvc 开发的时候.为了高效的开发,我们常常会搭配O ...

  4. vs2012新建单元测试

    多写单元测试也是算向优秀程序员迈进吧((ˇˍˇ)),就像我们小时候做算算术一样,老师会交给我们怎么样检验答案是否正确性.那么我们做程序员也一样,检验自己写的代码是否和我们预期的结果一样!项目小还行,但 ...

  5. linux学习-防火墙指令

    Redhat7之前的版本(iptables) 开启关闭防火墙 放行端口 RedHat7防火墙相关的指令(firewall-cmd) 安装firewall 本文内容适用于 redhat 和 centos ...

  6. Nginx配置单项SSL以及双向SSL

    Https安全协议的由来? 在实现 HTTPS协议前,我们需要了解 SSL 协议,但其实我们现在使用的更多的是 TLS 加密通讯协议. 那么TLS是怎么保证明文消息被加密的呢?在OSI七层模型中,应用 ...

  7. [echart] webpack中安装和使用

    安装echart npm install echarts --save 全量引入 可以直接在项目代码中 require('echarts') 得到 ECharts. 官方示例 var echarts ...

  8. Qt Graphics-View的打印功能实现

    本文来研究一下Qt Graphics-View的打印功能实现. 在Qt的官方文档中介绍了Graphics-View的打印相关内容. Qt中对打印的支持是有一个独立的printsupport模块来完成的 ...

  9. consul:健康检查

    官方文档:https://www.consul.io/docs/agent/checks.html consul提供的健康检查有以下几种: 1.script+interval 2.http+inter ...

  10. jsp 获取后端配置文件.properties的某个配置内容

    如后端有个叫做config.properties的配置文件: sys.img=st_sp jsp中引用的方式是: <%@ page language="java" impor ...