anaconda matplotlib 输出动画_Matplotlib输出动画实现K-means聚类过程可视化

本文主要讨论使用matplotlib保存gif动画,K-Means聚类是一个很基础的聚类方法,基本过程如下:

  1. 给定一组样本,确定k值,即类别数目
  2. 随机初始化k个聚类的中心(下称中心)
  3. 计算每个样本与每一个中心的相似的程度——距离
  4. 考察每个样本,离哪一个中心更近,就将该样本分为哪一类
  5. 所有样本划分完毕后,重新计算聚类的中心
  6. 重复3、4、5,直到中心不变或者变化很小

上述过程的3、4、5步需要展开一下。首先是第3步,使用欧式距离:

其中,

表示第
个样本的第
个特征值
表示第
个中心的第
个“特征值”
表示第
个样本与第
个中心的距离

一个样本有

个特征值(
),可以看作是
维空间中的一个坐标点。同样,一个聚类的中心也是该空间中的一个点,所以上面也使用了特征值这个名称,但是需要区分的是:一个中心并不算一个样本

然后是第4步,这里举一个具体的栗子。例如有80个样本,每个样本含有2个特征值。现在令

,即将这些样本分为4类

将所有样本作为一个二维数组,其shape为


将4个中心作为一个二维数组,其shape为

完成第3步的计算以后得到一个结果,其shape应为
,然后对每一行求最小值的索引就可算出一个样本应分为哪一类

关于这两步,numpy没有现成的函数可以一步到位,所以使用自定义的ufunc函数

class 

在calc_distance中计算距离时没有开方,是因为不开方不会影响单调性,所以省了

最后是第5步,根据现有的中心将所有的样本分类

类之后,计算每一类的新的中心。计算方法很简单,例如第0类有15个样本,计算这15个样本每个特征上的均值即得到了新的中心。当然也有其他方法计算中心,例如使用中位数等

K-means简单讨论到这里,然后时使用matplotlib保存聚类过程为一个gif动画,首先把直接效果贴出来

e53337f887595453b0c653551b513f06.gif
圆点是样本,X是聚类的中心

为了增加视觉效果,动态调整了每个聚类的点的大小。现在进入正题,要保存gif动画需要用到matplotlib的一个类:

from 

该类的初始化如下

def 

上面的代码列举了FuncAnimation类初始化的几个关键参数,注释已经写的比较详细,只针对func和init_func展开讨论

init_func 是动画的初始化函数,也可以不设置,该函数的过程无非就是前面讨论的,将样本分类,根据分类的样本计算新的中心。然后用分好类的样本数据进行散点图的绘制,并且将散点图的对象放在一个元组中返回(必须是元组)

    def setup(self, colors=['r', 'g', 'b', 'k']):
        '''
        动画初始化函数
        '''
        cs = self.get_classified_sample()    # 得到分类后的样本
        
        tmp = []
        for i in np.arange(self.k):     # 绘制已分类的样本
            tmp.append(self.ax.scatter(cs[i][:,0], cs[i][:,1], c=colors[i], animated=True))

        for i in np.arange(self.k):     # 绘制中心
            tmp.append(self.ax.scatter(self.center[i,0], self.center[i,1], c=colors[i], s=150, marker='x', animated=True))

        self.sc = tuple(tmp)            # 必须转换为元组

        for i in np.arange(self.k):     # 更新每个簇的中心
            self.center[i,:] = cs[i].mean(axis=0)

        return self.sc      # 返回必须是元组

上面的代码中有的函数还没贴出来显得有点凌乱,我会在文章最后给出github的链接,包括完整代码,测试数据,以及生成的动画

另外func参数要传入一个函数,该函数会在绘制每一帧动画时调用,同样也是返回一个包含散点图对象的元组

def 

通过上面的两个参数的解释,想必应该清楚这个动画是怎么生成的了,其实就是在这两个函数中生成matplotlib的绘图对象,或者调整其属性,然后FuncAnimation对象就会根据你返回的对象绘制每一帧的图像,最后组成动画

最后是实现的链接:

完整实现​github.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值