k-means算法

K-means算法(Lloyod,1982)是简单而又有效的统计聚类算法,使机器能够将具有	相同属性
的样本归置到一块儿。与分类不同,对于一个分类器,通常需要告诉它	“这个样本被分成哪些类”这样一些标签,在	
最理想情况下,一个分类器会从所	得到的训练集中进行“学习”,我们将这种提供训练的过程称为“监督学习”。但是
在聚类下,我们并不关心某一类是什么,我们的目的是想将相似的样本归置在	一起,这样,一个聚类算法通常只要知
道该如何计算样本间的相似度并将相似样	本归并到一起就可以操作了,因此聚类通常并不需要使用训练数据进行学
习,这	在机器学习中被称作“无监督学习”。K-means算法就是这种用于统计的无监督	聚类技术。

K-Means算法思想:对给定的样本集,事先确定聚类簇数K,让簇内的样本尽可	能紧密分布在一起,使簇间的距离
尽可能大。该算法试图使集群数据分为n组独	立数据样本,使n组集群间的方差相等,数学描述为最小化惯性或集群
内的平方	和。K-Means作为无监督的聚类算法,实现较简单,聚类效果好,因此被广泛使用。

在这里插入图片描述

K-means聚类算法简介

1.首先获得一个数据样品集
2.按照平均的方法找到k个初始聚类中心
3.将数据中的每个点 与已有的k个聚类中心计算得到欧氏距离
得到离该点最近的聚类中心 把数据集分成一个个的簇( cluster )

在这里插入图片描述
4.为了更加精确 要采取迭代的方法 将以经分好的簇 经过加权平均得到新的聚类中心 重新进行分类计算 —>3 直到new中心和last中心乎一样 既每个数据点的所属聚类中心不再发生变化 迭代结束
在这里插入图片描述

举例

初始数据坐标
在这里插入图片描述

每个数据点距离聚类中心的欧氏距离
在这里插入图片描述
按照距离找到所属的聚类中心
在这里插入图片描述
0代表第一个中心 1带代表第二个
因为这里选取的k为2
这个结果存到last容器里面 然后得到新的new数据后比较

import numpy as np
import matplotlib.pyplot as plt
# 构造聚类中心
# dataset [N,D]
# K 聚类中心的数目 [K,D]
def creat_centers(dataset, K):
    val_max = np.max(dataset, axis=0)
    val_min = np.min(dataset, axis=0)
    centers = np.linspace(val_min, val_max, num=K + 2)
    return centers[1:-1, :]
#draw_kmeans  画图
def draw_kmeans(dataset, lab, centers, dic_colors=None, name="0.jpg"):
    plt.cla()
    vals_lab = set(lab.tolist())
    for i, val in enumerate(vals_lab):
        index = np.where(lab == val)[0]
        sub_dataset = dataset[index, :]
        plt.scatter(sub_dataset[:, 0], sub_dataset[:, 1], s=16., color=dic_colors[i])
    for i in range(np.shape(centers)[0]):
        plt.scatter(centers[i, 0], centers[i, 1], color="k", marker="+", s=200.)
    plt.savefig(name)
#进行kmeans的计算
#dataset数据样品集
#k个聚类中心
#最多m次迭代
#颜色和是否画图
def run_kmeans(dataset, K, m, dic_colors, b_draw):
        N, D = np.shape(dataset)
        # print(N,D)
        # 确定初始化聚类中心
        centers = creat_centers(dataset, K)
        lab = np.zeros(N)
        if b_draw:
            draw_kmeans(dataset, lab, centers, dic_colors, name="int.jpg")
        # 进行m轮迭代
        labs = np.zeros(N)  # 初始聚类结果
        for it in range(m):
            # 计算每个点距离中心的距离
            distance = np.zeros([N, K])
            for k in range(K):
                center = centers[k, :]
                # 计算欧式距离
                diff = np.tile(center, (N, 1)) - dataset
                sqrDiff = diff ** 2
                sqrDiffSum = sqrDiff.sum(axis=1)
                distance[:, k] = sqrDiffSum
            # 距离排序,进行聚类
            labs_new = np.argmin(distance, axis=1)
            error = np.sum(np.min(distance, axis=1)) / N
            print(np.sum(np.min(distance,axis=1)))
            print("第 %d 次聚类 距离误差 %.2f" % (it, error))
            # 绘图
            if b_draw:
                draw_kmeans(dataset, labs_new, centers,
                            dic_colors, name=str(it) + "_oldcenter.jpg")
            # 计算新的聚类中心
            for k in range(K):
                index = np.where(labs_new == k)[0]
                centers[k, :] = np.mean(dataset[index, :], axis=0)
            # 绘图
            if b_draw:
                draw_kmeans(dataset, labs_new, centers,
                            dic_colors, name=str(it) + "_newcenter.jpg")
            # 如果聚类结果和上次相同,退出
            if np.sum(labs_new - labs) == 0:
                return labs_new
            else:
                labs = labs_new
        return labs
if __name__ == "__main__":
    a = np.random.multivariate_normal([2, 2], [[.5, 0], [0, .5]], 100)
    b = np.random.multivariate_normal([0, 0], [[0.5, 0], [0, 0.5]], 100)
    dataset = np.r_[a, b]
    lab_ture = np.r_[np.zeros(100), np.ones(100)].astype(int)
    dic_colors = {0: (0., 0.5, 0.), 1: (0.8, 0, 0)}
    labs = run_kmeans(dataset, 2, 20, dic_colors,True)

初始数据

在这里插入图片描述
分类后数据

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛郎恋刘娘,刘娘念牛郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值