Kmeans

作者: 似海深蓝 | 来源:发表于2020-04-28 16:43 被阅读0次

    1. 语法

    class sklearn.cluster.KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm='auto')

    参数说明:
    - n_clusters=8 : K的值,我们想要将数据聚类成几类
    
    - init='k-means++': 帮助你选择初始中心点的算法.
    
    - n_init = 10: 有可能一次聚类效果不好(因为随机选择初始中心点,所以效果不稳定),重复用不同的随机数种子,聚类10次,从中找出效果最好的.
    
    - max_iter=300 : 最大迭代次数.
    
    - tol=0.0001 : 阈值,算法停止的阈值. 在迭代的过程当中, 组内距离平方和评估聚类效果,如果这个值在某次迭代过程中,下载不到这个tol的大小,那么就提前停止算法.
    
    - random_state=None: 随机数种子
    
    - verbose=0 : 模型的算法日志,数字越大代表日志越详细
    
    - n_jobs=None: 使用cpu处理器个数,-1代表适用所有核心.
    
    属性说明:
    - cluster_centers_: 聚类最终的簇中心点.
    
    - labels_: 每个样本被分到了哪一个簇中.
    
    - inertia_: 评估指标,组内距离平方和.所有点到聚类中心点的距离平方和
    
    - n_iter_ : 算法迭代次数
    

    2. 算法实现

    基本流程:导包 --> 导数据 --> 实例化 --> fit --> 画轮廓系数学习曲线 --> 找到最好K重新建模 --> 得到结果并加入源数据 --> 分析

    2.1 生成聚类模拟数据

    sklearn.datasets.make_blobs

    参数说明:
    - n_samples: 生成的数据样本个数
    
    - n_features: 有多少个特征
    
    - centers: 生成数据的中心点
    
    - cluster_std: 聚类分布的标准差
    
    - random_state : 随机数种子
    
    函数返回值returns:
    - X : 就是输入数据
    
    - y : 标签
    
    import numpy as np
    import pandas as pd
    import matplotlib.pylab as plt
    from sklearn.datasets import make_blobs
    
    # 生成四堆数据,所以四个中心点,四个标准差
    X,y = make_blobs (n_samples = 1000,
                      n_features = 2,
                      centers = [ [-1,-1],[0,0],[1,1],[2,2] ],
                      cluster_std = [0.4,0.2,0.2,0.2],
                      random_state = 666)
    
    plt.scatter(X[:,0] ,X[:,1], c=y);# 使用y标签进行颜色的映射
    
    模拟数据

    2.2 sklearn 实现Kmeans

    from sklearn.cluster import KMeans
    
    kmeans = KMeans(n_clusters = 2,random_state=666)  #k = 2
    kmeans.fit(X,y)
    
    #查看属性
    print("中心点:\n{}".format(kmeans.cluster_centers_))
    print("组内平方和:\n{}".format(kmeans.inertia_))
    print("迭代次数:\n{}".format(kmeans.n_iter_))
    
    # 结果绘图
    plt.scatter(X[:,0],X[:,1],c=kmeans.labels_)
    plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100)
    
    
    单K
    ### 观察K变化之后,聚类的结果有什么不同,分别绘制出k取3,4,5,6的图形
    plt.figure()
    
    for k in range(3,7):
        kmeans = KMeans(n_clusters = k,random_state=666)
        kmeans.fit(X,y)
        
        #绘图,子图模式需先建画板
        plt.subplot(2,2,k-2)
        plt.scatter(X[:,0],X[:,1],c=kmeans.labels_,label = "k = "+str(k))
        plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100)
        plt.legend()
    
    多K

    2.3 通过学习曲线寻找最优K值

    # 族值增加时,组内距离平方和必下降
    
    scores = []
    
    for k in range(2,10):
        kmeans = KMeans(n_clusters = k,random_state=666)
        kmeans.fit(X,y)
        
        #将不同K的组内距离平方和保存
        scores.append(kmeans.inertia_)
        
    plt.plot(range(2,10),scores) # 4为最优参数,计算量和效果的妥协
    # 再用K=4去重新建模fit就行了
    
    学习曲线

    3. 轮廓系数:评价聚类效果

    SCi = (Bi - Ai)/max(Bi,AI)

    - Ai:衡量一个点到 本 簇内其他点所有距离的 均值
     
    - Bi:衡量一个点到 离他最近的其他 簇内所有点距离的 均值
    - 一般来说,这个值如果超过0.1 ,聚类效果已经算是非常好了。
    

    三种情况:

    - 1.聚类效果很好,组内距离近,组外远,即:Bi>>Ai 则SCi = Bi/Bi 约等于1
    - 2.聚类效果非常不好,组内距离远,组外近,还不如不聚类,即:Ai>>Bi 则SCi = -Ai/Ai 约等于 -1
    - 3.SCi = 0 ,Ai = Bi 聚类无效果
    

    3.1 代码实现流程

    from sklearn.metrics import silhouette_score
    from sklearn.cluster import KMeans
    
    kmeans = KMeans(n_clusters = 3,random_state=666)  #k = 3
    kmeans.fit(X,y)
    
    # 轮廓系数:
    silhouette_score(X,kmeans.labels_)
    

    3.2 用轮廓系数进行学习曲线调参

    # 初级版
    scores = []
    
    for k in range(2,10):
        kmeans = KMeans(n_clusters = k,random_state=666)
        kmeans.fit(X,y)
        
        #将不同K的组内距离平方和保存
        scores.append(silhouette_score(X,kmeans.labels_))
        
    plt.plot(range(2,10),scores) # 4为最优参数,计算量和效果的妥协
    
    初级版
    # 高级版
    # 解决坐标轴刻度负号乱码
    plt.rcParams['axes.unicode_minus'] = False
    
    plt.rcParams["font.family"] = 'Arial Unicode MS'
    
    # 生成画布,设置大小
    plt.figure(figsize = (10,12))
    
    for k in range(2,8):
        kmeans = KMeans(n_clusters = k,random_state=666)
        kmeans.fit(X,y)
        
        #将不同K的组内距离平方和保存
        scores = silhouette_score(X,kmeans.labels_)
        # 6次循环,6张子图,参数(i,j,k) i行j列的图,K为第K个
        plt.subplot(3,2,k-1)
        plt.scatter(X[:,0],X[:,1],c=kmeans.labels_)
        plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100,label = "k = "+str(k)+"\n"+"轮廓系数 = "+str(round(scores,3)))
        plt.text(0,-2,"轮廓系数 = "+str(round(scores,3))) #参数x,y,文字
        plt.legend(loc="upper left",shadow=True,fancybox=True,fontsize=10 )
    
    高级版

    4. 真实数据集流程

    基本流程:导包 --> 导数据 --> 实例化 --> fit --> 画轮廓系数学习曲线 --> 找到最好K重新建模 --> 得到结果并加入源数据 --> 分析

    4.1 读入数据

    mall_customer = pd.read_csv("Mall_Customers.csv")
    mall_customer.head()
    

    4.2 格式化并描述数据

    # 把特征名称换成中文
    d = {'CustomerID':'用户ID',
        'Gender':'性别',
        'Age':'年龄',
        'Annual Income (k$)':'年收入',
        'Spending Score (1-100)':'花销分数'}
    mall_customer = mall_customer.rename(columns=d)
    
    数据
    # 画图描述数据
    import seaborn as sns
    # 改变画图风格
    plt.style.use('seaborn')
    #mac电脑正常显示中文
    plt.rcParams['font.family'] = ['Arial Unicode MS']
    
    # 直方图
    sns.distplot(mall_customer['年龄'],bins = 20)
    sns.distplot(mall_customer['花销分数'] , bins= 20)
    sns.distplot(mall_customer['年收入'] , bins= 20)
    
    # 性别的分布
    sns.countplot(x = '性别',data = mall_customer)
    
    直方图
    性别

    4.3 探索数据特征的性关系

    # 自动帮你统计所有两两变量之间的关系,参数:数据[多列],reg是话回归线,看线性关系
    sns.pairplot(mall_customer[['年龄','年收入','花销分数']],kind = 'reg')
    
    plt.scatter(mall_customer['年收入'],mall_customer['花销分数'])
    plt.xlabel('年收入')
    plt.ylabel('花销分数')
    

    4.4 用Kmeans聚类

    from sklearn.metrics import silhouette_score
    from sklearn.cluster import KMeans
    
    kmeans = KMeans(n_clusters = 5,random_state=666)  #k = 3
    
    # 分隔X,mall_customer['年收入']是一维数据,转成二维才能输入
    X1 = mall_customer[['年收入','花销分数']]
    kmeans.fit(X1)
    
    # 画图
    plt.scatter(X1['年收入'],X1['花销分数'],c = kmeans.labels_,cmap='rainbow')
    plt.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1],
                c = 'black',s = 100)
    plt.title('k=3')
    
    K = 3
    # 结果
    kmeans.cluster_centers_ # 中心点
    
    # 轮廓系数学习曲线
    scores = []
    
    for i in range(2,8): # 2-9
        # 实例化
        kmeans = KMeans(n_clusters=i , random_state=666)
        kmeans.fit(X1)
        
        scores.append(silhouette_score(X1 , kmeans.labels_) )
    
    #  将曲线绘制出来
    plt.plot(range(2,8) , scores); # 5对应的点最大
    
    轮廓系数学习曲线

    4.5 用三个特征聚类

    # 非标准化数据情况:
    X2 = mall_customer[['年收入','花销分数','年龄']]
    scores = []
    
    for i in range(2,10): # 2-9
        # 实例化
        kmeans = KMeans(n_clusters=i , random_state=666)
        kmeans.fit(X2)
        
        # 将轮廓系数和保存下来
        scores.append(silhouette_score(X2 , kmeans.labels_) )
        
    plt.plot(range(2,10) , scores); # 6对应的点,我们叫做拐点
    
    非标准化数据情况
    # 标准化数据情况
    from sklearn.preprocessing import MinMaxScaler
    
    minmax = MinMaxScaler()
    minmax.fit(X2)
    X2_minmax = minmax.transform(X2)
    
    scores = []
    for i in range(2,15): 
        # 实例化
        kmeans = KMeans(n_clusters=i , random_state=666)
        kmeans.fit(X2_minmax)
        
        # 将轮廓系数和保存下来
        scores.append(silhouette_score(X2_minmax , kmeans.labels_) )
        
    plt.plot(range(2,15) , scores); # 9最大,但对不标准化不明显,所以用不标准化的
    
    标准化数据情况

    4.6 确定聚合的6个簇,并添加到表

    # 实例化
    kmeans = KMeans(n_clusters=6 , random_state=666)
    kmeans.fit(X2)
    
    mall_customer['聚类结果'] = kmeans.labels_ #在此用的没标准化的数据
    
    mall_customer.聚类结果.value_counts()
    
    image.png
    mall_customer[mall_customer['聚类结果'] == 3].describe()
    
    image.png

    相关文章

      网友评论

          本文标题:Kmeans

          本文链接:https://www.haomeiwen.com/subject/azqbwhtx.html