zoukankan      html  css  js  c++  java
  • kmeans原理

    一、kmeans概述

    K-means聚类算法也称k均值聚类算法,属于无监督学习的一种,k-means聚类无需给定Y变量,只有特征X。

    K-means聚类算法是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小

    在聚类问题中,给我们的训练样本是clip_image004,每个clip_image006,没有了y

    具体算法描述如下:

    1、 随机选取k个聚类质心点(cluster centroids)为clip_image008[6]

    2、 重复下面过程直到收敛 {

                   对于每一个样例i,计算其应该属于的类

                   clip_image009

                   对于每一个类j,重新计算该类的质心

                   clip_image010[6]}

    K是我们事先给定的聚类数,clip_image012[6]代表样例i与k个类中距离最近的那个类,clip_image012[7]的值是1到k中的一个。质心clip_image014[6]代表我们对属于同一个类的样本中心点的猜测,拿星团模型来解释就是要将所有的星星聚成k个星团,首先随机选取k个宇宙中的点(或者k个星星)作为k个星团的质心,然后第一步对于每一个星星计算其到k个质心中每一个的距离,然后选取距离最近的那个星团作为clip_image012[8],这样经过第一步每一个星星都有了所属的星团;第二步对于每一个星团,重新计算它的质心clip_image014[7](对里面所有的星星坐标求平均)。重复迭代第一步和第二步直到质心不变或者变化很小。

    K-means面对的第一个问题是如何保证收敛,前面的算法中强调结束条件就是收敛,可以证明的是K-means完全可以保证收敛性。下面我们定性的描述一下收敛性,我们定义畸变函数(distortion function)如下:

         clip_image016[6]

         J函数表示每个样本点到其质心的距离平方和。K-means是要将J调整到最小。假设当前J没有达到最小值,那么首先可以固定每个类的质心clip_image014[8],调整每个样例的所属的类别clip_image012[9]来让J函数减少,同样,固定clip_image012[10],调整每个类的质心clip_image014[9]也可以使J减小。这两个过程就是内循环中使J单调递减的过程。当J递减到最小时,clip_image018[6]和c也同时收敛。(在理论上,可以有多组不同的clip_image018[7]和c值能够使得J取得最小值,但这种现象实际上很少见)。

         由于畸变函数J是非凸函数,意味着我们不能保证取得的最小值是全局最小值,也就是说k-means对质心初始位置的选取比较感冒,但一般情况下k-means达到的局部最优已经满足需求。但如果你怕陷入局部最优,那么可以选取不同的初始值跑多遍k-means,然后取其中最小的J对应的clip_image018[8]和c输出

    二、kmeans的损失函数

    和其他机器学习算法一样,K-Means 也要评估并且最小化聚类代价,在引入 K-Means 的代价函数之前,先引入如下定义:

     引入代价函数:

     三、kmeans的优缺点

    优点:
    1)原理比较简单,实现也是很容易,收敛速度快。
    2)聚类效果较优。
    3)算法的可解释度比较强。
    4)主要需要调参的参数仅仅是簇数k。

    缺点:
    1)K值的选取不好把握
    2)对于不是凸的数据集比较难收敛
    3)如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳。
    4) 采用迭代方法,得到的结果只是局部最优

    四、kmeans参数

    sklearn.cluster.KMeans

    class sklearn.cluster.KMeans(n_clusters=8, *, init='k-means++', n_init=10, max_iter=300, tol=0.0001, 
    precompute_distances='deprecated', verbose=0, random_state=None, copy_x=True, n_jobs='deprecated', algorithm='auto')
    • n_clusters:int, default=8,簇的个数,即你想聚成几类
    • init:{'k-means++', 'random', ndarray, callable}, default=’k-means++’,初始簇中心的获取方法,'k-means ++':以一种聪明的方式为k-mean聚类选择初始聚类中心,以加快收敛速度​​。有关更多详细信息,请参见k_init中的注释部分。'random':n_clusters从初始质心的数据中随机选择观察(行)。如果传递了ndarray,则其形状应为(n_clusters,n_features),并给出初始中心。如果传递了callable,则应使用参数X,n_clusters和随机状态并返回初始化
    • n_init:int, default=10,获取初始簇中心的更迭次数,k均值算法将在不同质心种子下运行的次数
    • max_iter:int, default=300,最大迭代次数(因为kmeans算法的实现需要迭代),单次运行的k均值算法的最大迭代次数
    • tol:float, default=1e-4,容忍度,即kmeans运行准则收敛的条件,关于Frobenius范数的相对容差,该范数表示两个连续迭代的聚类中心的差异,以声明收敛
    • precompute_distances:{'auto', True, False}, default='auto',是否需要提前计算距离,这个参数会在空间和时间之间做权衡,如果是True 会把整个距离矩阵都放到内存中,auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False 时核心实现的方法是利用Cpython 来实现的
    • verbose:int, default=0,冗长模式(不太懂是啥意思,反正一般不去改默认值)
    • random_state:int, RandomState instance, default=None,确定质心初始化的随机数生成。使用整数使随机性具有确定性
    • copy_x:bool, default=True, 对是否修改数据的一个标记,如果True,即复制了就不会修改数据。bool 在scikit-learn 很多接口中都会有这个参数的,就是是否对输入数据继续copy 操作,以便不修改用户的输入数据。这个要理解Python 的内存机制才会比较清楚
    • n_job:sint, default=None,并行设置
    • algorithm:{'auto', 'full', 'elkan'}, default='auto',kmeans的实现算法,经典的EM风格算法是'full'的。通过使用三角形不等式,'elkan'变异对于定义良好的聚类的数据更有效。但是,由于分配了额外的形状数组(n_samples,n_clusters),因此需要更多的内存。目前,'auto'(保持向后兼容性)选择'elkan',但为了更好的启发式,将来可能会更改

    属性

    • cluster_centers_:ndarray(n_clusters, n_features),集群中心的坐标
    • labels_:ndarray(n_samples,),每个点的标签
    • inertia_:float,样本到其最近的聚类中心的平方距离的总和
    • n_iter_:int,运行的迭代次数

    方法

    • fit(X[, y, sample_weight]):拟合,计算k均值聚类
    • fit_predict(X[, y, sample_weight]):计算聚类中心并预测每个样本的聚类索引
    • fit_transform(X[, y, sample_weight]):计算聚类并将X转换为聚类距离空间
    • get_params([deep]):获取此估计量的参数
    • predict(X[, sample_weight]):预测X中每个样本所属的最近簇
    • score(X[, y, sample_weight]):与K均值目标上X的值相反
    • set_params(**params):设置此估算器的参数
    • transform(X):将X转换为群集距离空间

    也可以看看
    MiniBatchKMeans
    替代性在线实施,使用微型批次对中心位置进行增量更新。对于大规模学习(例如n_samples> 10k),MiniBatchKMeans可能比默认的批处理实现要快得多。

    sklearn.cluster.k_means

    sklearn.cluster.k_means(X, n_clusters, *, sample_weight=None, init='k-means++', precompute_distances='deprecated', n_init=10,
    max_iter=300, verbose=False, tol=0.0001, random_state=None, copy_x=True, n_jobs='deprecated', algorithm='auto', return_n_iter=False)
    • X:{array-like, sparse} matrix of shape (n_samples, n_features),数组,矩阵,稀疏矩阵
    • n_clusters:int
    • sample_weight:array-like of shape (n_samples,), default=None,X中每个观测值的权重。如果为None,则为所有观测值分配相等的权重
    • init:{'k-means++', 'random', ndarray, callable}, default='k-means++'
    • precompute_distances:{'auto', True, False}
    • n_init:int, default=10
    • max_iter:int, default=300
    • verbose:bool, default=False
    • tol:float, default=1e-4
    • random_state:int, RandomState instance, default=None
    • copy_x:bool, default=True
    • n_jobs:int, default=None
    • algorithm:{'auto', 'full', 'elkan'}, default='auto'
    • return_n_iter:bool, default=False

    属性

    • centroid
    • label
    • inertia
    • best_n_iter

    k_means这个是先写的,他们两的参数就相差一个数据集,不过还是建议用KMeans

    五、kmeans可视化

    使用iris数据做简单的聚类,并且画出聚类后的图片

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    from sklearn.datasets import load_iris
    from sklearn.cluster import KMeans
    
    X=load_iris().data
    kmeans = KMeans(n_clusters=3,random_state=0)
    kmeans.fit(X)
    
    labels = kmeans.labels_
    labels = pd.DataFrame(labels,columns=['labels'])
    X=pd.DataFrame(X)
    X.insert(4,'labels',labels)
    
    from sklearn.manifold import TSNE
    tsne = TSNE()
    a = tsne.fit_transform(X)
    liris = pd.DataFrame(a,index=X.index)
    
    d1 = liris[X['labels']==0]
    #plt.plot(d1[0],d1[1],'r.')
    d2 = liris[X['labels']==1]
    #plt.plot(d2[0],d2[1],'go')
    d3 = liris[X['labels']==2]
    #plt.plot(d3[0],d3[1],'b*')
    plt.plot(d1[0],d1[1],'r.',d2[0],d2[1],'go',d3[0],d3[1],'b*')

     值得注意的是,上面的可视化是将特征缩成一个值,然后在和label画图

    还有其他的可视化方法

    # 导入可视化工具包
    import matplotlib.pyplot as plt
    %matplotlib inline
    from sklearn.datasets import load_iris
    from sklearn.cluster import KMeans
    import numpy as np
    import pandas as pd
    
    X=load_iris().data
    clf = KMeans(n_clusters=3,random_state=0)
    clf.fit(X)
    label = clf.predict(X)
    
    # 颜色和标签列表
    colors_list = ['red', 'blue', 'green']
    labels_list = ['1','2','3']
    x=X
    for i in range(3):
        plt.scatter(x[label==i,0], x[label== i,1], s=100,c=colors_list[i],label=labels_list[i])
        
    # 聚类中心点
    plt.scatter(clf.cluster_centers_[:,0],clf.cluster_centers_[:,1], s=300,c='black',label='Centroids')
    
    plt.legend()
    plt.xlabel('Annual Income (k$)')
    plt.ylabel('Spending Score (1-100)')
    plt.show()

     六、获取kmeans特征权重,特征贡献度

    有时候我们需要看一下,哪个特征对kmeans贡献最大,但是如果是使用pca之后的数据做模型,那么就有点难计算,但是pca也是根据变量方差去选择,也即是说第一主成分的选择是根据最大方差去选择,了解这个或许还可以计算出来,

    但是我们主要说非pca之后的:

    #验证过,该属性确实可以计算出来
    estimator=KMeans()
    estimator.fit(X)
    res=estimator.__dict__
    print res['cluster_centers_']
  • 相关阅读:
    selenium(六)Page Object模式(使用selenium的PageFactory)
    CodeForces 1325C Ehab and Path-etic MEXs(思维)
    CodeForces 1325D Ehab the Xorcist(异或和+算数和)
    家庭房产(模拟)
    取硬币(思维)
    Xor and Sum(异或和+算术和)
    一元三次方程求解(数学、二分)
    最大最小公倍数 (数学、贪心)
    天梯---球队“食物链”(DFS+剪枝)
    HDU-4857 逃生(逆向拓扑排序)
  • 原文地址:https://www.cnblogs.com/cgmcoding/p/14070168.html
Copyright © 2011-2022 走看看