目录
算法原理
算法步骤
算法API
算法导入
API参数理解
算法实现
算法原理
Kmeans 算法是一种无监督的聚类算法,目的是将数据集中的样本划分到 K 个不同的簇中。
聚类:将数据集中相似的数据点归为一组或一个簇的过程。
数据集:一组相关的数据的集合。
样本:数据集中的单个数据点。
簇:通过聚类算法划分出来的具有相似特征的数据点的集合。
算法步骤
-
初始化:随机选择 K 个数据点作为初始的簇中心(也称为质心)。
-
分配数据点:对于数据集中的每个数据点,计算它到 K 个质心的距离,将其分配到距离最近的质心所代表的簇。
-
更新质心:对于每个簇,重新计算质心,即该簇中所有数据点的均值。
-
重复步骤 2 和 3,直到质心不再发生明显变化或者达到预定的迭代次数。
算法API
算法导入
from sklearn.cluster import KMeans
API参数理解
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’)[[source]]
n_clusters:类中心的个数,就是要聚成几类。【默认是8个】
init:参初始化的方法,默认为k-means++
(1)k-means++: 用一种特殊的方法选定初始质心从而能加速迭代过程的收敛.
(2) random: 随机从训练数据中选取初始质心。
(3) 如果传递的是一个ndarray,则应该形如 (n_clusters, n_features) 并给出初始质心。
n_init: 整形,缺省值=10,用不同的质心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果。
max_iter:int,default=300,执行一次k-means算法所进行的最大迭代数。
Tol:与inertia结合来确定收敛条件。
precompute_distances:三个可选值,‘auto’,True 或者 False。
预计算距离,计算速度更快但占用更多内存。
(1)‘auto’:如果样本数乘以聚类数大于12million 的话则不预计算距离。
(2)True:总是预先计算距离。
(3)False:永远不预先计算距离。
verbose:整形,默认值=0
random_state :随机状态
copy_x:布尔型,默认值=True
当我们precomputing distances时,将数据中心化会得到更准确的结果。如果把此参数值设为True,则原始数据不会被改变。如果是False,则会直接在原始数据上做修改并在函数返回值时将其还原。但是在计算过程中由于有对数据均值的加减运算,所以数据返回后,原始数据和计算前可能会有细小差别。
algorithm:'auto','full' or 'elkan'.默认为'auto' full:采用经典的EM算法 elkan:通过使用三角不等式从而更有效,但不支持稀疏数据 auto:数据稀疏选择full模式,数据稠密选择elkan模式
【属性】
cluster_centers_: 一个n-clusters*n_features的矩阵,表示聚类中心的坐标
Labels_:每个点的分类标签。
inertia_:float形每个点到其簇的质心的距离之和。
n_iter_ : int迭代次数。
算法实现
下面是一个啤酒数据集data.txt为例子,请用K-Means算法根据不同啤酒的不同指标对啤酒进行聚类
思路:
-
从文件中读取数据,提取特征,然后使用
KMeans
算法对不同的k
值(从 2 到 9)进行聚类,并计算每个k
值下的轮廓系数得分,存储在scores
列表中。 -
绘制出
k
值和轮廓系数得分的关系图,以直观地观察不同k
值下的聚类效果。 -
接着,使用
max(scores)
找到scores
列表中的最大值,scores.index(max(scores))
找到该最大值在scores
列表中的索引。由于k
从 2 开始,而列表索引从 0 开始,所以需要将索引加 2 得到最优的k
值,存储在best_k_index
中。 -
最后,使用
KMeans
算法进行聚类,将n_clusters
参数设置为best_k_index
进行聚类,并将聚类结果存储在beer
数据集的cluster
列中。然后计算聚类结果的轮廓系数得分,以评估聚类的质量。
import pandas as pd
from sklearn.cluster import KMeans
from sklearn import metrics
import matplotlib.pyplot as plt
# 读取文本文件 data.txt,文件中数据使用空格分隔,编码为 utf8,使用 python 引擎解析
beer = pd.read_table('data.txt', sep=' ', encoding='utf8', engine='python')
# 选取 beer 数据集中的 "calories","sodium","alcohol","cost" 列作为特征
X = beer[["calories", "sodium", "alcohol", "cost"]]
# 打印 beer 数据集的前几行
print(beer.head())
# 根据分成不同的簇,自动计算轮廓系数得分
scores = []
# 尝试不同的簇数量,从 2 到 9
for k in range(2, 10):
# 使用 KMeans 算法进行聚类,聚类簇的数量为 k
labels = KMeans(n_clusters=k).fit(X).labels_
# 计算轮廓系数得分
score = metrics.silhouette_score(X, labels)
# 将得分添加到 scores 列表中
scores.append(score)
print(scores)
# 绘制得分结果
# 绘制簇数量从 2 到 9 与对应的轮廓系数得分的折线图
plt.plot(list(range(2, 10)), scores)
# 设置 x 轴标签
plt.xlabel('Number of Clusters Initialized')
# 设置 y 轴标签
plt.ylabel('Sihouette Score')
# 显示图形
plt.show()
# 找到最优的簇数量
best_k_index = scores.index(max(scores)) + 2
print(f"最优的簇数量: {best_k_index}")
# 使用 KMeans 算法进行聚类,聚类簇的数量为最优的簇数量
km = KMeans(n_clusters=best_k_index).fit(X)
# 将聚类结果存储在 beer 数据集的 'cluster' 列中
beer['cluster'] = km.labels_
# 对聚类结果进行评分
# 计算轮廓系数得分,使用 beer['cluster'] 来访问 cluster 列的数据
score = metrics.silhouette_score(X, beer['cluster'])
print(f'最优的簇数量得分:{score}')