Py学习  »  机器学习算法

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

炼丹老顽童 • 5 年前 • 474 次点击  
阅读 24

【火炉炼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著,陶俊杰,陈小莉译


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/KTOgHLOz9t
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/23578
 
474 次点击