分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开

docker/kubernetes入门视频教程


全栈工程师开发手册 (作者:栾鹏)
python数据挖掘系列教程

本文使用层次聚类为文档进行分组,层次聚类为不给定聚类数目的情况下对数据对象进行聚类。形成一个对聚类二叉树。每个树节点的左右子树都具有最佳相似性。

层次聚类算法

层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法,本篇文章介绍合并方法。

层次聚类的合并算法AGNES(凝聚算法)

层次聚类的合并算法通过计算两类数据点间的相似性,对所有数据点中最为相似的两个数据点进行组合,并反复迭代这一过程。简单的说层次聚类的合并算法是通过计算每一个类别的数据点与所有数据点之间的距离来确定它们之间的相似性,距离越小,相似度越高。并将距离最近的两个数据点或类别进行组合,生成聚类树。

而当两个数据点进行组合成后,用一个新的代表点,替换原有的两个数据点,再进行下次组合。

其中距离的计算可以使用曼哈顿距离、欧几里得或者皮尔徐相似度进行计算。

距离的度量包含四种方式:
(1)最小距离(单链(MIN)):定义簇的邻近度为不同两个簇的两个最近的点之间的距离。
(2)最大距离(全链(MAX)):定义簇的邻近度为不同两个簇的两个最远的点之间的距离。
(3)平均距离(组平均):定义簇的邻近度为取自两个不同簇的所有点对邻近度的平均值。
(4)均值距离(Ward 方法的接近函数):质心方法通过计算集群的质心之间的距离来计算两个簇的接近度。对于 Ward 方法来说,两个簇的接近度指的是当两个簇合并时产生的平方误差的增量。

这里我们使用两个数据点的中心位置替换原有数据点。

当然除了凝聚的层次聚类,还有分裂的层次聚类算法DIANA,过程与凝聚的算法相反。

层次聚类树状图

将前面的每一步的计算结果以树状图的形式展现出来就是层次聚类树。最底层是原始A到G的7个数据点。依照7个数据点间的相似度组合为聚类树的第二层(A,F),(B,C),(D,E)和G。以此类推生成完整的层次聚类树状图。以下为简单的示意图。

加载数据集

使用我们一贯的文本数据集结构。每行为一个文档(链接或者文档名),每列为一个文档特征(单词),每个单元格的取值为单词在文档中出现的次数。

博客数据集点击下载

Blog     china   kids    music   yahoo   want    ...
Wonkette    0       2       1       0       6       ...
Publishing  2       0       0       7       4       ...
...         ...     ...     ...     ...     ...     ...

代码完成加载数据集,获取列名,行名,样本数据集

# 读取表格型数据,获取特征数据集。
def readfile(filename):lines=[line for line in open(filename)]# 第一行是列标题colnames=lines[0].strip().split('\t')[1:]rownames=[]data=[]for line in lines[1:]:p=line.strip().split('\t')# 每行的第一列是行名rownames.append(p[0])# 剩余部分就是该行对应的数据onerow = [float(x) for x in p[1:]]data.append(onerow)return rownames,colnames,data

层次聚类构建聚类树

层次聚类构建决策树的过程:

1、将每个样本点都初始化为一个独立的聚类
2、计算数据集中每两个聚类之间的相似度,寻找最相似的两个聚类
3、将最相似的两个聚类化为一个聚类,即用两个聚类的均值点做为新聚类替换原有的两个聚类。
4、重复2、3直到只剩下一个聚类。

这样最后形成的聚类树,每个聚类下都包含左右子聚类。聚类树的叶子节点就是由样本对象初始化来的样本点聚类。

我们先来创建聚类的面向对象类

每个聚类都包含左右子聚类,以及代表此聚类的中心点。另外我们还添加了聚类的id代表聚类在聚类树中的深度,以及左右子聚类的相似度的值。

决策树就是根节点这个聚类。

# 定义一个聚类,包含左右子聚类。
class bicluster:def __init__(self,vec,left=None,right=None,distance=0.0,id=None):self.left=left    #左子聚类self.right=right  #右子聚类self.vec=vec      #聚类的中心点self.id=id        #聚类的idself.distance=distance  #左右子聚类间的距离(相似度)

计算每个聚类点之间的相似度。

构建了聚类的类型,我们还要能计算两个聚类的相似度。我们知道每个聚类都有一个代表该聚类的中心点,我们通过两个聚类的中心点,计算两个聚类的相似度。

在推荐和匹配一章中,我们使用欧氏距离和皮尔逊相似度为例对两个影评者的相似度进行计算。在文本聚类中,一些博客比其他博客的文章更长一些,包含更多的文章单词。皮尔逊相似度是判断两个数组与一条直线的拟合程度,因此更适合对两个不同长度的数组进行计算。(两个数组的长度其实是相同的,只是两个数值包含非0值的长度是不同的)

我们使用皮尔逊相似度计算两个中心点的相似度。

# 计算两行的皮尔逊相似度
def pearson(v1,v2):# 简单求和sum1=sum(v1)sum2=sum(v2)# 求平方和sum1Sq=sum([pow(v,2) for v in v1])sum2Sq=sum([pow(v,2) for v in v2])# 求乘积之和pSum=sum([v1[i]*v2[i] for i in range(len(v1))])# 计算rnum=pSum-(sum1*sum2/len(v1))den=sqrt((sum1Sq-pow(sum1,2)/len(v1))*(sum2Sq-pow(sum2,2)/len(v1)))if den==0: return 0return 1.0-num/den

下面我们就来构建决策树,获取决策树的根节点。

# 根据数据集形成聚类树
def hcluster(rows,distance=pearson):distance_set={}currentclustid=-1# 最开始聚类就是数据集中的行,每行一个聚类clust=[bicluster(rows[i],id=i) for i in range(len(rows))]   #原始集合中的聚类都设置了不同的正数id,(使用正数是为了标记这是一个叶节点)(使用不同的数是为了建立配对集合)while len(clust)>1:lowestpair=(0,1)closest=distance(clust[0].vec,clust[1].vec)# 遍历每一对聚类,寻找距离最小的一对聚类for i in range(len(clust)):for j in range(i+1,len(clust)):# 用distance_set来缓存距离最小的计算值if (clust[i].id,clust[j].id) not in distance_set:distance_set[(clust[i].id,clust[j].id)]=distance(clust[i].vec,clust[j].vec)d=distance_set[(clust[i].id,clust[j].id)]if d<closest:closest=dlowestpair=(i,j)# 计算距离最近的两个聚类的平均值作为代表新聚类的中心点mergevec=[(clust[lowestpair[0]].vec[i]+clust[lowestpair[1]].vec[i])/2.0 for i in range(len(clust[0].vec))]# 将距离最近的两个聚类合并成新的聚类newcluster=bicluster(mergevec,left=clust[lowestpair[0]],right=clust[lowestpair[1]],distance=closest,id=currentclustid)# 不再原始集合中的聚类id设置为负数。为了标记这是一个枝节点currentclustid-=1# 删除旧的聚类。(因为旧聚类已经添加为新聚类的左右子聚类了)del clust[lowestpair[1]]del clust[lowestpair[0]]clust.append(newcluster)return clust[0]   #返回聚类树

绘制决策树

1、获取聚类树要显示完整需要的高度

def getheight(clusttree):# 若是叶节点则高度为1if clusttree.left==None and clusttree.right==None: return 1# 否则,高度为左右分枝的高度之和return getheight(clusttree.left)+getheight(clusttree.right)

2、获取聚类树要显示完整需要的深度(宽度)

def getdepth(clusttree):# 一个叶节点的距离是0.0if clusttree.left==None and clusttree.right==None: return 0# 一个叶节点的距离=左右两侧分支中距离较大者 + 该支节点自身的距离return max(getdepth(clusttree.left),getdepth(clusttree.right))+clusttree.distance

3、画聚类节点以及子聚类节点

def drawnode(draw,clust,x,y,scaling,labels):if clust.id<0:h1=getheight(clust.left)*20h2=getheight(clust.right)*20top=y-(h1+h2)/2bottom=y+(h1+h2)/2# 线的长度ll=clust.distance*scaling# 聚类到其子节点的垂直线draw.line((x,top+h1/2,x,bottom-h2/2),fill=(255,0,0))# 连接左侧节点的水平线draw.line((x,top+h1/2,x+ll,top+h1/2),fill=(255,0,0))# 连接右侧节点的水平线draw.line((x,bottom-h2/2,x+ll,bottom-h2/2),fill=(255,0,0))# 调用函数绘制左右子节点drawnode(draw,clust.left,x+ll,top+h1/2,scaling,labels)drawnode(draw,clust.right,x+ll,bottom-h2/2,scaling,labels)else:# 如果这是一个叶节点,则绘制节点的标签文本draw.text((x+5,y-7),labels[clust.id],(0,0,0))

绘制聚类树

# 绘制树状图——为每一个最终生成的聚类创建一个高度为20像素,宽度固定的图片。其中缩放因子是由固定宽度除以总的深度得到的
def drawdendrogram(clusttree, labels, jpeg='clusters.jpg'):# 高度和宽度h = getheight(clusttree) * 20w = 1200depth = getdepth(clusttree)# 由于宽度是固定的,因此我们需要对距离值做相应的调整。(因为显示窗口宽度固定,高度可上下拖动)scaling = float(w - 150) / depth# 新建一个白色背景的图片img = Image.new('RGB', (w, h), (255, 255, 255))draw = ImageDraw.Draw(img)draw.line((0, h / 2, 10, h / 2), fill=(255, 0, 0))# 画根节点(会迭代调用画子节点)drawnode(draw, clusttree, 10, (h / 2), scaling, labels)img.save(jpeg, 'JPEG')

我们来测试一下

if __name__=='__main__':blognames,words,data = readfile('blogdata.txt')  #加载数据集clust = hcluster(data)  #构建聚类树drawdendrogram(clust,blognames,jpeg='blogclust.jpg')  # 绘制聚类树

一个聚类树就构建完成了。我们看到这个聚类树还是有明显的分组的。

对特征进行聚类

上面的内容我们是对每个对象(也就是每行数据)形成聚类点,然后对聚类点进行聚类。

那么我们是否也可以对每个特征(每列数据)形成聚类点,然后对特征进行聚类,看看哪些单词经常用在一个主题中。

我们只要对特征数据集进行一下转置,让每行为一种特征(单词),每列代表一个对象(文档)。然后再调用上面的层次聚类算法就可以了。

数据集转置代码

# 数据集转置,进行列聚类。
def rotatematrix(data):newdata=[]for i in range(len(data[0])):newrow=[data[j][i] for j in range(len(data))]newdata.append(newrow)return newdata  #一行表示一个单词在每篇博客中出现的次数

下面我们来测试看看

if __name__=='__main__':blognames,words,data = readfile('blogdata.txt')  #加载数据集rdata = rotatematrix(data)  #旋转数据集矩阵,对特征属性进行聚类wordclust = hcluster(rdata) #构建特征的聚类树drawdendrogram(wordclust,labels=words,jpeg='wordclust.jpg')  # 绘制特征的聚类树

python机器学习案例系列教程——层次聚类(文档聚类)相关推荐

  1. python机器学习案例系列教程——k均值聚类、k中心点聚类

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 上一篇我们学习了层次聚类.层次聚类只是迭代的把最相近的两个聚类匹配起来.并没有给出能给出多少的分组.今天我们来研究一个K均值聚类.就是 ...

  2. python机器学习案例系列教程——聚类算法总结

    全栈工程师开发手册 (作者:栾鹏) python教程全解 一.什么是聚类? 聚类(Clustering):聚类是一个人们日常生活的常见行为,即所谓"物以类聚,人以群分",核心的思想 ...

  3. python机器学习案例系列教程——文档分类器,朴素贝叶斯分类器,费舍尔分类器

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 github地址:https://github.com/626626cdllp/data-mining/tree/master/Bay ...

  4. python机器学习案例系列教程——BIRCH聚类

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 BIRCH概述 BIRCH的全称是利用层次方法的平衡迭代规约和聚类(Balanced Iterative Reducing and C ...

  5. python机器学习案例系列教程——推荐系统

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 主流的推荐系统算法大致分为两类: 基于用户行为数据的协同过滤算法 基于内容数据的过滤算法 大致而言,基于内容数据的算法适用于cold ...

  6. python机器学习案例系列教程——决策树(ID3、C4.5、CART)

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 决策树简介 决策树算是最好理解的分类器了.决策树就是一个多层if-else函数,就是对对象属性进行多层if-else判断,获取目标属性 ...

  7. python机器学习案例系列教程——关联分析(Apriori、FP-growth)

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 关联分析的基本概念 关联分析(Association Analysis):在大规模数据集中寻找有趣的关系. 频繁项集(Frequent ...

  8. python机器学习案例系列教程——集成学习(Bagging、Boosting、随机森林RF、AdaBoost、GBDT、xgboost)

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 可以通过聚集多个分类器的预测结果提高分类器的分类准确率,这一方法称为集成(Ensemble)学习或分类器组合(Classifier C ...

  9. python机器学习案例系列教程——极大似然估计、EM算法

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 极大似然 极大似然(Maximum Likelihood)估计为用于已知模型的参数估计的统计学方法. 也就是求使得似然函数最大的代估参 ...

最新文章

  1. 独家 | 综述:情感树库上语义组合的递归深层模型
  2. VS.NET2003 开发环境 生成样式表 和 自动书写HTML对象模型
  3. 读芯片信息出错3_数字传感器的电路设计,跟着芯片哥学你也会
  4. zanePerfor 一款完整,高性能,高可用的前端性能监控系统,不要错过
  5. 。。。。。。想不通的ADO.NET。
  6. 0118——RTLabel和正则表达式
  7. 肖仰华 | 基于知识图谱的可解释人工智能:机遇与挑战
  8. matlab设置非平坦结构元,详解MATLAB/Simulink通信系统建模与仿真图书信息
  9. 1-java学习笔记
  10. 自己实现的数值到大写人民币的实现
  11. css的变量教程,更强大的css
  12. dms虚拟服务器,取得dms服务器ip
  13. ISO14001认证申请条件
  14. Matlab常用的滤波函数集合(会陆续更新详解)
  15. android 控件发光_Android自定义控件打造闪闪发光字体
  16. AI已经参与论文打假了
  17. 甲A十年十大悲情时刻回顾 谁的眼泪在空中飞舞?
  18. 数字模型制作规范(转自Unity3D群)
  19. 现实中的项目范围变更
  20. 三国无双模型数据结构。。。

热门文章

  1. python装饰器详解-python 装饰器详解
  2. 科学网—中文普通话语音识别DEMO,LilyMandarinSpeechRecognition V1.0 - 石自强的博文...
  3. 苹果沦为语音识别领域失败者?
  4. Linux断开进程的某个socket,Linux Socket:如何在客户端程序中检测断开的网络?
  5. LeetCode 72 编辑距离
  6. AS打开卡住、一直加载的问题
  7. JavaMail 发送邮件的实例
  8. java中的比较运算符_Java基础---Java中的比较运算符(十三)
  9. html文件用的那个版本,html – 使用Django进行静态文件版本控制
  10. 【NOIP2001】【Luogu1025】数的划分(可行性剪枝,上下界剪枝)