(自用)机器学习K-MEANS

在各处收集的大佬的文章,自用学习,非原创,在下面也有标注,感谢各位大佬的讲解。

1. K-means聚类定义: 

K-means算法是用来解决著名的聚类问题的最简单的非监督学习算法之一,是很典型的基于距离的聚类算法。该算法采用距离作为相似性的评价指标。即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

原理参考这篇,讲的很清楚的博主:

【海量数据挖掘/数据分析】之 K-Means 算法(K-Means算法、K-Means 中心值计算、K-Means 距离计算公式、K-Means 算法迭代步骤、K-Means算法实例)_kmeans聚类算法-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/u014361280/article/details/131547468

2. K-means的局限性

 当聚类的大小、密度、形状不同时,K-means 聚类的结果不理想
 数据集包含离群点时,K-means 聚类结果不理想
 两个类距离较近时,聚类结果不合理

3. 改进的K-means算法


上面介绍的k-means 算法是一种非常简单并且使用广泛的聚类算法,但是

  • k 值需要预先给定,很多情况下 k 值的估计很困难。
  • K-Means 算法对初始选取的聚类中心点很敏感,不同的中心点聚类结果有很大的不同。也就是说,有可能陷入局部最优解。
  • 对离群点敏感,聚类结果易产生误差。
  • 相似性度量的函数不同也会对聚类结果产生影响。

接下来针对 k-means 的缺陷,总结对k-means的改进。从初始中心点的选取、离群点的检测与去除、相似性度量等几个方面进行概括、比较。

3.1 距离和相似性度量

传统的 k-means 算法使用欧几里得距离来度量相似度。
改进的措施是:

        采用了欧式距离、平方欧式距离、曼哈顿距离、余弦距离、谷本距离分别作为相似度度量对文本数据进行处理,实验结果显示余弦距离、谷本距离者在文本聚类中的表现更优。不同的测度距离作为相似性度量对聚类结果会产生不同的影响,对于不同类型的数据也应采用不同的距离函数作为相似度度量。
        针对 k-means 算法不能求解非线性流形聚类的缺陷,用空间密度相似性度量来代替欧几里得距离,使 k-means算法能够适应数据集的分布。同一簇中的数据点应位于高密度区域,不同簇中的数据点应该用低密度区域分隔开来。所以需要压缩高密度区域的距离,放大低密度区域的距离。
针对比例数据,提出用 Aitchison 距离度量来对比例数据进行聚类。使用 Aitchison 距离、欧几里德对数距离、余弦距离、Kullback 距离、Matisuita 距离进行了对比实验,聚类结果显示 Aitchison 距离度量最适合所有,因为较高的轮廓值,聚类更合适。对于图像比例数据聚类,使用 Aitchison 距离作为初始化步骤可以提供适用于比例数据的更好的混合结果。


3.2 初始聚类中心的选取
       

初始聚类中心的选取对 k-means 算法聚类结果的影响很大,不同的初始聚类中心,可能会产生不同的聚类结果。也可以说,k-means算法是一种贪心算法,容易陷入局部最优解。解决办法如下:

      类簇中心都处在局部密度比较大的位置,且距离具有比它更大的局部密度的对象相对较远的思想。运用此思想可以确定最佳初始聚类中心及数据集的最佳类簇数目。在这个思想的基础上,为了避免密度对截断距离的依赖性,重新定义了计算样本局部密度 ρ i 的方法,计算样本点到具有比它更高的局部密度数据对象的最近距离 δ i (当样本点 x i 是数据集中具有最大局部密度的样本点时,δ i 定义为 x i 和距离他最远的样本点之间的欧氏距离)。根据 ρ i 和 δ i 构造决策图,运用统计学中残差分析的方法,选取残差绝对值大于阈值的异常点,即为聚类中心。在二维以及高维数据集上的实验结果均验证了该算法的有效性。但是不足之处在于这个算法适用于比较集中的数据集,稀疏的数据集结果并不理想。
       采用减法聚类的算法确定初始聚类中心。首先是计算每个样本点的山峰函数值,选取山峰函数值最大的点作为聚类中心。选取下一个聚类中心时要消除已经确定的聚类中心的影响,就修改山峰函数,减去上一个确定的聚类中心的比例高斯函数,如此反复,直到得到足够多的聚类中心。这个方法的缺点在于对于离群点、异常值抗干扰能力比较弱,且需要设置的参数较多(一般需要 3 个)。
        采用了四分位数的概念来确定初始聚类中心。首先采用特征选择的方法选取数据有意义的属性。然后将将属性的值按照顺序排列,以分成两类为例,将数据集的上四分位点和下四分位点作为初始聚类中心,计算所有样本点到到这两个聚类中心的距离,进行分类;接下来更新聚类中心,将每类所有样本点的均值作为新的聚类中心,直到类簇不再发生变化。这个方法不足之处是当数据集比较大时,花费时间会比较长。
        采用最大 - 最小准则算法初步确定初始聚类中心,然后通过FLANN(快速最近邻搜索库)将聚类中心偏移到尽可能地靠近实际的聚类中心。最大 - 最小准则算法是首先随机选取一个点作为第一个聚类中心,选取距离这个点最远的点作为第二个聚类中心,然后计算每个点到这两个聚类中心的距离,选取较小的距离加入到集合 V 中,在集合 V 中选取距离最远的点作为下一个聚类中心,依次类推,直到最大最小距离不大于θ•D 1,2 (D 1,2 为第一个和第二个聚类中心的距离)。 FLANN 是一个在高维空间中快速搜索k 个最近邻居的库。使用 FLANN 找到聚类中心的 k 近邻,计算中心点即为新的聚类中心。


3.3离群点的检测


        K-means 算法对于离群点敏感,对聚类结果产生很大的影响,因此离群点的检测与删除极为重要。解决的方法有:

       基于密度的方法是一种流行的异常值检测方法。 它计算每个点的局部离群因子(LOF)。 一个点的 LOF 是基于该点附近区域的密度和它的邻居的局部密度的比值。LOF 方法依赖于用户提供的最小数量点,用于确定邻居的大小。
       建立了一个基于本地距离的离群因子(LDOF)来测量分散的数据集对象的离群程度。LDOF 使用一个对象到它的邻居的相对位置,以确定物体偏离其邻近区域的程度。为了方便实际应用中的参数设置,在离群值检测方法中使用了一种 top-n 技术,其中只有具有最高值的对象才被视为离群值。与传统的方法(如前 n 和顶 n)相比,方法是在分散的数据中检测出离群值。
       通过添加上限范数和一种有效的迭代重加权算法,来减小离群点的影响。离群点的检测发生在每次聚类中心迭代时,每个样本点到聚类中心的距离大于给定的参数 ε,便会被去除。并且重新给样本分配权重,低错误率的样本具有更高的权重。这个方面的缺陷在于参数 ε 需要人为的设置与调整,不同的ε值导致的聚类结果准确率不同。
        提出了k-means-sharp 算法,通过从点到质心距离的分布得到的全局阈值自动检测离群点。离群点检测过程和聚类过程同时完成。假设 k-means的数据呈高斯分布,离群点检测发生在每次聚类中心更新时,计算每个样本点到聚类中心的距离,如果距离大于 3σ,则为离群点,其中σ=1.4826MADe, MADe 为每个点到中值点的距离组成的所有数据的中值点。因此,每次更新聚类中心时,就会去除一部分离群点。


3.4 k-means算法的其他改进


      最近几年出现了遗传算法、粒子群算法、萤火虫算法、蚁群算法等与传统的 kmeans 算法相结合的改进算法,这几类算法的共同点是具有一定的全局优化能力,理论上可以在一定的时间内找到最优解或近似最优解。通常是使用这些算法来寻找 k-means 算法的初始聚类中心。

        将k-means和遗传算法结合的 k-means 算法优于传统的 k-means 算法。遗传 k-means 算法就是把每个聚类中心坐标当成染色体基因。聚类中心个数就是染色体长度,对若干相异染色体进行初始化操作并将其当成一个种群进行遗传操作,最终获得适应度最大染色体,而最优聚类中心坐标就是解析出的各中心点坐标。
       将粒子群算法与 k-means算法结合,多子群多于多子群粒子群伪均值(PK-means)聚类算法,理论分析和实验表明,该算法不但可以防止空类出现,而且同时还具有非常好的全局收敛性和局部寻优能力,并且在孤立点问题的处理上也具有很好的效果。
基于萤火虫优化的加权 K-means 算法。该算法在提升聚类性能的同时,有效增强了算法的收敛速度。在实验阶段,通过 UCI 数据集中的几组数据对该算法进行了聚类实验及有效性测试,实验结果充分表明了该算法的有效性及优越性。可见,将k-means算法与其他算法相结合,可以弥补 k-means 算法的不足,获得更好的聚类效果。

4. 总结


       K-means 的发展已经经历了很长的一段时间,它所具有的独特优势使得其被广大研究者不断地优化和使用。本文对 k-means 进行简单介绍。同时对 k-means 的研究和改进还应注意以下几点:

(1)随着互联网技术的发展,数据量呈现出一种指数级增长。如何高效地对这些海量数据进行处理和分析已成为当前研究热点。传统的 k-means 算法难以有效处理大的数据集。所以将并行计算和 k-means 算法结合,并不断地对其加以改进和优化,是处理海量数据的有效途径。
(2)k-means 聚类算法的改进有许多依然需要用户输入参数,传统的 k-means 算法的k 值的确定研究不多。所以参数的自确定是一个不断需要发展研究的问题。
(3)从文中可以看出,现在存在着各种各样的数据类型,文本、图像、混合型数据等等,现有的多是处理二维数据,对高维数据处理的研究不多,需要对 k-means 算法进行扩展,以得到一个能够适应大多数类型数据类型的 k-means 算法模型。

以上内容来自:机器学习(九)-k-means算法及优化和Python_k均值聚类算法优化python-CSDN博客

 5. 手撕:


# coding=utf-8 
from numpy import *

# 加载数据 
def loadDataSet(fileName):  # 解析文件,按tab分割字段,得到一个浮点数字类型的矩阵
    dataMat = []              # 文件的最后一个字段是类别标签
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float, curLine)    # 将每个元素转成float类型
        dataMat.append(fltLine)
    return dataMat

# 计算欧几里得距离 
def distEclud(vecA, vecB):
    return sqrt(sum(power(vecA - vecB, 2))) # 求两个向量之间的距离

# 构建聚簇中心,取k个(此例中为4)随机质心 
def randCent(dataSet, k):
    n = shape(dataSet)[1]
    centroids = mat(zeros((k,n)))   # 每个质心有n个坐标值,总共要k个质心
    for j in range(n):
        minJ = min(dataSet[:,j])
        maxJ = max(dataSet[:,j])
        rangeJ = float(maxJ - minJ)
        centroids[:,j] = minJ + rangeJ * random.rand(k, 1)
    return centroids

# k-means 聚类算法 
def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent):
    m = shape(dataSet)[0]
    clusterAssment = mat(zeros((m,2)))    # 用于存放该样本属于哪类及质心距离
    # clusterAssment第一列存放该数据所属的中心点,第二列是该数据到中心点的距离
    centroids = createCent(dataSet, k)
    clusterChanged = True   # 用来判断聚类是否已经收敛
    while clusterChanged:
        clusterChanged = False;
        for i in range(m):  # 把每一个数据点划分到离它最近的中心点
            minDist = inf; minIndex = -1;
            for j in range(k):
                distJI = distMeans(centroids[j,:], dataSet[i,:])
                if distJI < minDist:
                    minDist = distJI; minIndex = j  # 如果第i个数据点到第j个中心点更近,则将i归属为j
            if clusterAssment[i,0] != minIndex: clusterChanged = True;  # 如果分配发生变化,则需要继续迭代
            clusterAssment[i,:] = minIndex,minDist**2   # 并将第i个数据点的分配情况存入字典
        print centroids
        for cent in range(k):   # 重新计算中心点
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]]   # 去第一列等于cent的所有列
            centroids[cent,:] = mean(ptsInClust, axis = 0)  # 算出这些数据的中心点
    return centroids, clusterAssment

# --------------------测试----------------------------------------------------
# 用测试数据及测试kmeans算法 
datMat = mat(loadDataSet('testSet.txt')) 
myCentroids,clustAssing = kMeans(datMat,4) 


 

  • 21
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值