9.1 聚类任务
聚类就是试图把数据集中的样本划分成若干个不相交的子集,每一个子集就称之为“簇”。这里需要说明一下,每个簇潜在的概念对于聚类算法而言事先都是未知的,聚类过程只能形成簇结构,簇对应的概念则要使用者来把握和命名。
假设样本集包含m个无标记样本,每个样本
是一个n维特征向量,再将样本集D划分为k个不相交的簇
,其中
且
。此外,用
表示样本
的“簇标记”,即
。聚类可以用簇标记向量
表示。
9.2 性能度量
聚类是将样本集D划分为若干互不相交的子集,即样本簇。我们一般希望同一个簇的样本尽可能相似,不同的簇尽可能不同。对于聚类性能的度量大致分为两类,即:
外部指标:将聚类结果与某个“参考模型”进行比较;
内部指标:直接考察聚类结果而不利用任何参考模型。
对于,假设聚类给出的簇划分为
,参考模型给出的簇划分为
。定义如下
其中集合包含了再
中隶属于相同簇且再
中也隶属于相同簇的样本对;其他同理。因为样本对
只能出现在一个集合中,所以就有
成立。
基于上面式子,可以得出下列常用的外部指标:
Jaccard系数
FM指数
Rand指数
显而易见,上述性能度量指标值都在[0,1]区间,值越大越好。
聚类的簇划分为,定义如下
其中,dist表示两样本之间的距离;表示簇C的中心点
。
表示簇C内样本间的平均距离,
表示簇C内样本间的最远距离,
表示簇
与簇
最近样本间的距离,
表示簇
与簇
中心点间的距离。
DB指数
Dunn指数
不难看出,DBI的值越小越好,而DI则相反,值越大越好。
9.3 距离计算
对于函数dist,如果是一个“距离度量”,则满足一些基本性质:
非负性:
同一性:当且仅当
;
对称性:;
直递性:.
假设与
,则“闵可夫斯基距离”为
当p=2时,即为欧氏距离
当p=1时,即为曼哈顿距离
连续属性:在定义域上有无穷多个可能的取值;
离散属性:在定义域上是有限个取值。
属性又可以划分为“有序属性”和“无序属性”,闵可夫斯基距离可用于有序属性,而对于无序属性,可采用VDM。
假设表示属性
上取值为
的样本数,
表示在第
个样本簇中在属性
上取值为
的样本数,
为样本簇数,那么属性
上两个离散值
和
之间的VDM距离为
当闵可夫斯基距离和VDM结合就可以处理混合属性。首先假设有个有序属性、
个无序属性,且假设有序属性在无需属性之前,则
如果样本空间不同属性的重要性不相同,那么可以进行加权,如下
9.4 原型聚类
原型聚类假设聚类结构可以用一组原型来刻画,先对原型进行初始化,然后对原型进行迭代更求解。
9.4.1 k均值算法
假设样本集,簇划分为
,那么k均值最小化平方误差为
其中是簇
的均值向量。上式描述的是簇内样本相对簇均值向量的紧密程度,E越小,那么簇内样本相似度越高。
9.4.2 高斯混合聚类
高斯混合聚类采用概率模型来表达聚类原型。对于n维样本空间中的随机向量x,若x服从高斯分布,则概率密度函数为
其中是n维均值向量,
是
的协方差矩阵。为方便表示,可将概率密度函数记为
。高斯混合分布为
该分布由k个混合成分组成,其中与
是第i个高斯混合成分的参数,而
为相应的“混合系数”,
。
令随机变量表示生成样本
的高斯混合成分。其取值未知。根据贝叶斯定理,
的后验分布对应于
给出了
由第i个高斯混合成分平生成的后验概率,简记为
。高斯混合聚类样本集D划分为k个簇
,每个样本
的簇标记
如下确定
.
采用极大似然估计来求解模型参数,如下
,
若参数能是上述式子最大化,则
有
,
以及,有
,
由可得
对于,既要最大化LL(D),又要满足
,
。LL(D)的拉格朗日形式为
,
上式对的导数为0,有
,
两边同乘以
,对所有样本求和可知
,有
,
在每一步迭代中,先根据当前参数来计算每个样本属于高斯成分的后验概率,在通过前面式子更新模型参数
。
9.5 层次聚类
层次聚类就是在不同层次对数据集进行划分,从而形成树形聚类结构。AGNES是自底向上聚合的层次聚类算法,它先把数据集样本看成初始聚类簇,接着在每一步中找出最近距离的两个聚类簇并且合并,不断重复直到达到预设聚类簇个数。假定聚类簇与
,簇的距离计算如下
最小距离:
最大距离:
平均距离:
显然,最小距离由最近样本决定,最大距离由最远样本决定,平均距离由所有样本共同决定。如图所示,AGNES算法先对仅含一个样本的初始聚类簇和相应的距离矩阵进行初始化;AGNES不断合并距离最近的聚类簇,并对合并得到的聚类簇的距离矩阵进行更新;不断重复上述过程,直到达到预设的聚类簇数。
以西瓜数据集4.0为例,令,则可得到如图所示的“树状图”,其中每层链接一组聚类簇。
将分割层逐步提升,则可以得到聚类簇逐渐减少的聚类结果,如图所示
9.6 试验
k均值算法实现实现步骤:
1.定义 k_means 函数,并且初始化聚类中心;
2.迭代执行算法,直到达到最大迭代次数或聚类中心不再变化为止;
3.计算距离并分配标签;
4.生成 300 个随机的二维数据点(范围在 0 到 1 之间);
5.设置聚类数并运行算法,最后得到可视化结果。
import numpy as np
import matplotlib.pyplot as plt
def k_means(X, k, max_iterations=100):
# 随机选择初始聚类中心
np.random.seed(42) # 为了结果可重复
centroids = X[np.random.choice(X.shape[0], k, replace=False)]
for _ in range(max_iterations):
# 计算距离并分配标签
distances = np.linalg.norm(X[:, np.newaxis] - centroids, axis=2)
labels = np.argmin(distances, axis=1)
# 更新聚类中心
new_centroids = np.array([X[labels == i].mean(axis=0) for i in range(k)])
# 检查聚类中心是否有变化
if np.all(centroids == new_centroids):
break
centroids = new_centroids
return centroids, labels
# 生成示例数据
np.random.seed(42)
X = np.random.rand(300, 2)
# 设定聚类数
k = 3
# 运行k均值算法
centroids, labels = k_means(X, k)
# 绘制结果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', marker='o')
plt.scatter(centroids[:, 0], centroids[:, 1], color='red', marker='X', s=200, label='Centroids')
plt.title('K-Means Clustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.show()
k均值算法运行结果