kmeans

import numpy as np

def get_dist(vec1, vec2):       # 两个向量之间的欧几里德距离
    return np.sqrt(np.sum(np.power(vec1 - vec2, 2)))

def rand_cent(dataSet, k):       # 返回初始化得到的k个质心向量  
    n = np.shape(dataSet)[1]     # 得到数据样本的维度
    centroids = np.mat(np.zeros((k, n))) # 初始化为一个(k,n)的全零矩阵
    # k个质心向量的第j维数据值随机为位于(最小值,最大值)内的某一值
    for j in range(n):           # 遍历数据集的每一个维度
        minJ = np.min(dataSet[:, j])  # 得到该列数据的最小值,最大值
        maxJ = np.max(dataSet[:, j])
        rangeJ = float(maxJ - minJ)   # 得到该列数据的范围(最大值-最小值)
        centroids[:, j] = minJ + rangeJ * np.random.rand(k, 1) # k个在0 1之间的二维矩阵
    return centroids            # 返回初始化得到的k个质心向量

def kMeans(dataSet, k):
    m = np.shape(dataSet)[0]    # 获取数据集样本数
    result = np.mat(np.zeros((m, 2)))   # 初始化(m,2)全零矩阵 (属于哪一簇,距离质心距离)
    centroids = rand_cent(dataSet, k)   # 创建初始的k个质心向量
    changed = True              # 聚类结果是否发生变化的布尔类型 
    while changed:       # 只要聚类结果一直发生变化,就一直执行聚类算法,直至所有数据点聚类结果不发生变化
        changed = False         # 聚类结果变化布尔类型置为False
        for i in range(m):      # 遍历数据集每一个样本向量
            minDist = float('inf')  # 初始化最小距离为正无穷,最小距离对应的索引为-1
            minIndex = -1
            for j in range(k):  # 循环k个类的质心
                dist = get_dist(dataSet[i, :], centroids[j, :])  # 计算数据点到质心的欧氏距离
                if dist < minDist:  # 如果距离小于当前最小距离            
                    minDist = dist  # 当前距离为最小距离,最小距离对应索引应为j(第j个类)
                    minIndex = j
            if result[i, 0] != minIndex:  # 当前聚类结果中第i个样本的聚类结果发生变化:布尔值置为True,继续聚类算法
                changed = True
            result[i, :] = minIndex, minDist**2 # 更新当前变化样本的聚类结果和平方误差
       
        for cent in range(k):    # 遍历每一个质心
            points = dataSet[np.nonzero(result[:, 0].A == cent)[0]] # 所有属于当前质心类的样本 
            centroids[cent, :] = np.mean(points, axis=0) # 计算当前质心类的均值(axis=0:求列均值),作为该类质心向量
    return centroids, result   # 返回质心,属于哪一簇 距离质心距离
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值