Kmeans算法
1.应用场景
- 文档分类器:根据标签、主题和文档内容将文档分为多个不同的类别。
- 客户分类:利用消费者的购买行为、偏好等数据,K-means能将客户分为不同的群体,帮助企业实施精细化营销策略,提升用户体验和销售效率。
- 社交网络分析:分析用户的行为模式、兴趣爱好等,将用户聚类为不同的社群,便于个性化推荐和社区管理。
2.算法区别
2.1.无监督学习与聚类算法理论的区别
- 有监督学习模型算法
- 模型需要的样本数据即需要有特征矩阵X,也需要有真实的标签y。
- 无监督学习模型算法
- 模型只需要使用特征矩阵X即可,不需要真实的标签y,聚类算法是无监督学习中的代表之一。
- 聚类算法
- 将数据划分成有意义或有用的组(或簇)。
2.2.聚类和分类算法的区别
3.Kmeans算法原理
3.1算法属性含义
属性 | 含义 |
---|---|
簇 | Kmeans 算法将一组N 个样本的特征矩阵X 划分为K 个无交集的簇,直观上看来簇是一个又一个聚集一起的数据,在一个簇中的数据就认为是同一类,簇就是聚类的结果表现 |
质心 | 每个簇中所有数据的均值u 通常被称为这个簇的"质心" 在二维平面中,簇的质心横坐标是横坐标的均值,质心的纵坐标是纵坐标的均值,同理可以推广到高维空间 |
-
簇的个数
k
是一个超参数。 -
算法迭代过程
- 随机抽取
k
个样本作为最初的质心 - 计算每个样本点与
k
个质心的距离,将样本点分配到最近的一个质心,生成k
个簇 - 对于每个簇,计算所有被分该簇的样本点的平均值作为新的质心
- 当质心的位置不再发生变化,迭代结束,聚类完成
- 如图所示【将数据分成4簇,白色x代表质心】
- 随机抽取
3.2 算法结果预测
Kmeans
算法通常不需要预测结果,因为该算法本质上是在对未知分类数据的探索,但是在某些情况下我们可以使用predict进行预测操作- 当数据太大的时候预测
- 不必使用所有的数据寻找质心,少量的数据就可以帮助我们确定质心
- 数据量非常大时,可以使用部分数据确认质心
- 剩下的数据的聚类结果,使用predict来调用
- 当我们不要求那么精确,或者我们的数据量实在太大,可以使用
predict
方法。如果数据量还行,直接使用fit
后调用labels_
查看聚类结果
3.3 Kmeans
有损失函数吗?
-
有,
Kmeans
追求的是,求解能够让簇内平方和最小化的质心。在质心不断变化不断迭代的过程中,整体平方和是越来越小的,当整体平方和最小的时候,质心就不再发生变化了,即求解问题,变成了最优化问题- 在
Kmeans
中,在一个固定的簇数k下,最小化整体平方和来求解最佳质心,并基于质心的存在去进行聚类,并且,整体距离平方和的最小值可以使用梯度下降来求解,因此有人认为:簇内平方和或整体平方和是Kmeans
的损失函数
- 在
-
没有
- 损失函数本质是用来衡量模型的拟合效果(损失越小,模拟的拟合效果越好),只有有求解参数需求的算法,才会有损失函数,
Kmeans
不求解参数,它的本质也不是在拟合数据,而是对数据进行一种探索。所以有些人认为:Kmeans
不存在损失函数,整体平方和更像是Kmeans
的模型评估指标,而非损失函数
- 损失函数本质是用来衡量模型的拟合效果(损失越小,模拟的拟合效果越好),只有有求解参数需求的算法,才会有损失函数,
3.4 优点与缺点
- 优点
- 简单,快速,适合常规数据集
- 缺点
- K值难确定
- 复杂度与样本呈线性关系
- 很难发现任意形状的簇
4.距离的衡量
-
聚类算法追求"簇内差异小,簇外差异大"【差异:由样本点到其所在簇的质心的距离来衡量】
-
同一个簇,所有样本点到质心的距离之和
越小
,认为簇中的样本越相似
,簇内差异就越小
。 -
距离的衡量【常用欧几里得距离和余弦相似度(先标准化)】
公式参数 | 含义 |
---|---|
x | 每个样本点 |
u | 质心 |
n | 每个样本点中的特征数目 |
i | 组成点的每个特征 |
-
簇内平方和
- 常采用欧几里得距离,一个簇中所有样本点到质心的距离的平方和为簇内平方和。簇内平方和可以表示簇内差异的大小
-
整体平方和
- 将一个数据集中所有簇的簇内平方和相加,得到整体平方和(
Total Cluster Sum of Square
),又叫做total inertia
。Total Inertia
越小,代表每个簇内样本越相似,聚类效果就越好
- 将一个数据集中所有簇的簇内平方和相加,得到整体平方和(
5.代码实现
from sklearn import cluster.KMeans
KMeans(
n_clusters=8,
init='k-means++',
n_init=10,
max_iter=300,
tol=0.0001,
precompute_distances='auto',
verbase=0,
random_state=None,
copy_x=True,
n_jobs=None,
algorthm='auto'
)
-
参数
参数 含义 n_clusters
是 KMeans
中的k,表示模型要分几类,必填参数,默认为8类,通常的聚类结果会是一个小于8的结果,在聚类之前,不知道n_clusters
是多少,即要对它进行探索random_state
初始化质心的生成器 -
属性
属性 含义 labels_
查看聚好的类别,每个样本所对应的类 cluster_centers_
查看质心坐标 intertia_
查看总距离平方和 -
拿到一个数据集,我们希望能够通过绘图先观察一下这个数据集的数据分布,以此来为我们聚类时输入的n_clusters做一个参考,自己创建一个数据集
make_blobs
,自己创建的,有标签from sklearn.datasets import make_blobs import matplotlib.pyplot as plt #自己创建数据集,特征维度为2,质心为4,分4类,500个样本 X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1) color=['red','pink','orange','gray'] fig,ax1=plt.subplots(1) for i in range(4): ax1.scatter( X[y==i,0], X[y==i,1], marker='o',#点的形状 s=8,#点的大小 c=color[i] #颜色 ) plt.show()
-
基于这个分布,使用
kmeans
,假设数据有3簇#假设为3簇 from sklearn.cluster import KMeans from sklearn.datasets import make_blobs #自己创建数据集,特征维度为2,质心为4,分4类,500个样本 X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1) n_clusters = 3 cluster = KMeans(n_clusters=n_clusters,random_state=0).fit(X) y_pred=cluster.labels_ #重要属性,查看聚好的类别,每个样本所对应的类 centroid=cluster.cluster_centers_ #重要属性查看质心 # array([[-8.0807047 , -3.50729701], # [-1.54234022, 4.43517599], # [-7.11207261, -8.09458846]]) inertia=cluster.inertia_ #重要属性,查看总距离平方和 # 1903.4503741659223
-
画图,显示质心
from sklearn.cluster import KMeans from sklearn.datasets import make_blobs #自己创建数据集,特征维度为2,质心为4,分4类,500个样本 X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1) n_clusters = 3 cluster = KMeans(n_clusters=n_clusters,random_state=0).fit(X) centroid=cluster.cluster_centers_ #重要属性查看质心 color=['red','pink','orange','gray'] fig,ax1=plt.subplots(1) for i in range(n_clusters): ax1.scatter(X[y_pred==i,0],X[y_pred==i,1],marker='o',s=8,c=color[i]) ax1.scatter(centroid[:,0],centroid[:,1],marker='x',s=15,c='black') plt.show()
-
使用部分数据
from sklearn.cluster import KMeans from sklearn.datasets import make_blobs X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1) n_clusters=3 cluster=KMeans(n_clusters=n_clusters,random_state=0).fit(X) y_pred=cluster.labels_ #重要属性,查看聚好的类别,每个样本所对应的类 cluster_smallsub=KMeans(n_clusters=n_clusters,random_state=0).fit(X[:200]) #使用模型对X进行分类预测 y_pred_ = cluster_smallsub.predict(X) (y_pred==y_pred_).sum()