解锁机器学习核心算法 | K-平均:揭开K-平均算法的神秘面纱

一、引言

机器学习算法种类繁多,它们各自有着独特的优势和应用场景。前面我们学习了线性回归算法、逻辑回归算法、决策树算法。而今天,我们要深入探讨的是其中一种经典且广泛应用的聚类算法 —— K - 平均算法(K-Means Algorithm) 。它在数据挖掘、图像处理、市场分析等众多领域都发挥着重要作用,能够帮助我们发现数据中的潜在模式和规律,为决策提供有力支持。

在这里插入图片描述

二、K - 平均算法基础

2.1 定义与概念

K - 平均算法,也被称为 K - 均值算法,是一种广泛应用的聚类算法 ,属于无监督学习的范畴。在无监督学习中,我们没有预先标记好的类别信息,而聚类的目的就是发现数据的内在结构和模式,将相似的数据点划分到同一个簇(cluster)中 。

K - 平均算法核心目标是将给定的数据集划分为 K 个互不重叠的簇,使得同一个簇内的数据点尽可能相似,而不同簇之间的数据点尽可能不同。这里的 “相似” 通常通过距离来衡量,比如欧氏距离、曼哈顿距离等 ,最常用的是欧氏距离。通过将数据点分配到距离最近的簇中心,来实现聚类的效果。

2.2 核心原理

  • 质心选择首先,需要确定要划分的簇的数量 K,这是 K - 平均算法的一个超参数,需要根据具体问题和数据特点进行设定。然后,随机从数据集中选择 K 个数据点作为初始质心(centroid),这些质心代表了每个簇的初始中心位置。

  • 样本分配对于数据集中的每一个样本点,计算它与 K 个质心的距离,通常使用欧氏距离公式 。将该样本点分配到距离最近的质心所对应的簇中。这样,所有样本点都被划分到了 K 个簇中的某一个。

  • 质心更新在完成所有样本点的分配后,重新计算每个簇的质心。新的质心是该簇中所有样本点的均值。例如,对于一个二维数据点的簇,新质心的横坐标是该簇中所有点横坐标的平均值,纵坐标是所有点纵坐标的平均值。通过更新质心,使得每个簇的中心位置更能代表该簇内的数据点。

  • 迭代优化重复样本分配和质心更新这两个步骤,直到质心不再发生变化(或变化非常小,小于预先设定的阈值),或者达到了预先设定的最大迭代次数。此时,算法收敛,认为聚类结果已经稳定,完成聚类过程。

2.3 数学原理

假设我们有一个包含 n 个样本的数据集 D = { x 1 , x 2 , ⋯   , x n } D=\{x_1,x_2,\cdots,x_n\} D={x1,x2,,xn},要将其划分为 K 个簇。用 C = { C 1 , C 2 , ⋯   , C k } C=\{C_1,C_2,\cdots,C_k\} C={C1,C2,,Ck} 表示划分后的簇集合,其中 C i C_i Ci 表示第 i 个簇, μ i \mu_i μi 表示第 i 个簇的质心。

K - 平均算法的目标是最小化每个样本点到其所属簇质心的距离平方和,即目标函数为:

J ( C , μ ) = ∑ i = 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 J(C,\mu)=\sum_{i = 1}^{K}\sum_{x\in C_i}||x-\mu_i||^2 J(C,μ)=i=1KxCi∣∣xμi2

其中, ∣ ∣ x − μ i ∣ ∣ 2 ||x-\mu_i||^2 ∣∣xμi2 表示样本点 x 到质心 μ i \mu_i μi 的欧氏距离的平方。

在算法的迭代过程中,通过不断更新质心和样本点的分配,来逐步优化目标函数,使其值不断减小,最终收敛到一个局部最优解(由于 K - 平均算法对初始质心敏感,不一定能收敛到全局最优解)。

具体来说,质心的更新公式为:

μ i = 1 ∣ C i ∣ ∑ x ∈ C i x \mu_i=\frac{1}{|C_i|}\sum_{x\in C_i}x μi=Ci1xCix

其中, ∣ C i ∣ |C_i| Ci 表示簇 C i C_i Ci 中的样本点数量。

通过不断重复样本分配(根据距离最近原则将样本点分配到簇中)和质心更新(根据簇内样本点计算新质心)这两个步骤,使得目标函数 J ( C , μ ) J(C,\mu) J(C,μ) 不断减小,直到满足收敛条件(质心不再变化或变化小于阈值,或者达到最大迭代次数)。

三、算法流程与步骤

3.1 初始化质心

初始化 K 个质心是 K - 平均算法的第一步,质心的选择对算法的收敛速度和最终聚类结果有着重要影响。常见的初始化方法有随机选择K-means++ 算法

  • 随机选择最简单的方式是从数据集中随机选取 K 个数据点作为初始质心。这种方法实现简单,计算开销小,在数据集较小且分布相对均匀时,有可能快速收敛到较好的聚类结果。但在复杂数据集上,随机选择的质心可能过于接近,导致聚类结果陷入局部最优。例如在一个包含多个明显分离簇的数据集上,若随机选择的质心都集中在一个小区域,那么聚类结果可能无法准确反映数据的真实结构。

  • K-means++ 算法该算法旨在选择距离较远的初始质心,以提高聚类效果和收敛速度。其步骤如下:

    • 1、随机选择一个数据点作为第一个质心。
    • 2、对于每个未被选择的数据点,计算它与已选择质心的最小距离,并将这个距离的平方作为该点被选为下一个质心的概率。
    • 3、根据计算出的概率,使用轮盘赌选择法或其他随机选择方法,选择下一个质心。
    • 4、重复步骤 2 和 3,直到选择出 K 个质心。

通过这种方式,K-means++ 算法能够使初始质心在数据空间中更均匀地分布,减少陷入局部最优的可能性。在图像分割任务中,使用 K-means++ 初始化质心可以更准确地将图像中的不同区域分割出来,相比随机初始化,聚类结果更加稳定和准确。

3.2 样本分配

在完成质心初始化后,接下来要将数据集中的每个样本分配到距离它最近的质心所在的簇中。这一步骤的关键是计算样本与质心之间的距离,最常用的距离度量是欧氏距离。对于两个 n n n 维向量 x = ( x 1 , x 2 , ⋯   , x n ) x=(x_1,x_2,\cdots,x_n) x=(x1,x2,,xn) y = ( y 1 , y 2 , ⋯   , y n ) y=(y_1,y_2,\cdots,y_n) y=(y1,y2,,yn),它们之间的欧氏距离计算公式为

d ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d(x,y)=\sqrt{\sum_{i = 1}^{n}(x_i - y_i)^2} d(x,y)=i=1n(xiyi)2

以一个二维数据集为例,假设有样本点 P ( 2 , 3 ) P(2,3) P(2,3) 和质心 C 1 ( 1 , 1 ) C_1(1,1) C1(1,1) C 2 ( 4 , 5 ) C_2(4,5) C2(4,5),则 P P P C 1 C_1 C1 的欧氏距离为:

d ( P , C 1 ) = ( 2 − 1 ) 2 + ( 3 − 1 ) 2 = 1 + 4 = 5 d(P,C_1)=\sqrt{(2 - 1)^2+(3 - 1)^2}=\sqrt{1 + 4}=\sqrt{5} d(P,C1)=(21)2+(31)2 =1+4 =5

P P P C 2 C_2 C2 的欧氏距离为:

d ( P , C 2 ) = ( 2 − 4 ) 2 + ( 3 − 5 ) 2 = 4 + 4 = 2 2 d(P,C_2)=\sqrt{(2 - 4)^2+(3 - 5)^2}=\sqrt{4 + 4}=2\sqrt{2} d(P,C2)=(24)2+(35)2 =4+4 =22

由于 5 < 2 2 \sqrt{5}<2\sqrt{2} 5 <22 ,所以样本点 P P P 被分配到质心 C 1 C_1 C1 所在的簇中。通过对数据集中的每一个样本点执行这样的距离计算和分配操作,完成一次样本分配过程,使得每个样本都归属于一个特定的簇。

3.3 质心更新

在完成所有样本的分配后,需要重新计算每个簇的质心。新质心的计算方法是将簇内所有样本点的对应维度的均值作为新质心在该维度的值。例如,对于一个包含 m 个样本点的簇 C C C,每个样本点是一个 n 维向量,设样本点为 x j = ( x 1 j , x 2 j , ⋯   , x n j ) x^j=(x_1^j,x_2^j,\cdots,x_n^j) xj=(x1j,x2j,,xnj) ,其中 j = 1 , 2 , ⋯   , m j = 1,2,\cdots,m j=1,2,,m ,则该簇的新质心 μ \mu μ 的计算公式为:

μ i = 1 m ∑ j = 1 m x i j \mu_i=\frac{1}{m}\sum_{j = 1}^{m}x_i^j μi=m1j=1mxij

其中, i = 1 , 2 , ⋯   , n i = 1,2,\cdots,n i=1,2,,n,表示质心的第 i 个维度的值。

假设一个簇中有三个样本点 A ( 1 , 2 ) A(1,2) A(1,2) B ( 3 , 4 ) B(3,4) B(3,4) C ( 5 , 6 ) C(5,6) C(5,6),则新质心的横坐标为:

μ 1 = 1 + 3 + 5 3 = 3 \mu_1=\frac{1 + 3 + 5}{3}=3 μ1=31+3+5=3

纵坐标为:

μ 2 = 2 + 4 + 6 3 = 4 \mu_2=\frac{2 + 4 + 6}{3}=4 μ2=32+4+6=4

所以新质心为 ( 3 , 4 ) (3,4) (3,4)。通过更新质心,使得每个簇的中心位置更能代表该簇内样本点的分布情况,为下一轮的样本分配提供更准确的参考。

3.4 迭代收敛

完成质心更新后,算法进入下一轮迭代,再次进行样本分配和质心更新的步骤。这个迭代过程不断重复,直到满足一定的收敛条件。常见的收敛条件有两种:

  • 质心不再变化当两次迭代之间,所有质心的位置变化都非常小(小于预先设定的一个极小阈值)时,认为算法已经收敛,聚类结果稳定。例如,设定阈值为 1 0 − 6 10^{-6} 106,如果某次迭代后,所有质心在各个维度上的变化量都小于 1 0 − 6 10^{-6} 106,则算法停止迭代。

  • 达到预设迭代次数预先设定一个最大迭代次数,如 100 次。无论质心是否还在变化,只要达到了这个最大迭代次数,算法就停止迭代。这种方式可以防止算法在某些情况下陷入无限循环,确保算法在有限的时间内结束。

在实际应用中,根据具体情况选择合适的收敛条件。如果对聚类结果的精度要求较高,且数据量不是特别大,可以优先考虑质心不再变化的条件;如果希望算法在一定时间内结束,并且对结果精度要求不是极高,可以采用达到预设迭代次数的条件。通过不断迭代优化,K - 平均算法最终能够将数据集划分成 K 个相对稳定的簇,完成聚类任务。

四、K - 平均算法的优缺点

4.1 优点

  • 简单高效 K - 平均算法的原理和步骤都相对简单,易于理解和实现。它的计算过程主要涉及距离计算和均值计算,不需要复杂的数学推导和模型训练,在处理大规模数据集时,能够快速地完成聚类任务,具有较高的计算效率。在电商领域,对海量的用户购买行为数据进行聚类分析,K - 平均算法可以在较短时间内完成聚类,帮助商家发现不同类型的用户群体,为精准营销提供依据。

  • 计算复杂度低K - 平均算法的时间复杂度主要取决于样本数量 n、簇的数量 K 和迭代次数 I,通常为 O (nKI)。在实际应用中,K 和 I 通常是相对较小的常数,因此算法的时间复杂度接近线性,能够在合理的时间内处理大规模数据。对于具有数百万条记录的客户交易数据集,K - 平均算法可以在可接受的时间内完成聚类分析,为企业的市场决策提供支持。

  • 可扩展性好K - 平均算法可以很容易地扩展到高维数据空间,对数据的维度没有严格限制。在图像识别领域,图像数据通常具有很高的维度(如 RGB 图像每个像素点有三个维度),K - 平均算法可以有效地对图像数据进行聚类,实现图像分割、图像压缩等任务。

  • 对球形簇数据效果好当数据集中的簇大致呈球形分布,且簇内数据点分布较为均匀时,K - 平均算法能够很好地识别出这些簇,聚类效果较为理想。在地理信息系统中,对城市中不同区域的人口分布进行聚类分析,如果不同区域的人口分布呈现出相对集中的球形特征,K - 平均算法可以准确地将这些区域划分成不同的簇,帮助城市规划者了解人口分布情况。

4.2 缺点

  • 需要预先指定 K 值在使用 K - 平均算法之前,必须事先确定要划分的簇的数量 K。然而,在实际应用中,很难预先知道数据的真实簇数。如果 K 值选择不当,可能会导致聚类结果不理想。选择的 K 值过小,会使得多个不同的簇被合并成一个簇,丢失数据的内在结构信息;选择的 K 值过大,会将一个簇划分成多个小簇,产生过度聚类的问题。在对新闻文章进行聚类时,如果 K 值设置不合理,可能会将不同主题的文章错误地聚在一起,或者将同一主题的文章分散到多个簇中,无法准确地提取文章的主题信息。

  • 对初始质心敏感由于初始质心是随机选择的,不同的初始质心可能会导致不同的聚类结果。如果初始质心选择不当,算法可能会收敛到局部最优解,而不是全局最优解。在一个包含多个明显分离簇的数据集上,如果初始质心都集中在一个小区域,那么聚类结果可能无法准确反映数据的真实结构,导致聚类效果不佳。为了克服这个问题,通常需要多次运行算法,选择不同的初始质心,然后根据某种评估指标(如轮廓系数、Calinski-Harabasz 指数等)选择最优的聚类结果。

  • 对非球形簇和异常值敏感K - 平均算法假设簇是球形的,且簇内数据点分布均匀。对于非球形的簇结构,K - 平均算法的聚类效果可能较差,无法准确地划分数据。当数据集中存在异常值时,这些异常值会对质心的计算产生较大影响,导致质心偏移,从而影响聚类结果的准确性。在一个包含离群点的客户收入数据集中,离群点(如高收入的企业家)可能会使某个簇的质心明显偏离正常客户的收入水平,导致该簇的聚类结果不能代表大多数客户的特征。

五、案例实战

5.1 准备数据集

为了更直观地理解 K - 平均算法的应用,我们以经典的 Iris 数据集为例。Iris 数据集是一个多类分类的基准数据集,包含 150 个样本,分为 3 个类别,分别对应鸢尾花的三个品种:Setosa、Versicolor 和 Virginica。每个样本具有 4 个特征维度:花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width),所有测量值均以厘米为单位。

在 Python 中,我们可以使用 Scikit-learn 库轻松加载 Iris 数据集,代码如下:

from sklearn.datasets import load_iris

# 加载Iris数据集

iris = load_iris()

data = iris.data

加载数据集后,通常需要对数据进行预处理。这一步骤旨在确保数据的质量和一致性,以提高算法的性能和准确性。常见的预处理操作包括处理缺失值、去除异常值和数据标准化。在 Iris 数据集中,不存在缺失值,异常值也较少,因此我们重点进行数据标准化处理,使每个特征具有相同的尺度,避免因特征尺度差异较大而影响算法效果。

使用 Scikit-learn 库中的StandardScaler进行数据标准化,代码如下:

from sklearn.preprocessing import StandardScaler

# 数据标准化

scaler = StandardScaler()

data_scaled = scaler.fit_transform(data)

经过标准化处理后,数据集中每个特征的均值变为 0,标准差变为 1,这样可以使 K - 平均算法更加稳定和准确。

5.2 算法实现

接下来,我们使用 Python 和 Scikit-learn 库实现 K - 平均算法。具体步骤包括模型初始化、训练和预测。

首先,初始化 K - 平均模型,设置簇的数量 K。在 Iris 数据集中,我们知道真实的类别数为 3,因此设置 n_clusters = 3。同时,为了使结果具有可重复性,设置 random_state 参数。代码如下:

from sklearn.cluster import KMeans

# 初始化K-平均模型,设置簇的数量为3

kmeans = KMeans(n_clusters=3, random_state=42)

然后,使用预处理后的数据对模型进行训练

# 训练模型

kmeans.fit(data_scaled)

训练完成后,模型会根据数据的特征和分布,将数据点划分到不同的簇中。我们可以使用训练好的模型对数据进行预测,得到每个数据点所属的簇标签:

# 预测每个数据点所属的簇

labels = kmeans.predict(data_scaled)

通过以上步骤,我们完成了 K - 平均算法的实现,得到了每个样本点所属的簇标签。这些标签将用于后续的结果分析和评估。

5.3 结果分析

完成 K - 平均算法的训练和预测后,我们需要对聚类结果进行分析。首先,查看每个簇的样本数量和质心位置。通过kmeans.labels_可以获取每个样本点所属的簇标签,通过kmeans.cluster_centers_可以获取每个簇的质心。代码如下:

import numpy as np

# 查看每个簇的样本数量

cluster_sizes = np.unique(labels, return_counts=True)[1]

print("每个簇的样本数量:", cluster_sizes)

# 查看每个簇的质心

cluster_centers = kmeans.cluster_centers_

print("每个簇的质心:\n", cluster_centers)

上述代码中,np.unique(labels, return_counts=True)用于统计每个簇标签的数量,从而得到每个簇的样本数量。kmeans.cluster_centers_直接返回每个簇的质心,这些质心是在聚类过程中通过不断迭代计算得到的,代表了每个簇的中心位置。
在这里插入图片描述
为了更直观地展示聚类效果,我们可以使用可视化工具,如 MatplotlibSeaborn。由于 Iris 数据集是四维数据,为了在二维平面上展示,我们可以选择其中两个特征进行可视化。这里我们选择花萼长度和花瓣长度两个特征:

import matplotlib.pyplot as plt

# 选择花萼长度和花瓣长度两个特征

x = data[:, 0]

y = data[:, 2]

# 绘制散点图,不同颜色表示不同的簇

plt.scatter(x, y, c=labels, cmap='viridis')

# 绘制簇的质心

plt.scatter(cluster_centers[:, 0], cluster_centers[:, 2], marker='x', c='red', s=200)

plt.xlabel('花萼长度')

plt.ylabel('花瓣长度')

plt.title('K-平均算法聚类结果')

plt.show()

在上述代码中,plt.scatter(x, y, c=labels, cmap='viridis') 根据样本点所属的簇标签,使用不同颜色绘制散点图,展示不同簇的数据分布情况。plt.scatter(cluster_centers[:, 0], cluster_centers[:, 2], marker='x', c='red', s=200)绘制每个簇的质心,以红色的 “x” 标记,便于观察簇的中心位置。通过可视化结果,可以直观地看到 K - 平均算法将数据点划分成了三个簇,并且不同簇之间的数据点具有一定的区分度。最终结果如下图所示:
在这里插入图片描述

5.4 评估指标

为了评估 K - 平均算法的聚类效果,我们引入一些常用的评估指标,如 SSE(Sum of Squared Errors,误差平方和)和轮廓系数(Silhouette Coefficient)。

SSE 是一种常用的评估聚类效果的指标,它衡量了每个样本点到其所属簇质心的距离平方和。SSE 值越小,说明簇内的数据点越紧密,聚类效果越好。在 Scikit-learn 中,可以通过kmeans.inertia_获取 SSE 值:

# 计算SSE

sse = kmeans.inertia_

print("SSE:", sse)

通过上述代码我们最终得到的SSE为:

SSE: 191.02473685317972

轮廓系数结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。其取值范围为 [-1, 1],系数越接近 1,表示聚类效果越好;越接近 - 1,表示样本可能被误分;越接近 0,表示样本处于两个簇的边界上。在 Scikit-learn 中,可以使用metrics.silhouette_score计算轮廓系数:

from sklearn import metrics

# 计算轮廓系数

silhouette_score = metrics.silhouette_score(data_scaled, labels)

print("轮廓系数:", silhouette_score)

通过上述代码我们最终得到的轮廓系数为:

轮廓系数: 0.4798814508199817

通过分析这些评估指标,可以更客观地了解 K - 平均算法在当前数据集上的聚类效果。如果 SSE 值较大,说明簇内的数据点不够紧密,可能需要调整簇的数量 K 或优化算法;如果轮廓系数较低,说明聚类效果不理想,可能存在样本误分或簇划分不合理的情况,需要进一步分析和改进。

六、优化与改进

6.1 初始质心选择策略

K - 平均算法对初始质心的选择非常敏感,不同的初始质心可能导致不同的聚类结果,甚至可能使算法收敛到局部最优解。为了改善这一问题,人们提出了多种优化初始质心选择的方法,其中 K-means++ 算法(具体算法见3.1:初始化质心)是一种广泛应用且效果显著的方法。

以一个包含多个明显分离簇的数据集为例,假设使用随机初始化质心的 K - 平均算法,可能会因为初始质心都集中在一个簇中,导致其他簇无法被正确识别,聚类结果陷入局部最优。而使用 K-means++ 算法初始化质心时,由于其选择质心的策略能够使质心在数据空间中更均匀地分布,更有可能将质心分别放置在不同的簇中,从而准确地识别出各个簇,得到更优的聚类结果。在实际应用中,K-means++ 算法在处理大规模数据集和复杂数据分布时,能够显著提高算法的收敛速度和聚类质量,减少算法对初始条件的依赖,使聚类结果更加可靠。

6.2 确定 K 值的方法

在使用 K - 平均算法时,预先指定 K 值是一个关键问题,因为不合适的 K 值可能导致聚类结果不理想。以下介绍两种常用的确定最优 K 值的方法:肘部法轮廓系数法

  • 肘部法(Elbow Method)

肘部法的核心指标是 SSE(Sum of Squared Errors,误差平方和),它表示每个样本点到其所属簇质心的距离平方和。公式为:

S S E = ∑ i = 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 SSE=\sum_{i = 1}^{K}\sum_{x\in C_i}||x-\mu_i||^2 SSE=i=1KxCi∣∣xμi2

其中, C i C_i Ci 是第 i 个簇, x x x C i C_i Ci 中的样本点, μ i \mu_i μi C i C_i Ci 的质心。

肘部法的核心思想是随着聚类数 K 的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和 SSE 自然会逐渐变小。并且,当 K 小于真实聚类数时,由于 K 的增大会大幅增加每个簇的聚合程度,故 SSE 的下降幅度会很大;而当 K 到达真实聚类数时,再增加 K 所得到的聚合程度回报会迅速变小,所以 SSE 的下降幅度会骤减,然后随着 K 值的继续增大而趋于平缓。也就是说 SSE 和 K 的关系图是一个手肘的形状,而这个肘部对应的 K 值就是数据的真实聚类数。

具体操作步骤如下:

  1. 选择一个合理的 K 值范围,例如从 1 到 10。
  2. 对于范围内的每个 K 值,运行 K - 平均算法,并计算相应的 SSE 值。
  3. 绘制 K 值与 SSE 值的关系曲线,即肘部图。在图中,横轴表示 K 值,纵轴表示 SSE 值。
  4. 观察曲线,找到 SSE 下降速度显著减缓的点,即曲线出现 “肘部” 的位置,该位置对应的 K 值即为最佳聚类数。

轮廓系数法(Silhouette Coefficient)

轮廓系数结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。对于数据集中的每个样本点 x i x_i xi,其轮廓系数 s i s_i si 的计算如下:

  1. 计算 x i x_i xi 与同一簇中所有其他样本的平均距离,记为 a i a_i ai a i a_i ai 越小,表示样本点在簇内的凝聚度越高。
  2. 计算 x i x_i xi 与最近簇中所有样本的平均距离,记为 b i b_i bi b i b_i bi 越大,表示样本点与其他簇的分离度越高。
  3. 计算样本点 x i x_i xi 的轮廓系数:

s i = b i − a i max ⁡ ( a i , b i ) s_i=\frac{b_i - a_i}{\max(a_i,b_i)} si=max(ai,bi)biai

整个数据集的轮廓系数是所有样本点轮廓系数的平均值,其取值范围为 [-1, 1]。轮廓系数越接近 1,表示聚类效果越好;越接近 - 1,表示样本可能被误分;越接近 0,表示样本处于两个簇的边界上。

确定 K 值的步骤如下:

  1. 选择一个 K 值范围,如从 2 到 10。
  2. 对于每个 K 值,运行 K - 平均算法并计算轮廓系数。
  3. 选择轮廓系数最大时对应的 K 值作为最优的聚类数。

6.3 应对非球形簇和异常值

K - 平均算法假设簇是球形的,且对异常值较为敏感,这在实际应用中可能导致聚类效果不佳。为了解决这些问题,可以采用以下方法:

  • 使用 DBSCAN 算法处理非球形簇
    DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它不需要事先指定簇的数量,并且能够处理非球形簇数据

    • 核心概念包括:

      • 核心点如果一个点的 ϵ \epsilon ϵ邻域内至少包含 MinPts 个点,则该点被定义为核心点。这里的 ϵ \epsilon ϵ是邻域半径,MinPts 是最小点数,这两个参数需要根据数据特点进行设置。

      • 边界点一个点如果不在任何核心点的 ϵ \epsilon ϵ邻域内,但属于某个核心点的 ϵ \epsilon ϵ邻域,则被定义为边界点。

      • 噪声点不属于任何核心点或边界点的点被称为噪声点。

    • DBSCAN 算法的主要步骤如下:

    1. 选择合适的参数 ϵ \epsilon ϵ和 MinPts。这是 DBSCAN 算法的关键步骤,参数的选择会直接影响聚类结果。通常可以通过多次试验或根据数据的先验知识来确定合适的参数值。
    2. 对于数据集中的每个点,定义其 ϵ \epsilon ϵ邻域(即距离不超过 ϵ \epsilon ϵ的所有点)。
    3. 检查每个点的邻域是否包含至少 MinPts 个点,确定核心点。
    4. 从每个核心点开始,递归地将邻近的核心点添加到同一簇中,形成簇。
    5. 标记未被分配到任何簇中的点为噪声点。


    在一个包含环形分布数据点的数据集上,K - 平均算法由于假设簇是球形的,可能无法正确识别环形簇,而 DBSCAN 算法能够根据数据点的密度分布,准确地将环形区域划分为一个簇,并将噪声点识别出来,从而得到更符合数据实际分布的聚类结果。

    • 处理异常值的方法

      • 删除含有异常值的记录如果异常值是由于错误或噪声(如设备故障、手动输入错误等)导致的,那么最简单的处理方法就是删除这些异常值。但这种方法需要谨慎使用,因为如果删除的数据量过大,可能会导致信息丢失。在一个客户收入数据集中,如果某个收入值明显偏离正常范围,且经过核实是由于录入错误导致的,那么可以考虑删除该记录。但如果数据集中存在较多这样的异常值,删除它们可能会影响对整体客户收入分布的分析。

      • 将异常值视为缺失值,交给缺失值处理方法来处理常见的缺失值处理方法有均值填充、中位数填充、众数填充等。可以根据数据的特点选择合适的填充方法。对于一个数值型数据集,如果某个特征存在异常值,可以将其视为缺失值,然后用该特征的均值或中位数进行填充。但这种方法可能会掩盖异常值所包含的信息,在某些情况下可能会影响分析结果的准确性。

      • 使用鲁棒的统计方法某些统计方法对异常值有很好的鲁棒性,即使存在异常值,也能得到准确的结果。在计算数据的中心趋势时,可以使用中位数代替均值,因为中位数受异常值的影响较小。在聚类算法中,也有一些鲁棒的聚类方法,如基于密度的聚类算法(如 DBSCAN),它们能够自动识别并排除噪声点(异常值),从而得到更稳定的聚类结果。

七、应用领域

K - 平均算法作为一种经典的聚类算法,凭借其简单高效的特点,在众多领域都有着广泛的应用,为解决实际问题提供了有效的手段。以下是 K - 平均算法在一些主要领域的应用介绍。

7.1 图像分割

在图像处理领域,图像分割是一项关键任务,其目的是将图像中的不同区域分离出来,以便进行后续的分析和处理,如目标识别、图像压缩等。K - 平均算法图像分割中发挥着重要作用,它可以根据图像中像素的颜色、亮度等特征将像素点聚类成不同的组,每个组对应图像中的一个区域。

以彩色图像分割为例,我们可以将每个像素的 RGB 值作为一个三维向量,将图像中的所有像素点看作一个数据集。通过 K - 平均算法,将这些像素点划分成 K 个簇,每个簇代表图像中的一个特定区域,如天空、地面、建筑物等。在这个过程中,K 值的选择决定了分割的精细程度,K 值越大,分割出的区域越细致,但计算复杂度也会相应增加。

7.2 市场细分

在市场营销领域,了解消费者的需求和行为模式是制定有效营销策略的关键。K - 平均算法可以帮助企业根据消费者的各种属性,如年龄、收入、消费习惯、购买频率等,将消费者细分为不同的群体,每个群体具有相似的消费特征和需求。

假设我们有一个包含大量消费者信息的数据集,通过 K - 平均算法对这些数据进行聚类分析,我们可能会发现一些有趣的消费者群体,如高收入且高消费的群体、年轻且注重时尚的群体、价格敏感型的群体等。企业可以针对不同的群体制定个性化的营销策略,推出符合他们需求的产品和服务,提高市场竞争力。

7.3 生物信息学

在生物信息学领域,随着高通量技术的发展,产生了大量的生物数据,如基因表达数据、蛋白质序列数据等。如何从这些海量的数据中挖掘出有价值的信息,成为了生物信息学研究的重要课题。K - 平均算法在生物信息学中有着广泛的应用,特别是在基因表达数据分析方面

研究人员可以通过 K - 平均算法将具有相似表达模式的基因聚类到一起,从而发现基因之间的潜在关系和功能模块。这有助于深入了解生物过程的分子机制,为疾病的诊断、治疗和药物研发提供重要的线索。在研究癌症相关基因时,通过对大量癌症患者和正常样本的基因表达数据进行 K - 平均聚类分析,可能会发现一些与癌症发生发展密切相关的基因簇,为癌症的早期诊断和治疗提供新的靶点。

7.4 文本挖掘

在信息爆炸的时代,文本数据的数量呈指数级增长,如何对这些文本数据进行有效的组织和管理,成为了一个重要的问题。K - 平均算法在文本挖掘领域有着重要的应用,它可以用于文档聚类、主题提取等任务。

对于大量的新闻文章,我们可以使用 K - 平均算法将它们按照主题进行聚类,每个簇代表一个特定的主题,如政治、经济、体育、娱乐等。这样可以帮助用户快速找到自己感兴趣的文章,提高信息检索的效率。在主题提取方面,K - 平均算法可以将文本中的关键词聚类,从而提取出文本的主要主题,为文本的分类和标注提供依据。

八、总结与展望

简单总结一下,我们这篇文章主要学习了如下内容:K - 平均算法是经典聚类算法,简单高效,应用广泛。它通过迭代将数据集划分为 K 个簇,使簇内相似性高、簇间低。该算法有核心概念、数学原理及特定流程,如初始化质心、样本分配等。

其优点是简单高效、复杂度低、扩展性好,尤其适用于球形簇数据,但存在需预指定 K 值、对初始质心及非球形簇和异常值敏感等缺点。为克服不足,可采用 K - means++ 选初始质心,用肘部法等确定 K 值,借助 DBSCAN 处理非球形簇及应对异常值。

通过 Iris 数据集实战,体验其实现过程。在图像分割等多领域,K - 平均算法发挥重要作用。未来,随着数据变化,它有望与新兴技术结合,研究人员也将持续优化,以适应复杂场景,在数据挖掘等领域贡献更大力量。


K-Means 项目代码地址:【传送门】


延伸阅读

  • 机器学习核心算法系列文章
    解锁机器学习核心算法 | 决策树:机器学习中高效分类的利器
    解锁机器学习核心算法 | 逻辑回归:不是回归的“回归”
    解锁机器学习核心算法 | 线性回归:机器学习的基石

  • 深度学习框架探系列文章
    深度学习框架探秘|TensorFlow:AI 世界的万能钥匙
    深度学习框架探秘|PyTorch:AI 开发的灵动画笔
    深度学习框架探秘|TensorFlow vs PyTorch:AI 框架的巅峰对决
    深度学习框架探秘|Keras:深度学习的魔法钥匙

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/972439.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Bigemap Pro如何设置经纬网出图网格设置

第一步&#xff1a;打开bigemap pro软件&#xff0c;单击顶部网格选项第二栏&#xff0c;弹出经纬网设置对话框&#xff0c;如下图&#xff1a; 按作图需求自定义设置后&#xff0c;点击应用如下图&#xff1a; 第二步&#xff1a;设置好经纬网之后&#xff0c;进行作图&#x…

K8s 之端口暴露(The Port of K8s is Exposed)

K8s 之端口暴露 Kubernetes 是一个用于管理容器化应用程序的流行工具。然而&#xff0c;关于它的工作原理存在一些误解。最常见的误解之一是关于 Kubernetes Pod 中的端口暴露。本文将解释 Kubernetes 中端口暴露的真相。 1 误解 像许多 Kubernetes 新手一样&#xff0c;我最…

操作系统2.4

一、死锁&#xff0c;饥饿&#xff0c;死循环 死锁&#xff1a;各进程互相等待对方手里的资源&#xff0c;导致各进程都阻塞&#xff0c;无法向前推进的现象 饥饿&#xff1a;由于长期得不到想要的资源&#xff0c;某进程无法向前推进的现象&#xff0c;例如&#xff1a;短进…

解决DeepSeek服务器繁忙问题的实用指南

目录 简述 1. 关于服务器繁忙 1.1 服务器负载与资源限制 1.2 会话管理与连接机制 1.3 客户端配置与网络问题 2. 关于DeepSeek服务的备用选项 2.1 纳米AI搜索 2.2 硅基流动 2.3 秘塔AI搜索 2.4 字节跳动火山引擎 2.5 百度云千帆 2.6 英伟达NIM 2.7 Groq 2.8 Firew…

c++进阶———继承

1.引言 在一些大的项目中&#xff0c;我们可能要重复定义一些类&#xff0c;但是很麻烦&#xff0c;应该怎么办呢&#xff1f;举个简单的例子&#xff0c;我要做一个全校师生统计表&#xff0c;统计学号&#xff0c;教师编号&#xff0c;姓名&#xff0c;年龄&#xff0c;电话…

Android 平台GB28181设备接入实战指南

一、引言 随着视频监控技术的不断发展&#xff0c;国标 GB28181 协议在安防监控领域得到了广泛应用。该协议为不同厂家的视频监控设备之间的互联互通提供了统一的规范&#xff0c;使得设备的接入与管理变得更加简单和高效。在 Android 平台上实现 GB28181 设备接入&#xff0c…

细说Java 引用(强、软、弱、虚)和 GC 流程(一)

一、引用概览 1.1 引用简介 JDK1.2中引入了 Reference 抽象类及其子类&#xff0c;来满足不同场景的 JVM 垃圾回收工作&#xff1a; SoftReference 内存不足&#xff0c;GC发生时&#xff0c;引用的对象&#xff08;没有强引用时&#xff09;会被清理&#xff1b;高速缓存使用…

基于图像处理的裂缝检测与特征提取

一、引言 裂缝检测是基础设施监测中至关重要的一项任务,尤其是在土木工程和建筑工程领域。随着自动化技术的发展,传统的人工巡检方法逐渐被基于图像分析的自动化检测系统所取代。通过计算机视觉和图像处理技术,能够高效、精确地提取裂缝的几何特征,如长度、宽度、方向、面…

android ViewPager 管理 Fragment的预加载onCreate

一、前言 当ViewPager 加载多个 Fragment时候&#xff0c;怎么管理Fragment预加载。因为有些数据需要提前加载&#xff0c;第一个方便后面数据使用&#xff0c;提前初始化。或者预加载网络数据等。 二、实现示例 在onCreate方法进行数据预加载。如果在onCreateView函数里面&…

云计算架构学习之Ansible-playbook实战、Ansible-流程控制、Ansible-字典循环-roles角色

一、Ansible-playbook实战 1.Ansible-playbook安装软件 bash #编写yml [rootansible ansible]# cat wget.yml - hosts: backup tasks: - name: Install wget yum: name: wget state: present #检查playbook的语法 [rootansible ansible]…

Redis常用命令合集【二】

在合集【一】中已经介绍了redis中String类型和Hash类型&#xff0c;接下来就继续介绍剩下的List、Set、SortedSet类型。 1.List类型 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与…

挑战用Cursor实现“Cursor“的第二天

挑战用Cursor实现"Cursor"的第二天 项目地址 &#xff1a;https://github.com/Ez4Sterben/Ez4Code/tree/master 省流&#xff08;困了想睡觉了&#xff0c;就不多描述了&#xff09;&#xff1a; 干了1小时&#xff0c;文件树没问题了&#xff0c;代码能编辑了&…

已解决IDEA无法输入中文问题(亲测有效)

前言 在使用IDEA的时候&#xff0c;比如我们想写个注释&#xff0c;可能不经意间&#xff0c;输入法就无法输入中文了&#xff0c;但是在其他地方打字&#xff0c;输入法仍然能够正常工作。这是什么原因呢&#xff0c;这篇文章带你解决这个问题&#xff01; 快捷键 如果你的I…

阿里云上的网站配置HTTPS

1. 获取SSL证书 创建证书 下载证书 下载 上传 .key .pem 文件 到 阿里云服务器 /etc/nginx/ssl nginx.conf 配置 server { listen 443 ssl; server_name yuming; ssl_certificate /etc/nginx/ssl/*.pem; ssl_certificate_key /etc/nginx/ssl/*.key;

在Unity中用简单工厂模式模拟原神中的元素反应

1. 第一步创建3个脚本Factory&#xff08;反应工厂&#xff09;&#xff0c;Reactions&#xff08;具体反应&#xff09;&#xff0c;FactoryText&#xff08;测试反应的脚本&#xff09; 2.编写工厂脚本 using UnityEngine;// 定义一个元素反应的接口&#xff0c;所有具体的元…

数组和指针常见笔试题(深度剖析)

下边我来讲一下常见的面试题&#xff0c;过程很详细放心观看 #include<stdio.h>#include <string.h>int main() {char arr[] { a,b,c,d,e,f };printf("%d\n", strlen(arr));//随机值&#xff0c;因为strlen是遇到斜杠\0结束&#xff0c;统计\0之前的字符…

懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)

1.合集懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)&#xff1a;https://www.bilibili.com/video/BV1M6rdYEEog/ 备注&#xff1a; 1.本地离线卡密采用最安全的非对称加解密技术&#xff0c;设备id采用最安全多重混合加密不可逆技术生成&…

实战开发coze应用-姓氏头像生成器(上)

​欢迎关注【AI技术开发者】 上次&#xff0c;我们开发了一个对话形式的头像生成器智能体&#xff08;Agents&#xff09;&#xff0c;广受大家欢迎。 同时也接收到一些用户的反馈&#xff0c;生成前无法看到头像样式、初次使用不会用等等。 对此&#xff0c;我准备使用Coze开…

达梦:用户和模式

目录标题 数据库管理系统与用户权限管理**四权分立****用户管理与权限划分****用户管理界面与权限控制****用户创建与管理****实操**1. **默认创建用户与模式**&#xff1a;2. **用户权限和角色分配**&#xff1a;3. **命令行管理用户与角色**&#xff1a;4. 模式也可以创建 **…

【C++】类与对象全面剖析(尾卷)(构造深化、类型转换、static成员特性及内部类与匿名对象)

文章目录 一、再探构造函数二、隐式类型转换三、类中的静态成员1.静态成员变量2.静态成员函数 四、友元函数与友元类五、内部类六、匿名对象 一、再探构造函数 在之前的文章中我们大致将构造函数讲完了&#xff0c;但是还有一个比较重要的知识点当时没有讲到&#xff0c;因为如…