学习目标:
1、k-means:模型原理、收敛过程、超参数的选择
2、代码实现
学习内容:
【1】
模型原理:k-means算法将将训练集分成k个靠近彼此的不同样本聚类。对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。
聚类试图将数据集中的样本划分为若干个通常是不相交的子集,每个子集成为一个“簇”。通过这样的划分,每个簇可能对应于一些潜在的概念(也就是类别),如“浅色瓜” “深色瓜”,“有籽瓜” “无籽瓜”,甚至“本地瓜” “外地瓜”等;需说明的是,这些概念对聚类算法而言事先是未知的,聚类过程仅能自动形成簇结构,簇对应的概念语义由使用者来把握和命名。
优点:
1、 简单,易于理解和实现
2、 收敛快,一般仅需5-10次迭代即可,高效
缺点:
1、对K值得选取把握不同对结果有很大的不同
2、对于初始点的选取敏感,不同的随机初始点得到的聚类结果可能完全不同
3、对于不是凸的数据集比较难收敛
4、对噪点过于敏感,因为算法是根据基于均值的
5、结果不一定是全局最优,只能保证局部最优
6、对球形簇的分组效果较好,对非球型簇、不同尺寸、不同密度的簇分组效果不好。
收敛过程:
选择K个点作为初始质心
repeat
将每个点指派到最近的质心,形成K个簇
重新计算每个簇的质心
until 簇不发生变化或达到最大迭代次数
输入:
样本集D={};
聚类簇数k
过程:
从D中随机选择k个样本作为初始均值向量{}
repeat
令C=空集(1<=i<=k)
for j=1,2,...m do
计算样本x与各均值向量μ
(1<=i<=k)的距离:d
=||x
-μ
||
;
根据距离最近的均值向量确定x的簇标记:λ
=argmin
∈{1,2,...,k}d
;
将样本x划入相应的的簇:C
=C
∪{x
};
end for
for i=1,2,...k do
计算新均值向量:
if then
将当前均值向量μ更新为
else
保持当前均值向量不变
end if
end for
until 当前均值向量未更新
输出:簇划分C={}
超参数的选择:
可优化的 K-Means 超参数
使用以下超参数优化 Amazon SageMaker k-means 模型。对 k-means 目标指标影响最大的超参数为:mini_batch_size
、extra_center_factor
和 init_method
。优化超参数 epochs
通常会得到较小的改进。
参数名称 | 参数类型建 | 议的范围 |
epochs | IntegerParameterRanges | 最小值:1 最大值:10 |
extra_center_factor | IntegerParameterRanges | 最小值:4 最大值:10 |
init_method | CategoricalParameterRanges | ['kmeans++', 'random'] |
mini_batch_size | IntegerParameterRanges | 最小值:3000 最大值:15000 |
【2】
# dataSet样本点,k 簇的个数
# disMeas距离量度,默认为欧几里得距离
# createCent,初始点的选取
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0] #样本数
clusterAssment = mat(zeros((m,2))) #m*2的矩阵
centroids = createCent(dataSet, k) #初始化k个中心
clusterChanged = True
while clusterChanged: #当聚类不再变化
clusterChanged = False
for i in range(m):
minDist = inf; minIndex = -1
for j in range(k): #找到最近的质心
distJI = distMeas(centroids[j,:],dataSet[i,:])
if distJI < minDist:
minDist = distJI; minIndex = j
if clusterAssment[i,0] != minIndex: clusterChanged = True
# 第1列为所属质心,第2列为距离
clusterAssment[i,:] = minIndex,minDist**2
print centroids
# 更改质心位置
for cent in range(k):
ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
centroids[cent,:] = mean(ptsInClust, axis=0)
return centroids, clusterAssment