明天我们将介绍机器学习专题的第12篇文章,主题是Kmeans聚类算法。
在上一篇文章中,我们探讨了KNN算法。KNN算法通过距离公式找到最近的K个邻居,从而推测当前数据的结果。明天我们要讲的算法同样直观,是经典的聚类算法之一——Kmeans。
我们知道,在英文中Means意为平均,因此Kmeans有时也被译作K-均值算法。无论哪种叫法,它们都利用求均值的方式对样本进行分类。
既然Kmeans算法与均值和分类有关,那么接下来的问题有两个:如何计算均值,以及在获取均值后如何进行分类?
我们暂时不讨论这些问题,先来看一个实例。假设我们有一批用户的消费数据,希望通过这些数据将用户分为富人、中产和工薪阶层。
在这个例子中,我们已知要分成三类,但具体如何分却不明确。这就是我们需要模型解决的问题。我们希望模型能够识别出数据间的关联,将具有强关联性的数据归为一类。在这个例子中,我们希望模型将数据分为三个类别。
如果我们自己来分这个问题并不难,只需要根据用户的消费数据绘制折线图,找出最佳的分割点即可。但如果缺少消费数据,例如只知道用户是否有车、是否有房,或者家庭存款和负债情况,虽然不如消费数据直观,但仍然可以通过简单的建模解决。再进一步,如果我们只有用户的工作地点和居住地的信息,这个问题就会变得更加抽象。
当特征变得抽象和模糊时,直接划分数据就会变得困难。因为我们没有明确的标签,无法使用监督学习模型。为了解决这个问题,Kmeans采取了反向思维,不再对数据进行划分,而是让相似的数据自行聚集在一起。Kmeans算法正是基于这一思想,让数据通过某种算法聚集,而不进行划分。
不知道大家是否听说过这样一个观点:人类和计算机其实是相反的。有些对人类来说简单的问题,对计算机而言却很难,比如视觉和创作;而有些对人类来说复杂的问题,对计算机来说却相对简单,比如记忆和计算。
尽管如此,我们仍然可以利用计算机的优势。例如,人类可以轻易分辨图片中的猫和狗,但对于计算机来说,这并不容易。即使在深度学习和人工智能大行其道的今天,我们也需要专门设计复杂的模型和大量数据训练,才能让计算机学会分辨图像内容。
Kmeans算法正是基于这种朴素但有效的方法。算法并不知道要分成几类,我们提供多少类它就分成多少类。我们假设已经知道数据需要分成三类,那么Kmeans是如何实现这一目标的?
我们思考后发现,虽然我们提到要量化密度,但直接量化密度并不容易,因为密度本身是在聚类完成后确定的。所以,Kmeans采用了一种反向思维,先聚类再计算密度,根据密度结果进行调整。
算法运行之初,Kmeans会在数据集中随机选择K个中心点,然后根据这些中心点进行聚类。虽然初始选择的中心点可能不准确,但没关系,我们可以通过不断迭代优化聚类结果。
在详细介绍迭代方法之前,我们先分析一下情况。由于初始中心点是随机选择的,聚类结果肯定不准确。问题在于,随机选择的中心点离实际类簇太远。因此,我们需要让中心点逐渐靠近类簇。
我们可以通过观察完美聚类后的状态来了解这一点。在完美聚类状态下,中心点和类簇重叠。中心点实际上就是该类样本的质心。在聚类不准确的情况下,样本坐标的均值(即质心)和我们选择的中心点不会重合。因此,我们需要不断调整中心点的位置,使其逐渐靠近质心。
每次聚类后,我们计算各个类的质心,并将其作为下一次聚类的中心点,重复这一过程直到聚类收敛。
理解了Kmeans的原理后,我们可以用Python轻松实现它。我们可以使用sklearn库中的make_blobs函数生成聚类数据。接下来,我们开发基础方法,如计算向量间的欧氏距离,并随机选择K个簇中心。
我们先生成数据,然后随机选择三个簇中心,检查它们是否在样本范围内。随后,我们实现KMeans的核心逻辑,包括计算逻辑和迭代过程。
通过本文,我们介绍了Kmeans算法的原理和实现。尽管Kmeans算法简单,但在每次迭代时仍需对所有样本进行计算,初始中心点的随机选择可能导致需要更多迭代次数。对于Kmeans效率的提升方法,我们将在下周的机器学习专题中详细讨论。
Kmeans算法因其简单易懂且实现方便,经常出现在各大公司的招聘笔试题中。虽然算法本身简单,但我们仍需深入理解其原理,以便更好地应对各种应用场景。