如前所述,无监督学习帮助我们发现数据中固有的模式,无需依赖预先存在的标签。聚类是无监督学习中的一种基本方法,专门用于将相似数据点归集到一起。可以将其视为根据数据点本身的特征,自动将数据整理成不同的类别。聚类的主要目标是将数据集划分,使得同一组(或簇)内的点彼此之间比与其他组的点更相似。这在许多情况下很有用,例如:客户细分: 根据相似的购买行为或人口统计学信息对客户进行分组,以便进行精准营销。文档分析: 按主题对文章或文档进行分组。图像分割: 根据颜色或纹理对图像中的像素进行分组。异常检测: 识别不明显属于任何簇的点。数据概括: 理解数据集中主要的原型或概况。衡量相似度:聚类方法的依据我们如何判断两个数据点是否“相似”?这通常通过在特征空间中计算的距离或相似度量来量化。度量的选择非常重要,并且很大程度上取决于数据本身的特性。欧几里得距离数值数据最常用的度量是欧几里得距离。它表示特征空间中两点之间的直线距离。对于$n$维空间中的两点$p = (p_1, p_2, ..., p_n)$和$q = (q_1, q_2, ..., q_n)$,欧几里得距离计算如下:$$ d(p, q) = \sqrt{\sum_{i=1}^{n}(p_i - q_i)^2} $$此度量直观易懂,但对特征的尺度很敏感。如果某个特征的范围远大于其他特征(例如,薪水与工作年限相比),它可能会在距离计算中占据主导地位。因此,如第1章所述,在应用使用欧几里得距离的聚类算法之前,特征缩放(如标准化或归一化)通常是必要的预处理步骤。曼哈顿距离另一个常用度量是曼哈顿距离(或L1距离)。它通过对坐标的绝对差求和来衡量距离,类似于在城市网格中导航,只能沿着水平或垂直路径移动。$$ d(p, q) = \sum_{i=1}^{n}|p_i - q_i| $$曼哈顿距离与欧几里得距离相比,对异常值不太敏感,在某些高维情况或特征表示不同方向或数量时,可能更受青睐。其他度量尽管欧几里得距离和曼哈顿距离是数值数据的常用选择,但针对不同数据类型还存在其他度量:余弦相似度: 通常用于表示为向量的文本数据(如TF-IDF),衡量的是两个向量之间夹角的余弦值,而非它们的大小差异。它在高维数据中表现良好。汉明距离: 用于分类数据,计算对应符号不同的位置数量。选择合适的距离度量是聚类过程中的重要首步。聚类算法的主要方法聚类算法在定义簇和寻找簇的方式上有所不同。主要类别如下:基于质心的聚类: 这类算法通过一个中心向量或质心来表示簇。最著名的例子是K-Means。数据点被分配到其质心最近的簇(通常使用欧几里得距离)。算法通常迭代地更新质心位置和点分配,以最小化点到其分配质心的距离。基于密度的聚类: 这些方法将簇定义为数据点的密集区域,这些区域由较低点密度的区域分隔。DBSCAN是一个常用示例。这类算法可以发现任意形状的簇,并且能有效处理噪声(不属于任何密集区域的点)。它们通常不需要预先指定簇的数量,而是依赖于密度参数。层次聚类: 这类算法构建簇的层次结构。凝聚式(自底向上)方法从每个点作为一个簇开始,并迭代地合并最接近的簇对。分裂式(自顶向下)方法从所有点在一个簇中开始,并递归地将其分裂。结果通常可视化为称为树状图的树形图,它允许通过在某个级别切割树来选择簇的数量。下图显示了一个简单数据集,我们可能会凭视觉识别出潜在的群组,聚类算法旨在自动找出这些群组。{ "layout": { "title": { "text": "用于聚类的示例数据分布", "x": 0.5 }, "xaxis_title": "特征 1", "yaxis_title": "特征 2", "showlegend": false, "margin": { "l": 20, "r": 20, "t": 40, "b": 20 }, "width": 600, "height": 400, "template": "plotly_white" }, "data": [ { "x": [0.4967141530112327,-0.13826430117118106,0.6476885381006918,1.523029856408028,-0.2341533747233349,1.5792128155073914,0.7674347291489968,-0.4694743859396103,0.5425600434343351,-0.46341769191767374,0.24196227153555614,-1.9132802448048763,-1.7249178371096086,-0.562287534136596,-1.0128311247078662,0.31424733485538134,-0.9080240768934953,1.465648760861919,-0.22577630375666538,0.06752820497519641,-1.4247481960116965,-0.5443827248248843,0.11092258866995938,-1.150993535779378,-0.4370319537993011,-1.4123035175794964,1.1989178090857962,-0.18565869779566696,-1.1063352376133975,-0.008383850749608456,0.23009464889234344,-1.404897778971823,0.5868982959769657,-0.43189767239162735,0.8279746414541663,5.496714153011233,4.861735698828819,5.647688538100692,6.523029856408028,4.765846625276665,6.579212815507391,5.767434729148997,4.53052561406039,5.542560043434335,4.536582308082326,5.241962271535556,3.0867197551951237,3.2750821628903914,4.437712465863404,3.987168875292134,5.3142473348553815,4.091975923106505,6.465648760861919,4.774223696243334,5.067528204975196,3.5752518039883035,4.455617275175116,5.110922588669959,3.849006464220622,4.562968046200699,3.5876964824205037,6.198917809085797,4.814341302204333,3.8936647623866025,4.991616149250391,5.230094648892343,3.595102221028177,5.586898295976966,4.5681023276083725,5.827974641454166,0.4967141530112327,5.861735698828819,6.647688538100692,7.523029856408028,5.765846625276665,7.579212815507391,6.767434729148997,5.53052561406039,6.542560043434335,5.536582308082326,6.241962271535556,4.0867197551951237,4.2750821628903914,5.437712465863404,4.987168875292134,6.3142473348553815,5.091975923106505,7.465648760861919,5.774223696243334,6.067528204975196,4.5752518039883035,5.455617275175116,6.110922588669959,4.849006464220622,5.562968046200699,4.5876964824205037,7.198917809085797,5.814341302204333,4.8936647623866025,5.991616149250391], "y": [0.6157491948516547,0.3882923263743956,0.7835460018651221,0.2088767573774357,-1.2889401028589818,1.0447767780953394,-1.1037446318324634,0.1044885607931436,-0.41858381196440956,0.488200989210499,-0.3224172019066849,1.1274869258004256,0.3675515760280859,0.9015907444233863,0.5061394406186969,0.9008559071189616,-0.2518930515913928,-0.9875791687065583,1.5407788061962463,-0.1746002136110181,-0.053476795799800014,0.847309599833549,0.2637317678807452,0.3890499311481193,0.3921752501166669,-0.974694120809755,-0.7538405196548308,-1.167579604101369,0.5031871860990673,0.1077729697120851,0.04488490098891308,1.1913371901202466,1.0521829578087697,1.1713675530508767,1.54303957812199,5.615749194851654,5.388292326374395,5.783546001865122,5.208876757377436,3.711059897141018,6.044776778095339,-0.10374463183246343,5.104488560793144,4.581416188035591,5.488200989210499,4.677582798093315,6.127486925800426,5.367551576028086,5.901590744423387,5.506139440618697,5.900855907118962,4.748106948408607,4.012420831293442,6.540778806196246,4.825399786388982,4.9465232042001996,5.847309599833549,5.263731767880745,5.389049931148119,5.392175250116667,4.025305879190245,4.246159480345169,3.832420395898631,6.503187186099067,6.107772969712085], "mode": "markers", "marker": { "color": "#495057", "size": 7, "opacity": 0.8 }, "name": "数据点", "type": "scatter" } ] }示例:无标签的二维数据点,其中似乎存在明显的群组。聚类算法旨在正式识别这些群组。聚类面临的挑战聚类功能强大,但也伴随一些固有的挑战:确定簇的数量(K): 对于K-Means等算法,需要预先指定簇的数量($K$),但最优数量通常未知。像“肘部法则”或“轮廓分析”(我们稍后可能会提及)这样的方法可以帮助指导此选择,但这通常涉及一些领域知识或实验。对初始化和参数的敏感性: 某些算法(尤其是K-Means)可能会根据初始起始条件(例如,初始质心位置)产生不同的结果。基于密度的方法取决于定义“密度”的参数,这可能需要调整。处理高维数据: 随着特征数量的增加(高维度),距离度量可能变得意义不大(“维度灾难”)。点可能看起来等距,使得难以形成明显的簇。降维技术(如PCA,本章稍后讨论)在聚类之前可能有所帮助。结果评估: 由于无监督学习中没有真实标签,评估簇的“质量”是主观的,通常依赖于内部验证指标(衡量簇的凝聚度和分离度,如轮廓系数)或基于领域知识的解释。理解这些要点为有效应用特定聚类算法提供了依据。在接下来的章节中,我们将实现并学习两种广泛使用的算法:K-Means和DBSCAN。