文章目录
一、什么是K-means 聚类算法?
- K-Means 是 Python 中非常流行的一个聚类算法,它属于无监督学习算法的一种。在 scikit-learn(一个广泛使用的机器学习库)中,KMeans 类用于执行 K-均值聚类。K-均值聚类是一种将数据点分成 K 个簇的算法,其中每个簇由簇内数据点的均值(即“质心”)定义。
- 基本原理
- 初始化:首先,算法随机选择 K 个点作为初始的簇质心(如动图中的X点)。
- 分配:然后,算法将每个数据点分配到最近的簇质心,形成 K 个簇。
- 满足条件:所有的数据点到质心的距离(使用欧氏距离)之和是最小的
- 更新:接着,算法重新计算每个簇的质心,即计算簇内所有点的均值。
- 迭代:重复分配和更新步骤,直到簇质心的位置不再发生显著变化,或者达到预设的迭代次数。
- 动图解释
二、聚类效果评价方式——轮廓系数
- metrics.silhouette_score 是 Scikit-learn(一个流行的 Python 机器学习库)中用于评估聚类效果好坏的一个指标。它衡量了聚类内样本的相似度与聚类间样本的不相似度,其值范围从 -1 到 1。
- 原理:
- Silhouette Score(轮廓系数)结合了凝聚度和分离度两种因素。对于单个样本,其轮廓系数定义为:
- a 是样本与同一聚类中其他样本的平均距离(即样本的凝聚度或内聚度)
- b 是样本与最近聚类中所有样本的平均距离(即样本的分离度)
- Silhouette Score(轮廓系数)结合了凝聚度和分离度两种因素。对于单个样本,其轮廓系数定义为:
- 整个数据集的轮廓系数是所有样本轮廓系数的平均值
- 如何判断聚类效果好坏:
- 值接近 1 :表示样本远离其他聚类,且聚类内部紧密。这是聚类效果好的标志。
- 值接近 0 :表示样本位于两个聚类之间。
- 值为负 :表示样本被分配到了错误的聚类中,因为该样本与其聚类内的平均距离大于它与最近聚类中样本的平均距离。
三、示例:代码实现
-
python中的 class sklearn.cluster.KMeans 方法用于实现K-means 聚类算法
-
它有以下一些参数:
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 :
- n_clusters: 类中心的个数,就是要聚成几类。(默认是8个)
-
数据集介绍
- 下面是一份含有20个不同的酒,且每瓶酒都有四个相同属性的数据
- 通过对四个属性的模型训练,将这些酒进行聚类
- 数据的第一行为列名,第一列为酒的名字
-
1、读取数据并获取训练数据
import pandas as pd # 注意这里读取文本数据时,需要指定,数据之间是以什么进行分隔的 data = pd.read_table('data.txt', sep=' ', encoding='utf8', engine='python') # 通过传入变量(列名)获取训练数据 x = data[['calories', 'sodium', 'alcohol', 'cost']]
-
2、循环找到合适的K值(簇数)
- 循环不同的K值,通过比较轮廓系数的大小确定出最优K值
from sklearn.cluster import KMeans from sklearn import metrics scores = [] for k in range(2, 10): # 寻找合适的k值(簇数) labels = KMeans(n_clusters=k).fit(x).labels_ # .labels_ 获取训练后各样本对应的分类标签 score = metrics.silhouette_score(x, labels) # 轮廓系数 scores.append(score) # 将每次循环得到的轮廓系数存放在scores列表中 print(scores) import numpy as np best_k = range(2, 10)[np.argmax(scores)] # 找到scores中最大的值对应的K值 print("最优k值为:{}".format(best_k))
- 结果:
-
3、可视化不同K值下,轮廓系数的大小
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文 # 为了坐标轴负号正常显示。matplotlib默认不支持中文,设置中文字体后,负号会显示异常。需要手动将坐标轴负号设为False才能正常显示负号。 plt.rcParams['axes.unicode_minus'] = False plt.plot(list(range(2, 10)), scores) plt.xlabel('K值(簇数)') plt.ylabel('轮廓系数') plt.show()
- 结果:
-
4、在最优K值下训练模型,并计算出轮廓系数
from sklearn.cluster import KMeans from sklearn import metrics km = KMeans(n_clusters=2).fit(x) data['cluster'] = km.labels_ # 为原数据增加一个新列用于存放训练得出的每个样本的类标签 score = metrics.silhouette_score(x, data.cluster) # 计算轮廓系数 print(score)
- 结果:
- 可以看出K-means 聚类算法的效果并不是太好,存在各种因素的影响,有待我们进一步的学习与思考
- 结果:
四、聚类算法的优缺点
- 优点:
- 无监督学习,不需要事先标记的数据。
- 能够发现数据中的隐藏模式和结构。
- 适用于多种数据类型和领域。
- 缺点:
- 需要选择合适的聚类算法和参数,这往往依赖于数据的特性和问题的需求。
- 聚类结果可能受到初始条件(如K-means的初始质心选择)的影响。
- 对于复杂形状和密度的簇,可能需要更复杂的聚类算法或参数调整。