zoukankan      html  css  js  c++  java
  • 【火炉炼AI】机器学习024-无监督学习模型的性能评估--轮廓系数

    【火炉炼AI】机器学习024-无监督学习模型的性能评估--轮廓系数

    (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

    前面我们学习过监督学习模型的性能评估,由于数据集有标记,所以我们可以将模型预测值和真实的标记做比较,计算两者之间的差异,从而来评估监督学习模型的好坏。

    但是,对于无监督学习模型,由于没有标记数据,我们该怎么样评估一个模型的好坏了?显然,此时我们不能采用和监督学习模型一样的评估方式了,而要另辟蹊径。


    1. 度量聚类模型的好坏---轮廓系数

    有很多种度量聚类模型的算法,其中一个比较好用的算法就是轮廓系数(Silhouette Coefficient)指标。这个指标度量模型将数据集分类的离散程度,即判断数据集是否分离的合理,判断一个集群中的数据点是不是足够紧密(即内聚度),一个集群中的点和其他集群中的点相隔是否足够远(即分离度),故而轮廓系数结合了内聚度和分离度这两种因素,可以用来在相同原始数据的基础上用来评价不同算法,或者算法不同运行方式对聚类结果所产生的影响。

    以下是百度对轮廓系数的说明,此处我直接搬过来用了。

    轮廓系数的计算方式说明


    2. 使用轮廓系数评估K-means模型

    首先是用pandas加载数据集,查看数据集加载是否正确,这部分可以看我的具体代码,此处省略。

    然后我随机的构建一个K-means模型,用这个模型来训练数据集,并用轮廓系数来评估该模型的优虐,代码如下:

    from sklearn.cluster import KMeans
    # 构建一个聚类模型,此处用K-means算法
    model=KMeans(init='k-means++',n_clusters=3,n_init=10) 
    # 原始K-means算法最开始随机选取数据集中K个点作为聚类中心,
    # 分类结果会因为初始点的选取不同而有所区别
    # 而K-means++算法改变这种随机选取方法,能显著的改善分类结果的最终误差
    # 此处我随机的指定n_cluster=3,看看评估结果
    model.fit(dataset)
    
    # 使用轮廓系数评估模型的优虐
    from sklearn.metrics import silhouette_score
    si_score=silhouette_score(dataset,model.labels_,
                              metric='euclidean',sample_size=len(dataset))
    print('si_score: {:.4f}'.format(si_score))
    

    -------------------------------------输---------出--------------------------------

    si_score: 0.5572

    --------------------------------------------完-------------------------------------

    从上面的代码可以看出,计算轮廓系数是非常简单的。

    ########################小**********结###############################

    1, sklearn中已经集成了轮廓系数的计算方法,我们只需要调用该函数即可,使用非常简单。

    2, 有了模型的评估指标,我们就可以对模型进行一些优化,提升模型的性能,或者用该指标来比较两个不同模型在相同数据集上的效果,从而为我们选择模型提供指导。

    #################################################################


    3. K-means模型性能的提升方法

    上面在评价K-means模型时,我们随机指定了划分的族群数量,即K值,但是有了评估指标之后,我们就可以优化这个K值,其基本思路是:遍历各种可能的K值,计算每种K值之下的轮廓系数,选择轮廓系数最大的K值,即为最优的族群数量。

    下面我先定义一个函数,专门用来计算K-means算法的最优K值,这个函数具有一定的通用性,也可以用于其它场合。如下为代码:

    # K-means模型的提升
    # 在定义K-means时,往往我们很难知道最优的簇群数量,即K值,
    # 故而可以通过遍历得到最优值
    def get_optimal_K(dataset,K_list=None):
        k_lists=K_list if K_list else range(2,15)
        scores=[]
        for k in k_lists:
            kmeans=KMeans(init='k-means++',n_clusters=k,n_init=10)
            kmeans.fit(dataset)
            scores.append(silhouette_score(dataset,kmeans.labels_,
                                          metric='euclidean',
                                          sample_size=len(dataset)))
        return k_lists[scores.index(max(scores))],scores
    

    有了这个通用性求解最优K值的函数,我们就可以用来获取这个数据集的最佳K值,如下为代码:

    optimal_K, scores=get_optimal_K(dataset)
    print('optimal_K is: {}, all scores: {}'.format(optimal_K,scores))
    
    # or:
    # optimal_K, scores=get_optimal_K(dataset,[2,4,6,8,10,12])
    # print('optimal_K is: {}, all scores: {}'.format(optimal_K,scores))
    

    -------------------------------------输---------出--------------------------------

    optimal_K is: 5, all scores: [0.5290397175472954, 0.5551898802099927, 0.5832757517829593, 0.6582796909760834, 0.5823584119482567, 0.5238070812131604, 0.4674788136779971, 0.38754867890367795, 0.41013511008667664, 0.41972398760085106, 0.41614459998617975, 0.3485105795903397, 0.357222732243728]

    --------------------------------------------完-------------------------------------

    从上面的结果可以看出,函数计算出来的最优K值为5,即最好的情况是将本数据集划分为5个类别,且在K=5时的轮廓系数为0.6583。

    下面我们来看一下这个数据集在平面上的分布情况,看看是不是数据集有5种类别,如下所示是使用visual_2D_dataset()函数之后得到的平面分布图。

    本项目数据集在二维平面上的分布情况

    从上图中可以看出,的确数据集中到五个不同的簇群中。那么用最优的参数来聚类这些数据集,得到什么样的效果了?如下是平面的聚类效果图。

    使用最优K参数来聚类数据得到的效果图

    ########################小**********结###############################

    1, 使用轮廓系数可以对模型进行参数优化,此处我们定义了一个通用性函数,可以直接计算出数据集的最佳K值。

    2, 当然,也可以用轮廓系数来优化其他参数,只要稍微修改一下上面的通用函数即可。

    #################################################################


    注:本部分代码已经全部上传到(我的github)上,欢迎下载。

    参考资料:

    1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

  • 相关阅读:
    Rust语言环境配置;Rust版本1.45.2学习
    《代码英雄》系列整理
    Pingcap High Performance TiDB 课程学习记录@yaowenxu
    11. C语言百钱买百鸡问题(详解版)
    10. C语言输出菱形(详解版)
    9. C语言判断素数(求素数)(两种方法)
    8. C语言求圆周率π(三种方法)
    7. C语言杨辉三角(两种方法)
    6. C语言九九乘法表(五种输出形式)
    5. C语言希尔排序算法
  • 原文地址:https://www.cnblogs.com/RayDean/p/9765722.html
Copyright © 2011-2022 走看看