前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k均值聚类算法

k均值聚类算法

作者头像
皮大大
发布2021-03-02 14:36:36
1.5K0
发布2021-03-02 14:36:36
举报
文章被收录于专栏:机器学习/数据可视化

吴恩达老师-K均值聚类

K均值聚类算法中主要是有两个关键的步骤:簇分配和移动聚类中心。

  • 簇分配
    • 假设有一个样本集合,需要将其分成两个类(簇:cluster,红色和蓝色)
    • 首先随机生成两个聚类中心:红色和蓝色两个点
    • 遍历每个样本绿色的点,求出和两个聚类中心的距离,判断和哪个更接近,则归属于哪个类(簇)
  • 移动聚类中心
    • 将两个聚类中心(红色和蓝色的叉)移动到同色点的均值处,找到所有红色(蓝色)点的均值

重复上述的步骤:簇分配和移动聚类中心,直到颜色的点不再改变,具体算法过程如下各图所示:

算法

输入
  • K值:分成K个簇
  • 训练样本
簇分配和移动聚类中心

和某个聚类中心之间距离的最小值,采用的是欧式距离的平方,则该样本归属于其类

c_i=\min ||x{(i)}-u_k||2

代价损失函数

算法特性

  • 基于划分的聚类算法,k值需要预先指定;
  • 欧式距离的平方表示样本和聚类中心之间的距离,以中心或者样本的均值表示类别
  • 算法是迭代算法,不能得到全局最优解
  • 选择不同的初始中心,会得到不同的聚类结果
  • 聚类结果的质量一般是通过类的平均直径来进行衡量的
  • k的选择:一般的,当类别数增加平均直径会减小,当到达某个值后平均直径不再变化,此时的值就是k

代码实现

代码语言:javascript
复制
import numpy as np

def kmeans(data, n, m, k):
    rarray = np.random.random(size=k)    # 设置簇的个数k
    rarray = np.floor(rarray*n)   # 
    rarray.astype(int)
    cls = np.zeros([1,n],np.int)            
    center = np.take(data,rarray)
    pcenter = np.zeros([k,m])
    end = True
    while end:
        for i in xrange(n):
            tmp = data[i] - center
            tmp = np.square(tmp)
            tmp = np.sum(tmp,axis=1)
            cls[i] = np.argmin(tmp)
        center = np.zeros([k,m])
        count = np.zeros([1,k],np.int)
        for i in xrange(n):
            center[cls[i]]=center[cls[i]]+data[i]
            count[cls[i]]= count[cls[i]]+1
        if np.sum(center/count - pcenter) <= 1e-4:
            end = False
        pcenter = center/count
代码语言:javascript
复制
from numpy import *
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans


#dataSet:聚类数据集
#k:指定的k个类
def kmeans(dataSet, k):
    #得到数据样本的维度n
    sampleNum, col = dataSet.shape
     #初始化为一个(k,n)的矩阵=簇
    cluster = mat(zeros((sampleNum, 2)))
    #生成全零阵
    centroids = zeros((k, col))
    #选择质心
    for i in range(k):
        #索引为随机生成的int类型的且在0-sampleNum间的数
        index = int(random.uniform(0, sampleNum))
        centroids[i, :] = dataSet[index, :]
    #设置flag,查看聚类结果是否发生变化
    clusterChanged = True
     #只要聚类结果一直发生变化,就一直执行聚类算法,直至所有数据点聚类结果不变化
    while clusterChanged:
        #聚类结果变化布尔类型置为false
        clusterChanged = False
         #遍历数据集每一个样本向量
        for i in range(sampleNum):
            #使用sqrt函数(二分法)
            minDist = sqrt(sum(power(centroids[0, :] - dataSet[i, :], 2)))
            minIndex = 0
            #计算点到质心的距离
            for j in range(1,k):
                distance = sqrt(sum(power(centroids[j, :] - dataSet[i, :], 2)))
                #当前最小距离一定时,索引为J
                if distance < minDist:
                    minDist  = distance
                    minIndex = j

            # 当前聚类结果中第i个样本的聚类结果发生变化:布尔类型置为true,继续聚类算法
            if cluster[i, 0] != minIndex:
                clusterChanged = True
                #更新聚类结果和平方误差
                cluster[i, :] = minIndex, minDist**2
        #遍历每一个质心
        for j in range(k):
            #筛选出属于当前质心类的所有样本
            pointsInCluster = dataSet[nonzero(cluster[:, 0].A == j)[0]]
            #计算列的均值(使用axis=0:求列的均值)
            centroids[j, :] = mean(pointsInCluster, axis = 0)

    return centroids, cluster

#创建简单数据集以及进行可视化
dataSet = [[1,1],[3,1],[1,4],[2,5],[11,12],[14,11],[13,12],[11,16],[17,12],[28,10],[26,15],[27,13],[28,11],[29,15]]
dataSet = mat(dataSet)
k = 3
centroids, cluster = kmeans(dataSet, k)
sampleNum, col = dataSet.shape
mark = ['or', 'ob', 'og']

for i in range(sampleNum):
    markIndex = int(cluster[i, 0])
    plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])

mark = ['+r', '+b', '+g']
for i in range(k):
    plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12)

plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-9-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 吴恩达老师-K均值聚类
  • 算法
    • 输入
      • 簇分配和移动聚类中心
      • 代价损失函数
      • 算法特性
      • 代码实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档