K-means

k-means是无监督的聚类算法,k-means指的是  每个簇的中心即簇中所包含的值的均值。可使用k-means算法实现音调的分类与可视化 文本文档聚类等用途。

算法原理:

  1. 选择k个初始中心点;
  2. 将每个初始点与每个点进行比较,如果与第n个点距离最近,则标记为n;
  3. 将标记为n的一类数据,计算他们每个特征的均值;
  4. 重复第二步和第三步,直到每个特征列的均值变化小于所给定的值,或者是达到了最大迭代次数。

k值选取:

  • 层次聚类或者使用Canopy算法进行聚类
  • 根据实际需求选取:衣服的尺寸分为(M,L,S)三种
  • 肘部法则(Elbow Method)

初始质心的选取:

  • 随机选取
  • 层次聚类:划分k个层次,计算出每个簇对应的质心即初始质心;
  • k-means++

距离度量:

  • 欧式距离
  • 余弦相似度

 

聚类的评估标准——轮廓系数(Silhouette Coefficient)

轮廓系数结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估类的密集与分散程度。该值处于-1~1之间,值越大,表示聚类效果越好。计算公式如下:

ai为计算样本i到同簇其他样本的平均距离, 
计算样本i到其他某簇Cj 的所有样本的平均距离bij,称为样本i与簇Cj 的不相似度。

轮廓系数所反映的聚类效果:

  • si接近1,则说明样本i聚类合理;
  • si接近-1,则说明样本i更应该分类到另外的簇;
  • 若si 近似为0,则说明样本i在两个簇的边界上

使用代码自定义实现k-means:

#计算欧式距离
def distanceEuclid(pointA,pointB):
    return sqrt( sum( power(pointA-pointB,2 ) ) )


#随机生成中心点
def randCenter( dataSet,k):
    m,n = shape(dataSet)
    centers = mat( zeros((k,n)) )  #k个质心  n列
    for j in range(n):   #每循环一次   产生一个列的值
        #找最小值与最大值
        minJ = min( dataSet[:,j])
        maxJ = max( dataSet[:,j])
        rangeJ = float(maxJ-minJ)
        #print( random.rand(k,1))   # k个   从0到1
        centers[:,j] = minJ + rangeJ* random.rand(k,1)
    return centers

#k-means实现
def myKmeans(dataSet,k,distMea = distanceEuclid, initCenter = randCenter):
    '''
    参数列表:
    dataSet: 数据集
    k: 分类的簇的数量
    distMea: 距离算法
    initCenter: 中心点
    '''
    m,n = shape( dataSet )
    #zeros(m,2) -> 生成m行2列,m行对应每条数据,2列中的第一列表示每条数据属于哪个簇,第二列表示每条数据距中心点距离
    clusterAssment = mat(zeros((m,2)))
    #生成初始化质心
    centers = initCenter(dataSet,k)
    
    clusterChanged = True
    #簇是否改变
    while clusterChanged:
        clusterChanged=False
        #循环每个点,计算它与质心的距离
        for i in range(m):
            minDistance = inf   #计算第i个点到每个质心的最小距离,并保存
            minIndex = -1    #到哪个质心的距离最小保存索引
            for j in range(k):    #循环,取每个质心点
                #计算第i个点到第i个质心的距离
                distance = distMea(centers[j,:],dataSet[i,:])
                #是否为最小距离
                if distance<minDistance:
                    minDistance = distance
                    minIndex = j 
                #判断当前 第i个点是否要更改质心点
                if clusterAssment[i,0] != minIndex:   #索引不相等  更改簇
                    clusterChanged = True
                    
                clusterAssment[i,0] = minIndex
                clusterAssment[i,1] = minDistance**2    #距离
                print('第',i , '条数据运行结果:',clusterAssment[i])
                
        #循环所有的簇  重新计算质心
        for cent in range(k):
            flag = clusterAssment[:,0].A == cent#  clusterAssment[;,0] 数据编号
            pointsInCluster = dataSet[ nonzero(flag)[0] ]  
            centers[cent,:]=mean(pointsInCluster,axis = 0)   #k-means
    
    return centers,clusterAssment

 

Reference:

sklearn官网:  https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans

k值选取: https://www.codercto.com/a/26692.html

几种初始化质心的方式: https://blog.csdn.net/xiaoxik/article/details/79023439

距离度量: https://blog.csdn.net/les000lie/article/details/89503537

轮廓系数: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.silhouette_score.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值