1,简介
k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是,预将数据分为K组,则随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。
2,注意点
k均值算法常用欧氏距离作为样本之间距离的度量:
其中m是数据本身的维数(例如(1,2)就是二维)
3,算法过程将所需分类的样本输入
1,初始化:随机选择k个样本作为初始聚类中心
2,开始对样本进行聚类:对所选取的样本中心,计算每个样本到所有聚类中心的聚类,将每个样本分类到所属样本中心中,构成聚类结果
3,计算新的类中心:对于聚类结果,重新计算当前各聚类中样本的均值,作为新的类中心
4,重复2,3步,直到迭代收敛或者符合停止条件。
3.1 K值的确定
经验法:结合实际情况确定选取K值
肘部法则:将K值的损失函数刻画出来。随着K值的增加,每个类得平均损失会随之降低,每个聚类包含的样本数量会减少,平均损失函数的改善效果会降低。平均损失函数下降幅度最大时,K值最好
规则法:k=(n/2)^(1/2) 就是将n除以2开根号
损失函数:
3.2 K均值的缺点
K-means虽然是一种极为高效的聚类算法,但是它存在诸多问题
1.初始聚类点的并不明确,传统的K均值聚类采用随机选取中心点,但是有很大的可能在初始时就出现病态聚类,因为在中心点随机选取时,很有可能出现两个中心点距离过近的情况。
2.k-means无法指出应该划分多少类别。在同一组数据集中划分不同数量的类别的含义以及意义是完全不同的。
3.3 算法的实现
import numpy as np
class Kmeans:
def __init__(self, k):
self.k = k
self.cendroids = None
def distance(self, x1, x2):
return np.sqrt(np.sum(np.square(x1 - x2), axis=-1))
def fit(self, X, max_iter=500):
'''
Input: X: np.array, shape=[N, dim]
output: cluster: np.array, shape=[N,]
'''
N, dim = X.shape
# 随机选择样本作为初始簇中心
cendroids = np.zeros((self.k, dim))
for i in range(k):
cendroids[i, :] = X[int(np.random.uniform(0, N)), :]
# 迭代
for _ in range(max_iter):
pre_cendroids = cendroids
distances = self.distances(X[:, None, :], cendroids[None, :, :]) clusters = np.argmin(distances, axis=1)
for k in range(self.k):
cendroids[k, :] = np.mean(X[clusters == k, :])
if pre_cendroids == cendroids:
break
self.cendroids = cendroids
return clusters
模型优化以及思考
k-means算法严重问题之一就是初始点的选取问题,在此处,也许会有优化之处,此处提出两点优化。
1.第一种优化方式在第一个点的选取处进行优化,第一个点可以挑选密度最大处的中心点,从而避免了出现离群点的问题,但是在此方法中选取我们需要选择一个合适区域(或者说选取合适的半径).第二个点则需要选取距离此点最远的点最为第二个中心点。第三个点则选取距离两点最远的点作为第三个点。以此类推,直到选取出K个初始聚类中心。
2.第二种改进方式是选取出密度最大的点,然后减去它周围最近的n个点(n的值是数据总数除以K),然后再找到剩余数据中密度最大的点,再减去它周围的n个点,以此类推,直到选取完成,此方法的局限性很大,基本选取完成之后,聚类的簇已经非常明显了。而且一般适用于三维以下的数据,三维以下的数据均可以在图像中表示出来,但四维以上的数据很难直观的观察。
k-means算法选取初始点k值的简单方法
在使用k-means算法时我们很难根据经验法对k值进行确定,而且在一般的比赛中使用经验法是极其不现实的。因此,我们可以观察不同k值情况下,每个簇中每个点到中心点的平均距离,当k的值大于真实数目时,平均距离上升速度会上升的很缓慢,但是当k值小于真实数目时,平均距离会急剧上升。
总结的来说k-means算法的优势还是很大的,它适用于大数据集,而且简单高效,当簇接近高斯分布时,效果非常显著。但是k-means的局限性很大,很多情况下均不适用,它需要将簇的平均值进行定义,而且k值需要事先给定,k值的选取非常的麻烦,繁琐。而且需要根据第一个初始聚类中心进行初始划分,然后进行后续的划分,初始聚类中心的影响非常大。
个人对大家的建议是,在比赛中k-means算法在特殊的题型中会起到点睛之笔的作用,但是一般的数据分析类题目中,k-means的局限性太大不建议大家强行使用。
大家有需要可以关注一下公众号哈