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

  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. vs2017专业版和企业版的密钥

    Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH

  2. Visual Studio的语法着色终于调得赏心悦目

    代码可读性瞬间大大提升.Reshaper真的强大.

  3. 【转载】Jupyter Notebook 常用快捷键

    原文:http://blog.csdn.net/lawme/article/details/51034543 Jupyter Notebook 有两种键盘输入模式.编辑模式,允许你往单元中键入代码或文 ...

  4. Spring MVC异常友好展示

    官网 https://docs.spring.io/spring/docs/4.3.25.RELEASE/spring-framework-reference/htmlsingle/ Springmv ...

  5. iOS架构:MVVM设计模式+RAC响应式编程

    https://cloud.tencent.com/developer/article/1117009 一:为什么要用MVVM? 为什么要用MVVM?只是因为它不会让我时常懵逼. 每次做完项目过后,都 ...

  6. JavaWeb第二天--CSS

    CSS CSS简述 CSS是什么?有什么作用? CSS(Cascading Style Sheets):层叠样式表. CSS通常称为CSS样式或层叠样式表.主要用于设置HTML页面中的文本内容(字体. ...

  7. odex vdex art区别

    一.vdexpackage 直接转化的 可执行二进制码 文件:1.第一次开机就会生成在/system/app/<packagename>/oat/下:2.在系统运行过程中,虚拟机将其 从 ...

  8. VirtualDub在处理WMV文件时显示“MISSING CODEC”怎么办

    以下内容主要来自:http://www.brilliantcode.com/virtualdub-is-showing-missing-codec-when-i-play-a-wmv-movie-ev ...

  9. 不知道密码情况下 进行docker数据库可视化连接

    1. 通过命令 docker inpect mysql容器id ,查询mysql容器的密码和绑定的端口号 2.通过vscode插件或者navicat等可视化工具,进行连接即可. 有问题请进群联系我,或 ...

  10. H3C FAT AP