K-means

1.算法流程

1.1 确定参数:指定要划分的簇数k。

1.2 初始化质心:从所有数据样本中随机选取k个样本,作为k个簇的初始 "质心"。

1.3 样本分配:计算每个样本到k个质心的距离,将样本分配给距离最近的质心所属的簇。

1.4 更新质心:对每个簇,计算其所有样本的特征均值,用这个均值替换原质心。

1.5 迭代收敛:重复 "样本分配→更新质心" 的步骤,直到质心的位置不再明显变化,算法停止。

2.代码实现

python 复制代码
# -*- coding: utf-8 -*-


import numpy as np
import matplotlib.pyplot as plt

def L2(vecXi, vecXj):
    '''
    计算欧氏距离
    para vecXi:点坐标,向量
    para vecXj:点坐标,向量
    retrurn: 两点之间的欧氏距离
    '''
    return np.sqrt(np.sum(np.power(vecXi - vecXj, 2)))

def kMeans(S, k, distMeas=L2):
    '''
    K均值聚类
    para S:样本集,多维数组
    para k:簇个数
    para distMeas:距离度量函数,默认为欧氏距离计算函数
    return sampleTag:一维数组,存储样本对应的簇标记
    return clusterCents:一维数组,各簇中心
    retrun SSE:误差平方和
    '''
    m = np.shape(S)[0] # 样本总数
    sampleTag = np.zeros(m)
    
    # 随机产生k个初始簇中心
    n = np.shape(S)[1] # 样本向量的特征数
    clusterCents = np.mat([[-1.93964824,2.33260803],[7.79822795,6.72621783],[10.64183154,0.20088133]])
    #clusterCents = np.mat(np.zeros((k,n)))
    #for j in range(n):
    #    minJ = min(S[:,j]) 
    #    rangeJ = float(max(S[:,j]) - minJ)
    #    clusterCents[:,j] = np.mat(minJ + rangeJ * np.random.rand(k,1))
        
    sampleTagChanged = True
    SSE = 0.0
    while sampleTagChanged: # 如果没有点发生分配结果改变,则结束
        sampleTagChanged = False
        SSE = 0.0
        
        # 计算每个样本点到各簇中心的距离
        for i in range(m):
            minD = np.inf
            minIndex = -1
            for j in range(k):
                d = distMeas(clusterCents[j,:],S[i,:])
                if d < minD:
                    minD = d
                    minIndex = j
            if sampleTag[i] != minIndex: 
                sampleTagChanged = True
            sampleTag[i] = minIndex
            SSE += minD**2
        print(clusterCents)
        plt.scatter(clusterCents[:,0].tolist(),clusterCents[:,1].tolist(),c='r',marker='^',linewidths=7)
        plt.scatter(S[:,0],S[:,1],c=sampleTag,linewidths=np.power(sampleTag+0.5, 2))
        plt.show()
        print(SSE)
        
        # 重新计算簇中心
        for i in range(k):
            ClustI = S[np.nonzero(sampleTag[:]==i)[0]]
            clusterCents[i,:] = np.mean(ClustI, axis=0) 
    return clusterCents, sampleTag, SSE

if __name__=='__main__':
    samples = np.loadtxt("kmeansSamples.txt")
    clusterCents, sampleTag, SSE = kMeans(samples, 3)
    #plt.scatter(clusterCents[:,0].tolist(),clusterCents[:,1].tolist(),c='r',marker='^')
    #plt.scatter(samples[:,0],samples[:,1],c=sampleTag,linewidths=np.power(sampleTag+0.5, 2))
    plt.show()
    print(clusterCents)
    print(SSE)
相关推荐
轮到我狗叫了7 分钟前
GAN初次阅读
人工智能·神经网络·生成对抗网络
一只土卜皿7 分钟前
列线图/诺莫图 含概率轴
人工智能
造夢先森8 分钟前
【白话神经网络(三)】从Transformer到XXX
人工智能·神经网络·transformer
研究点啥好呢19 分钟前
3月22日GitHub热门项目推荐|网页浏览,何须手动
人工智能·python·开源·github
zl_vslam20 分钟前
SLAM中的非线性优-3D图优化之相对位姿Between Factor-四元数(十二)
人工智能·算法·计算机视觉
知行产研24 分钟前
神宝能源:启动国内首个极寒工况5G+无人驾驶项目
人工智能·自动驾驶
love530love32 分钟前
ComfyUI-3D-Pack:Windows 下手动编译 mesh_inpaint_processor C++ 加速模块
c++·人工智能·windows·python·3d·hunyuan3d·comfyui-3d-pack
uzong37 分钟前
“腾讯QClaw全面开放”,不花 Token 钱、真正体验一把小龙虾的快乐,最低成本全面了解龙虾
人工智能·后端
vx_biyesheji000142 分钟前
计算机毕业设计:Python多源新闻数据智能舆情挖掘平台 Flask框架 爬虫 SnowNLP ARIMA 可视化 数据分析 大数据(建议收藏)✅
爬虫·python·机器学习·数据分析·django·flask·课程设计
剑穗挂着新流苏31242 分钟前
111_神经网络的指路明灯:损失函数与反向传播深度解析
人工智能·深度学习·神经网络