
简介面向数据挖掘、模式识别与市场细分等应用场景的聚类分析专题课件围绕系统聚类、快速聚类及MATLAB实现展开讲解Q型与R型聚类、样品间距离度量、谱系聚类步骤并结合pdist、linkage、dendrogram、cophenet、cluster等函数给出可操作的实现思路。资源共1个pptx文件压缩包大小467KB内容紧凑、配有聚类图与案例数据适合高校统计课程学习者、科研人员及需要入门聚类算法与MATLAB编程的工程师。目前已有125人学习浏览。通过该PPT可系统理解聚类分析的基本思想掌握从数据预处理、距离与相似系数计算到聚类树绘制、类别判定的完整流程并获取典型例题的MATLAB求解演示便于直接对照练习或嵌入教学课件使用。1. 聚类分析与MATLAB为什么这份资料值得你照着敲一遍聚类分析是机器学习里最常用的无监督方法但很多人一上来就想手写算法反而把工具链忽略了。以「聚类分析及MATLAB实现PPT资料」这类课件为入口你会发现用MATLAB做聚类实验能绕开大量底层编码kmeans、linkage、dbscan都是现成函数半天就能把数据聚类、评估和可视化全部跑通剩下的精力可以用在参数理解和结果解释上比从零重写一遍K-means更有产出。这份资料适合三类人交课程作业的本科生、想在论文里补一组对比实验的研究生、以MATLAB为主要分析环境的工程师。前置要求不高会矩阵操作和基本统计概念就能跟上。后面的章节按我整理同类课件的一贯顺序展开先立住原理再给可运行的代码最后逐个拆坑。2. 聚类分析的核心距离度量和三类范式怎么选才不翻车2.1 距离度量欧氏距离不是唯一答案聚类里的“相似”和“不相似”完全由距离定义决定这是第一步就要走对的地方。kmeans函数默认使用sqeuclidean欧氏距离的平方很多人一直用默认值结果数据一变就翻车。举一个很典型的场景对商品做分群特征是价格、销量、上架天数。价格量级可能是几百销量可能上万上架天数只有几十。用欧氏距离时销量这一列会主导总距离价格和天数的差异被稀释聚类结果几乎只反映销量分组。两个解决方向先标准化再算距离或者换距离度量。cityblock曼哈顿距离对个别列离群值更稳当特征是用户行为占比、文本词频这类方向性数据时用cosine更合理。% 三种距离在 kmeans 中的用法对比 [idx1, C1] kmeans(X, 3, Distance, sqeuclidean); % 默认欧氏距离平方 [idx2, C2] kmeans(X, 3, Distance, cityblock); % 曼哈顿距离抗离群点 [idx3, C3] kmeans(X, 3, Distance, cosine); % 余弦距离看方向不看模长这段代码的逻辑其实很简单Distance参数决定了样本到质心的距离怎么算也决定了质心如何更新。sqeuclidean适合标准化后的连续数值特征cityblock用的是各维度绝对差之和极端值带来的扰动比平方小cosine则把样本看成方向向量适合模长本身没有业务含义的数据。注意cosine模式下质心会被重新归一化距离含义和欧氏完全不同结果解释要跟着变。如果做层次聚类还需要用pdist单独生成距离矩阵这点经常被初学者漏掉D pdist(X, correlation); % 相关距离适合特征间高相关、量纲差异大的数据 Z linkage(D, average); % 距离矩阵直接进 linkagepdist输出的是紧凑形式的上三角距离向量linkage可以直接消费。correlation距离关注的是样本间趋势是否一致而不是绝对数值差基因表达、评分偏好这类场景下比欧氏距离合理得多。我自己的习惯是先想清楚“我要让哪个维度上的差异驱动分群”再选距离度量而不是对着默认值一路跑到底。2.2 三类聚类范式划分、层次、密度适用边界要分清K-means是划分聚类目标是把样本分成K个球形簇算法快、结果好解释但必须先给定K遇到环形、半月形这类非凸簇会硬生生切开。层次聚类不要求预设K先用linkage把所有样本逐步合并成一棵树之后在树的任意高度切分适合连“到底分几类”都还没想清楚的探索阶段。DBSCAN则按密度把稠密区域连成簇同时自动标记噪声样本任意形状都能处理但在密度差异很大的数据上表现不稳定。MATLAB里三个家族的入口分别是kmeans、linkagedendrogramcluster、dbscan。它们输出内容也不一样kmeans直接给簇标签和质心坐标层次聚类先给树结构再靠你在某个高度切dbscan除了簇标签还会返回核心点标记数组告诉你哪些样本是密度核心。下面这张表我每次讲课件都会放用来快速选型方法簇形状假设是否预设K噪声容忍度主要MATLAB函数K-means凸形、尺度相似必须低离群点会拉偏质心kmeans层次聚类无特定形状不需树上切中取决于linkage方法linkage、dendrogram、clusterDBSCAN任意形状不需高自动标噪声dbscan选型的核心是问自己两句话第一我是否已经知道大概分几类知道就K-means不知道就层次或DBSCAN。第二我的簇是紧凑球形还是可能弯弯曲曲数据本身形状复杂、还有明显噪声点直接上DBSCAN比硬调K-means的K值省事得多。2.3 评估指标轮廓系数、CH与DB指数要配合着看聚类没有标准答案只能用内部指标判断“分得是否紧、离得是否开”。MATLAB把这项能力收敛在evalclusters函数里一次调用能算一个指标并自动筛选最优K。我一般会跑三遍分别看轮廓系数、Calinski-HarabaszCH和Davies-BouldinDB三个指标往往不会指向同一个K这时候交叉判断才有意义。rng(1); % 固定种子evalclusters内部也会调用kmeans evaSil evalclusters(X, kmeans, silhouette, KList, 2:8); evaCH evalclusters(X, kmeans, CalinskiHarabasz, KList, 2:8); evaDB evalclusters(X, kmeans, DaviesBouldin, KList, 2:8); K_sil evaSil.OptimalK; % 轮廓系数选出的最优K K_ch evaCH.OptimalK; % CH指数选出的最优K K_db evaDB.OptimalK; % DB指数选出的最优Kevalclusters会对KList里的每个K跑一次聚类再按指标打分帮你把“不同K下的质量曲线”一次算完。轮廓系数值域是-1到1越接近1说明样本贴着同类簇、远离其他簇CH是类间离散度与类内离散度的比值越大越好DB是类内散步和类间距离之比越小越好。三个指标侧重点不同轮廓系数偏向紧致球形簇CH对大间距划分更友好DB对重叠簇更敏感。我自己的标准是看三个指标有没有共同指向的K如果有就选它如果没有选业务上更好解释的那个。评估指标是必要不充分条件。数值上“分得好”不代表业务上“分得对”这个坑会在第5章展开。3. 用MATLAB实现K-means从数据清洗到K值确定的完整步骤3.1 数据准备读入、清洗、标准化一步到位开始聚类之前数据从文件到矩阵的这段路经常被当作“无技术含量”跳过实际上这里出问题的概率比算法本身大。readtable能自动推断列类型适合混合数据但如果文件里有ID列、日期列记得先摘掉否则聚类会把样本ID当数值特征算进距离里结果瞬间变成“谁和谁编号相邻”。% 读入CSV假设第一列是样本ID其余是特征 T readtable(data.csv); Xraw T(:, 2:end); % 去掉ID列 X table2array(Xraw); % table转数值矩阵 X rmmissing(X); % 删除包含缺失值的行 X zscore(X); % 按列标准化均值为0、标准差为1rmmissing默认按行删除某行只要有一个NaN就会被整行删掉。如果缺失集中在少数特征列比如某列缺了30%删行会让样本量骤减这时候考虑先删高缺失列再做行删除。zscore按列做标准化是我认为聚类前最不该跳的一步。标准化的意义不是玄学而是让每一列在距离计算里获得相同的初始权重。还有一种常见做法在标准化前先做分位数截断防止极端值把标准化后的分布拉偏。% 对每列做分位数截断把超出[1%, 99%]区间的值拉回边界 for j 1:size(X, 2) lo quantile(X(:, j), 0.01); hi quantile(X(:, j), 0.99); X(:, j) min(max(X(:, j), lo), hi); end X zscore(X);这段的用意是长尾特征很重的时候直接zscore仍然会保留极端值聚类结果几乎由那几个极端样本主导。截断之后再做标准化稳定性能明显改善。这一整段“清洗再标准化”的流程值得整理成你自己的预处理脚本每一次聚类实验都从它开始。3.2 一个最小可用的kmeans调用与关键参数kmeans在MATLAB里是非常成熟的实现但默认参数只适合快速验证正式分析至少要改两个地方固定随机种子、设置Replicates。rng(42); % 固定随机种子确保结果可复现 K 3; [idx, C, sumd] kmeans(X, K, ... Distance, sqeuclidean, ... Replicates, 10, ... MaxIter, 200); SSE sum(sumd); % 总离差平方和肘部法则的素材参数逐个说清楚K目标簇数不能拍脑袋定应该由第2章的评估流程或者业务约束给出。Replicates, 10用不同初始质心随机跑10次取目标函数最小的结果。默认值是1意味着只初始化一次碰上糟糕的起点可能收敛到局部最优。正式实验我通常设10到20次。Start, plus默认就是k-means初始化比纯随机稳定得多一般不用改。它是一份后悔药在样本量大、簇形不规则时能明显降低初始化带来的方差。MaxIter, 200默认100数据量大且分布复杂时可能到迭代上限还没收敛建议放宽到300以上。并行选项数据量大、Replicates高的时候在kmeans里加一行Options, statset(UseParallel, true)能压掉接近一半时间。注意Replicates和并行都依赖rng。不在脚本最前面固定随机种子复现实验就是空话这也是一些实验室“同代码不同结果”的根源。聚类后画图是第一时间确认结果是否合理的动作gscatter(X(:, 1), X(:, 2), idx); % 用前两列特征着色画散点 hold on; plot(C(:, 1), C(:, 2), kx, MarkerSize, 12, LineWidth, 2); hold off;gscatter会按组别自动分配颜色质心用黑色叉号叠加适合K比较小时看图。特征超过两维时这个画法会失真我一般先对X做PCA取前两个主成分再喂给gscatter能看到整体分离形态。3.3 确定K值肘部法则的代码化做法K值到底怎么选最朴素的工具是肘部法则跑K从1到10的kmeans记录每个K的总离差平方和SSE然后画折线找“由陡变缓”的拐点。注意K1没有意义但作为曲线起点可以保留。rng(42); SSE zeros(1, 10); for k 1:10 [~, ~, sumd] kmeans(X, k, Replicates, 10); SSE(k) sum(sumd); end plot(1:10, SSE, -o); xlabel(K); ylabel(SSE);用眼睛看拐点最直接但写论文时想有个量化依据可以算二阶差分d1 diff(SSE); % 一阶差分每增加K时SSE的下降量 d2 abs(diff(d1)); % 二阶差分下降量本身的变化幅度 [~, elbow] max(d2(1:end-1)); K_candidate elbow 1; % 候选K这段代码的思路是SSE下降速率从大到小的转折处就是肘点。d1记录的是“多分一类能减少多少误差”d2记录的是这个减少量是否明显变小d2最大值对应的位置通常就是曲线坡度突变点。注意索引偏移d2的第i个值对应K从i1到i2的变化所以候选K加1。自动定位只是辅助我强烈建议同时对照2.3节evalclusters的结果多个方法指向同一个K时这个选择才站得住。肘部法则的局限性在平滑数据上很突出曲线没有明显拐点SSE一路缓慢下降这时K值选择必须回归业务。比如电商分群K4正好对应运营团队能承接的四类人群画像那就不必为了“统计上更优”选K6。4. 层次聚类与DBSCAN的MATLAB实现两张图看懂参数敏感度4.1 linkage、dendrogram、cluster层次聚类的完整流程层次聚类在MATLAB里由三个函数接力完成linkage建树、dendrogram画树、cluster切树。最小代码很干净但这三步里有不少参数会影响结果走向。rng(42); Z linkage(X, ward, euclidean); % ward离差平方和法欧氏距离 dendrogram(Z, 0); % 0表示显示全部叶子节点 idx cluster(Z, MaxClust, 4); % 把树切成4个簇linkage的第二个参数是合并准则这是层次聚类真正的“个性开关”ward合并样本时让类内离差平方和增量最小倾向得到大小均匀的紧凑簇连续数值特征最常用。average类平均距离对离群值稳健适合形状不规整的数据。complete类间最远距离容易切出细长簇。single最近距离很容易产生链式效应不到万不得已不太推荐。dendrogram的第二个参数控制显示多少叶子节点0表示全显示。样本超过1000时整张树状图会挤成一堵墙什么都看不清这时候改成dendrogram(Z, 200)只显示最近合并的200个叶子局部结构会清楚得多。cluster切树用的是MaxClust意思是“保留4个簇”但同样在树上画一条水平线看它穿过几条竖枝就知道这个切割对应的簇结构是否稳定。有一项像“质量检查”的指标值得每次算一下c cophenet(Z, pdist(X, euclidean)); % 越接近1树结构越能代表原始距离cophenet把树上的合并距离与原始样本距离做相关越接近1说明这棵树忠实地反映了样本间的远近关系。数值低于0.6时要么换合并准则要么换距离度量否则树状图讲的故事可信度很低。4.2 dbscaneps和minpts怎么配合才能结束调参玄学DBSCAN在MATLAB里就是一个dbscan函数但两个前置参数把很多人卡住了。它不像kmeans那样有K值一切由密度定义而密度的两个坐标系是邻域半径eps和邻域内最少点数minpts。rng(42); [idx, corepts] dbscan(X, eps, minpts); % idx: 每个样本的簇标签-1表示噪声 % corepts: 逻辑向量true表示该样本是核心点minpts建议从2倍特征维度开始。维度为5时minpts取10维度是20时从40起步。minpts太小一点轻微波动就会形成碎片簇太大真正的稠密簇会被拆碎。定好minpts之后再去反推eps这是DBSCAN调参的标准流程顺序不能倒。eps可以用k距离图来定这比反复试参数可靠得多minpts 2 * size(X, 2); % 经验初值 D pdist2(X, X); % 两两距离方阵 Dsort sort(D, 2); % 每行按距离升序 kDist Dsort(:, minpts); % 每个样本到第minpts个近邻的距离 plot(sort(kDist, descend));横轴是样本按k距离降序排列后的序号纵轴是k距离。曲线平缓段对应稠密区域突然上翘的位置就是稠密区与稀疏区的分界取上翘处的纵坐标作为eps的初始值。图上的“膝盖”不是精确数学定义所以拿到初始值后我会在它上下各试两三个数对比簇数量和噪声比例噪声超过20%说明eps偏小全部样本挤成一个簇说明eps偏大。4.3 三种聚类在非凸数据上的表现差异有一类数据是聚类方法的“照妖镜”两个半环交错分布或者螺旋带噪声。K-means在这些数据上会强制按球形切把一个环切成好几段层次聚类在ward准则下也会偏紧凑但改用average能保留一部分链式结构DBSCAN只要eps选对通常能还原出半环的原始形状还能把游离噪声单独标记出来。我把这类对比总结成一句话聚类方法没有绝对优劣只有“数据形状 业务诉求 方法假设”三者是否匹配。做课件时我习惯放三张图并排对比比任何表格都直观。如果你手头没有现成数据可以生成模拟数据自己跑一遍两个半环、一团高斯、一堆均匀噪声分别跑三种聚类观察簇标签和真实形状的吻合度。这个练习做完对三个函数的边界理解会扎实很多。5. 聚类分析及MATLAB实现避坑六条血泪经验一次讲清5.1 不标准化就跑聚类量纲差异让结果“看着合理但全是错的”现象数据里有一列数值明显大于其他列聚类结果表面正常轮廓系数也不算差但业务一看分群维度发现几乎只按那一列在分。原因欧氏距离里大数值特征贡献绝对主导小数值特征在距离计算里近似噪声。MATLAB的kmeans不会自动按特征加权默认距离默认就是看“数值差”。解决聚类前先做zscore标准化。二值变量和连续变量混在一起时二值列不要做zscore用min-max缩放到0到1区间更好处理顺序是清洗、截断、标准化、再聚类。这一步不做后面所有指标和可视化都是自欺欺人。5.2 K-means每次跑结果都不一样实验无法复现现象同一份代码第二次运行的质心和簇标签都变了自己画出来的图和同事复现的图对不上。原因kmeans默认用k-means初始化带随机性默认只跑一次碰到坏起点会收敛到局部最优不稳定的实验结果就是这么来的。解决脚本最前面写rng(42)固定随机种子调用kmeans时设置Replicates, 10以上让算法自己筛掉差的初始中心。注意DBSCAN和层次聚类本身是确定性的不需要rng而kmeans和tsne这类带随机初始化的函数必须固定种子。5.3 DBSCAN的eps只能靠肉眼试调参变成玄学现象eps从0.1试到1.0要么几乎全是噪声要么所有样本变成一个簇中间只隔着很窄的可行区间根本不知道“正确值”在哪。原因eps的合理范围完全由数据密度决定不同数据的合适eps可能相差几个数量级直接看数据值范围猜不出来。解决按“先minpts后eps”的顺序来。minpts取2倍特征维度然后用k距离图的“膝盖”位置定eps初值再围绕初值上下扫几个数。判断时观察噪声点比例和簇数噪声超过20%说明eps小了全部样本聚成一类说明eps大了。5.4 高维数据直接聚类距离退化导致无法解释现象30维特征直接kmeans指标不低质心坐标却是一堆小数画图只能取两维报告根本没法向非技术的人解释。原因高维空间下欧氏距离趋于平均样本间距离差异变小聚类边界模糊相关性强的特征还会重复参与距离计算相当于给某些信息加权了。解决先PCA降维到能解释80%以上方差的前几个主成分再做聚类。如果只是为了可视化取前两个主成分画gscatter足够如果为了稳定聚类保留到85%方差那档即可。另一个思路是把距离换成correlation让相关性而不是绝对数值驱动分群——这是改变距离语义不只是换个参数。5.5 轮廓系数遇到密度聚类不友好别被单一指标带偏现象DBSCAN跑出的簇形状清晰但silhouette值只有0.2而K-means的轮廓系数有0.6于是误以为DBSCAN不如K-means。原因轮廓系数用样本到同类簇均值、最近其他簇均值的距离构造隐含球形簇假设。DBSCAN产生的任意形状簇和噪声样本都会拉低这个值指标不匹配不是聚类不好。解决密度聚类不要单独依赖轮廓系数。改看核心点占比、噪声比例、不同eps下簇数的稳定性。如果必须和其他方法比指标先把噪声样本剔除再算轮廓值并在报告里说明这个处理。5.6 统计指标漂亮但业务无法解释现象轮廓系数0.72CH指数也高但分出来的簇画像没有明显差异或者某个簇同时包含行为上互斥的用户业务无法落地。原因内部指标衡量的是数值分离度不代表业务含义的区分度聚类标签是纯数据驱动产物和运营口径可能完全错位。解决聚类之后必须做画像分析每个簇的特征均值、中位数、占比再叠加业务标签做交叉验证。如果画像讲不出一个“为什么”回去调整特征集而不是继续调参。这是我反复经历后最认同的一条聚类输出的是候选分组不是最终结论。6. 把聚类结果讲清楚可视化、轮廓图与画像描述的进阶习惯6.1 t-SNE降维看聚类整体形态PCA是线性降维适合压缩特征要看簇在原始空间里的真实分离形态t-SNE更直观。MATLAB里直接调tsne函数对高维聚类结果做二维投影再叠加聚类标签着色。rng(42); Y tsne(X, NumDimensions, 2, Perplexity, 30); gscatter(Y(:, 1), Y(:, 2), idx);Perplexity平衡局部与全局视角默认30对绝大多数数据够用样本量小的时候可以降到5到15否则t-SNE图会显得过度挤压。t-SNE是有随机性的多跑几次看整体结构是否稳定别拿单次结果讲故事。6.2 silhouette图找出被硬凑进簇的样本轮廓系数除了给一个平均数还可以画成每样本一条横杠的图。负值样本就是“离其他簇比离自己簇更近”的硬凑分子值得单独检查。figure; silhouette(X, idx); xline(0, --); % 在0处画参考线负值条一目了然我会把这些负值样本挑出来看原始特征是录入错误还是极端值或者是某个簇里混入了本应属于其他簇的数据。确认后再决定剔除还是保留而不是直接改K值避开问题。6.3 聚类画像描述模板从数字到业务语言把聚类结果从标签数组变成业务事实我习惯先算一张汇总表簇样本数占比特征A均值特征B均值一句话描述1............高活跃、低客单2............新客、品项少每簇写一段横向对比“第1簇样本占比35%A高、B低可以定位为……人群资源投放应该……”如果这句话写不出来要么特征选择有问题要么K不匹配回到前面重新审视距离度量、标准化和K值的选择。我早期交聚类报告只看轮廓系数和散点图被追问“这类用户为什么均价这么低”时答不上来因为只看了聚类编号没做画像。后来养成习惯每跑一组聚类先回答“每个簇是谁、和别的簇差在哪、下一步做什么”答不上就回去检查。这个流程比任何参数优化技巧都重要也治好了我对聚类结果黑匣子式的信任。希望帮到你。本文还有配套的精品资源点击获取