ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MATLAB聚类算法实战:K-Means、层次聚类与DBSCAN原理与应用

MATLAB聚类算法实战:K-Means、层次聚类与DBSCAN原理与应用 1. 从“物以类聚”到数据洞察聚类算法的核心价值在数据科学和数学建模的实战中我们常常面对一堆没有标签、结构未知的数据。比如市场部门拿到了一份包含成千上万用户消费行为、浏览记录的数据集他们想知道这些用户天然地可以分成几类以便进行精准营销。又比如生物学家手上有大量基因表达数据希望发现其中隐藏的、具有相似表达模式的基因簇从而推断其功能。这时候给数据“贴标签”的分类算法就派不上用场了因为我们根本不知道有哪些类别。我们需要的是另一种思路让数据自己“说话”根据它们内在的相似性自动聚集成群。这就是聚类算法要解决的核心问题。简单来说聚类就是一种无监督学习方法。它的目标是将数据集中的样本划分成若干个互不相交的子集每个子集称为一个“簇”。理想情况下同一个簇内的样本彼此之间非常相似而不同簇的样本则差异明显。这个“相似”的定义通常由我们选择的距离度量如欧氏距离、余弦相似度来决定。聚类的结果为我们提供了一种数据压缩和理解的视角是从混乱中寻找秩序的第一步也是后续深入分析如模式发现、异常检测、数据降维可视化的重要基础。在MATLAB这个强大的科学计算与算法原型平台上实现和应用各类聚类算法变得异常高效。MATLAB不仅提供了直观的绘图工具让我们能“看见”聚类效果其优化的数值计算库和丰富的统计与机器学习工具箱更让我们能够轻松处理从原理验证到大规模数据实战的全流程。接下来我将结合几个典型的应用场景深入剖析几种核心聚类算法的原理、在MATLAB中的实现细节、参数调优的“手感”以及那些容易踩坑的实战经验。2. 聚类算法家族巡礼原理、适用场景与MATLAB实现面对不同的数据分布和业务需求没有一种聚类算法是万能的。选择合适的算法往往比盲目调参更重要。这里我们重点探讨三种最经典、应用最广泛的算法K-Means、层次聚类和DBSCAN。2.1 K-Means效率与球形假设K-Means可能是知名度最高的聚类算法其思想直观预先指定簇的数量K算法通过迭代将样本划分到K个簇中使得每个样本到其所属簇的质心即簇内所有点的均值的距离平方和最小。算法步骤简述初始化随机选择K个样本点作为初始质心。分配对于每一个样本计算其到K个质心的距离将其分配到距离最近的质心所在的簇。更新对于每一个簇重新计算该簇所有样本点的均值作为新的质心。迭代重复步骤2和3直到质心的位置不再发生显著变化或达到最大迭代次数。MATLAB实战MATLAB的kmeans函数封装得非常完善。一个基础调用示例如下% 假设 data 是一个 n×p 的矩阵n个样本p个特征 data randn(300, 2); % 生成300个二维随机样本 K 3; % 假设我们想分成3类 % 调用kmeans函数Display参数设置为final显示最终结果 [idx, C, sumd] kmeans(data, K, Display, final); % idx: n×1向量存储每个样本的簇标签1,2,3 % C: K×p矩阵存储最终得到的K个质心坐标 % sumd: 1×K向量存储每个簇内样本到质心的距离总和 % 可视化结果 figure; gscatter(data(:,1), data(:,2), idx); % 按簇标签着色散点 hold on; plot(C(:,1), C(:,2), kx, MarkerSize, 15, LineWidth, 3); % 标记质心 legend(Cluster 1, Cluster 2, Cluster 3, Centroids); title(K-Means Clustering Results);核心参数与调优经验‘Start’: 初始化方法。默认是‘plus’K-Means这是一种更智能的初始化能有效避免糟糕的初始质心导致收敛到局部最优强烈建议使用默认值。‘sample’是随机选择样本点‘uniform’是随机生成点稳定性较差。‘MaxIter’: 最大迭代次数默认100通常足够。‘Replicates’: 重复运行次数。由于K-Means结果受初始质心影响这是一个至关重要的参数。设置‘Replicates’为10或20让算法用不同的初始质心运行多次最终返回总距离和最小的那次结果能极大提升结果的稳定性。[idx, C] kmeans(data, K, Replicates, 20);适用场景与局限K-Means擅长处理球形或凸形分布、簇大小相近的数据。它的计算效率很高适合处理大规模数据。但其局限性也很明显必须预先指定K值这往往需要业务先验或通过肘部法则等方法评估。对噪声和离群点敏感离群点会显著拉偏质心的位置。假设簇是凸形的对于环形、流形等复杂结构的数据K-Means效果很差。2.2 层次聚类揭示数据层次结构层次聚类不需要预先指定簇的数目它通过计算样本间的相似度构建一个树状的聚类层次图树状图。有两种主要策略凝聚法自底向上开始时每个样本自成一簇然后迭代地将最相似的两个簇合并直到所有样本归于一个簇。分裂法自顶向下开始时所有样本属于一个簇然后迭代地分裂最不相似的簇。MATLAB实战MATLAB使用linkage和cluster函数配合完成。% 生成一些有层次结构的数据 rng(default); X [randn(30,2)*0.52; randn(30,2)*0.5-2; randn(30,2)*0.5[2 -2]]; % 计算样本间距离矩阵 Y pdist(X); % 默认欧氏距离 % 进行层次聚类凝聚法 Z linkage(Y, ward); % 使用Ward方法最小化簇内方差 % 绘制树状图 figure; dendrogram(Z); title(Hierarchical Clustering Dendrogram); % 从树状图中“切割”出指定数量的簇 T cluster(Z, MaxClust, 3); % 切割成3个簇 % 或者根据距离阈值切割 % T cluster(Z, Cutoff, 1.5); % 可视化切割结果 figure; gscatter(X(:,1), X(:,2), T); title(Clusters from Hierarchical Clustering (MaxClust3));核心参数与经验linkage方法‘ward’沃德法倾向于生成大小相近的球状簇最常用‘average’平均距离对噪声相对不敏感‘complete’最远距离倾向于生成紧凑的簇。树状图是核心通过观察树状图的“枝干”长度可以直观判断合理的簇数目。枝干很长的地方进行切割通常意味着分离出了差异较大的簇。适用场景层次聚类特别适合需要展现数据层次关系的场景比如生物分类学、文档主题演化分析。小规模数据下非常直观。但其计算复杂度为O(n³)或O(n² log n)不适合大数据集。2.3 DBSCAN基于密度的噪声容忍高手DBSCAN是一种革命性的密度聚类算法。它不需要指定簇的个数而是基于“簇是数据空间中密集的区域被低密度区域分隔”这一直观概念。它能识别任意形状的簇并且能将低密度区域的点标记为噪声离群点。核心概念ε邻域以某个样本为中心半径为ε的圆形区域。核心点如果某个样本的ε邻域内至少包含MinPts个样本包括自身则该样本为核心点。直接密度可达如果点q在点p的ε邻域内且p是核心点则q从p直接密度可达。密度相连如果存在一个核心点序列使得相邻点之间都是直接密度可达的则这些点密度相连属于同一个簇。MATLAB实战从R2019a开始MATLAB统计和机器学习工具箱提供了dbscan函数。% 生成一个环形加一个球形簇并加入一些噪声 theta linspace(0,2*pi,100); X1 [cos(theta), sin(theta)] randn(100,2)*0.05; X2 randn(50,2)*0.3 [1.5, 1.5]; X3 randn(20,2)*0.1; % 噪声点 X [X1; X2; X3]; % 执行DBSCAN聚类 epsilon 0.3; % 邻域半径 minPts 5; % 核心点最小邻居数 labels dbscan(X, epsilon, minPts); % 可视化噪声点标签为-1用黑色十字表示 figure; gscatter(X(:,1), X(:,2), labels); hold on; plot(X(labels-1,1), X(labels-1,2), k, MarkerSize, 10, LineWidth, 1.5); title([DBSCAN Clustering (\epsilon , num2str(epsilon), , MinPts , num2str(minPts), )]);参数调优的“手感”epsilon这是最关键的参数。一个实用的技巧是绘制k-距离图。计算每个点到其第MinPts个最近邻的距离并排序后绘图。图中拐点距离突然增大的点对应的距离通常是一个较好的ε候选值。[~, D] knnsearch(X, X, K, minPts1); % 找每个点的minPts1个最近邻包含自身 k_dist sort(D(:, end)); % 取第minPts1个距离即第minPts个最近邻的距离 figure; plot(k_dist); ylabel([num2str(minPts), -distance]); xlabel(Points sorted by distance); title(k-distance Graph for Epsilon Estimation);MinPts一般从数据维度p开始尝试经验规则是MinPts p 1。对于二维数据可以从3或4开始。增大MinPts会使算法更“保守”只识别密度更高的区域为簇。优势与挑战DBSCAN能发现任意形状的簇且对噪声鲁棒。但它对参数epsilon和MinPts非常敏感且在高维数据中由于“维度灾难”距离度量可能失效导致效果下降。3. 实战全流程从数据到洞察的完整案例我们以一个虚拟的客户细分场景为例串联起聚类分析的全过程。假设我们有一份客户数据集customer_data.mat包含“年消费额”、“平均订单金额”、“最近一次消费间隔天”、“网站访问频率”四个特征共5000个样本。3.1 数据预处理聚类的基石“垃圾进垃圾出”在聚类中体现得尤为明显。糟糕的预处理会直接导致荒谬的聚类结果。% 1. 加载数据 load(customer_data.mat); % 假设数据变量名为 features (5000×4) % 2. 处理缺失值本例假设无缺失 % 如有缺失可考虑删除或填充如用均值 % features(isnan(features)) nanmean(features); % 列均值填充 % 3. 数据标准化 - 至关重要 % 因为“年消费额”可能数值在万级而“访问频率”在个位级。 % 如果不标准化距离计算将被大数值特征主导。 [Z, mu, sigma] zscore(features); % Z-score标准化 % Z是标准化后的数据mu是均值sigma是标准差 % 也可以使用范围缩放Z (features - min(features)) ./ (max(features)-min(features)); % 4. 可视化初步分布可选看两两特征关系 figure; plotmatrix(Z); title(Pairwise Feature Scatter after Standardization);3.2 确定最佳簇数K-Means的肘部法则与轮廓系数对于K-Means我们需要确定K。两个最常用的方法是肘部法则和轮廓系数。% 肘部法则计算不同K值下的总距离和失真度 maxK 10; distortions zeros(maxK, 1); for k 1:maxK [~, ~, sumd] kmeans(Z, k, Replicates, 10, Display, off); distortions(k) sum(sumd); % 所有簇的距离和之和 end figure; plot(1:maxK, distortions, bo-); xlabel(Number of Clusters K); ylabel(Total Within-Cluster Sum of Distances); title(Elbow Method for Optimal K); grid on; % 寻找“肘点”即曲线拐点。此处可能在K3或4处。 % 轮廓系数衡量一个样本与自身簇的紧密度 vs 与其他簇的分离度 % 值在[-1,1]之间越大越好均值越高说明聚类整体质量越好。 silhouette_vals zeros(maxK-1, 1); % K从2开始 for k 2:maxK idx kmeans(Z, k, Replicates, 10, Display, off); s silhouette(Z, idx); silhouette_vals(k-1) mean(s); end figure; plot(2:maxK, silhouette_vals, rs-); xlabel(Number of Clusters K); ylabel(Average Silhouette Value); title(Silhouette Analysis for Optimal K); grid on; % 选择轮廓系数最大的K值。通常需要结合两种方法以及业务理解来综合判断。假设我们确定K4。3.3 执行聚类与结果分析% 执行K-Means聚类 K 4; [idx_kmeans, centroids] kmeans(Z, K, Replicates, 20, Display, final); % 由于数据是4维无法直接可视化。我们可以使用t-SNE或PCA降维到2维后再看。 % 使用PCA [coeff, score, ~, ~, explained] pca(Z); % 取前两个主成分看其解释的方差比例 disp(前两个主成分解释的方差比例); disp(sum(explained(1:2))); % 在PCA降维后的空间可视化聚类结果 figure; gscatter(score(:,1), score(:,2), idx_kmeans); xlabel(First Principal Component); ylabel(Second Principal Component); title(Customer Segments (K-Means) Visualized by PCA); legend(Cluster 1, Cluster 2, Cluster 3, Cluster 4); % 分析每个簇的特征查看质心在原始特征空间的意义 % 注意质心 centroids 是在标准化空间Z中的。 % 要理解原始特征需要反标准化。 centroids_original centroids .* sigma mu; % 反标准化 cluster_profile array2table(centroids_original, ... VariableNames, {Annual_Spend, Avg_Order_Value, Recency_Days, Visit_Frequency}, ... RowNames, {Cluster1, Cluster2, Cluster3, Cluster4}); disp(Cluster Profiles (Original Feature Scale):); disp(cluster_profile);通过分析cluster_profile表格我们可以为每个簇赋予业务含义簇A高价值活跃用户年消费额高、订单金额大、最近消费近、访问频繁。簇B高价值流失风险用户年消费额高但最近消费间隔长Recency大访问频率低。簇C低频普通用户各项指标均处于中等或偏低水平。簇D新用户/小额高频用户年消费额低但访问频率可能不低订单金额小。3.4 结果验证与稳定性评估聚类是无监督学习没有绝对正确的标签。除了轮廓系数我们还可以通过以下方式增加信心多次运行看一致性由于K-Means的随机初始化多次运行结果应基本一致。可以运行多次计算两两结果之间的调整兰德指数。numRepeats 10; allIdx zeros(size(Z,1), numRepeats); for r 1:numRepeats allIdx(:, r) kmeans(Z, K, Replicates, 1, Display, off); end % 计算第一轮结果与其他轮结果的ARI ari_vals zeros(numRepeats-1, 1); for r 2:numRepeats ari_vals(r-1) rand_index(allIdx(:,1), allIdx(:,r), adjusted); % rand_index函数需要自己实现或从File Exchange获取 end disp([平均调整兰德指数, num2str(mean(ari_vals))]); % ARI接近1表示一致性高。在不同数据子集上聚类使用自助法采样看在子集上得到的簇模式是否稳定。业务验证这是最重要的。将聚类结果交给业务部门看是否符合他们的直觉和经验能否驱动具体的营销动作如对“流失风险用户”进行召回活动。4. 进阶话题与避坑指南4.1 高维数据与降维的协同当特征维度很高p 10时几乎所有基于距离的聚类算法都会受到“维度灾难”影响因为在高维空间中所有点对之间的距离都趋于相似。此时直接聚类效果很差。解决方案特征选择使用方差过滤、基于模型的重要性评估等方法筛选出与目标如果是后续任务或内部结构相关性强的特征。特征降维这是更常用的方法。除了上面用到的PCA线性对于非线性结构的数据可以使用t-SNE或UMAP。它们能更好地在低维空间保持数据的局部结构便于后续可视化观察和聚类。% 使用t-SNE降维需要Statistics and Machine Learning Toolbox Y_tsne tsne(Z, NumDimensions, 2, Perplexity, 30); figure; gscatter(Y_tsne(:,1), Y_tsne(:,2), idx_kmeans); title(Clusters Visualized in t-SNE Space);重要提示t-SNE/UMAP降维后的坐标仅用于可视化不应在其之上直接运行聚类算法因为其距离关系已被非线性扭曲。正确的流程是在原始高维空间或PCA降维后的空间进行聚类然后用t-SNE可视化结果。4.2 混合型数据与距离度量我们的例子中数据都是数值型的。现实中常包含分类变量如性别、职业。处理混合型数据是聚类的一大挑战。常见策略将分类变量独热编码但会极大增加维度且欧氏距离对独热编码的解释性不强。使用能处理混合距离的算法如K-PrototypesK-Means的扩展或使用Gower距离。Gower距离能同时处理数值型和分类型变量计算样本间的综合相异性。MATLAB中没有内置函数但可以自己实现或寻找第三方代码。计算Gower距离矩阵后可以传递给linkage进行层次聚类或通过cmdscale进行度量多维缩放后再用K-Means。4.3 那些年我踩过的坑忘记标准化这是新手最常犯的错误会导致聚类结果完全由量纲大的特征主导。任何基于距离的算法在开始前都必须考虑标准化或归一化。盲目相信“最佳K值”肘部法则的拐点可能不明显轮廓系数可能给出多个局部峰值。没有银弹必须结合业务背景、聚类结果的可解释性综合判断。有时业务上明确的3类划分即使轮廓系数略低于4类也可能是更优选择。用聚类结果直接做预测聚类是无监督学习得到的簇标签没有预测意义。不能像分类模型那样用历史聚类结果去预测新样本的类别。对于新样本通常计算其与已有各簇质心的距离分配到最近的簇但这只是一种“归类”其可靠性取决于新样本与训练数据分布的相似性。忽略可视化尤其是在确定参数和评估结果时一定要画图。散点图、平行坐标图用于高维簇特征分析、树状图、轮廓图都是理解数据和模型的好工具。DBSCAN参数设置过于随意不画k-距离图拍脑袋定epsilon结果要么全是噪声要么全是一个簇。花时间理解数据和参数的含义是用好DBSCAN的前提。聚类分析更像一门艺术需要在数学严谨性和业务直觉之间找到平衡。MATLAB提供的强大工具箱和可视化能力让我们能够快速迭代和探索。记住聚类的终极目标不是得到一个“数学上最优”的划分而是获得对数据深刻、有用且可行动的洞察。每一次聚类实验都是与数据的一次深度对话。
返回列表