简介一份面向数据分析入门者与广告运营人员的K-means聚类实战项目围绕广告渠道90天核心指标日均UV、注册率、搜索率、访问深度、停留时长、订单转化率等进行渠道分群帮助定位每类渠道的关键特征为投放策略优化和业务讨论提供数据支撑。压缩包共4个文件含2份csv原始与结果数据、1个Python聚类脚本和1份PDF分析报告整套资源仅617KB轻量易用。已有1978人学习该资源适合需要快速上手聚类分析并落地业务场景的读者。通过源码可复现完整聚类流程理解特征预处理、K值选择与结果解释结合PDF报告可学习如何从聚类结果提炼渠道重点特征形成可汇报的数据分析结论。项目数据集直接可用便于对照练习是广告数据分析与机器学习入门的高性价比资料。 做广告投放和用户增长的同学大概率都遇到过这种情况手里攒了一堆广告数据包括曝光、点击、转化、消费、时段分布但除了能看出来整体ROI还行之外很难说清楚哪些用户值得重点追投哪些渠道纯粹在烧钱。单纯看报表看不出什么结构性问题因为数据是多维度的人脑处理不了七八个维度叠加在一起的规律。这个zip项目就是用K-means把广告数据里隐藏的“人群结构”给刨出来。K-means是无监督聚类算法里的入门主力它的核心逻辑是在不知道标签的前提下根据样本特征之间的欧氏距离把数据点划到K个簇里让同一个簇内的样本尽量相似不同簇之间的样本尽量疏远。放在广告场景里就是把一大堆带曝光、点击、转化、消费特征的用户聚成几大类每一类天然就是一个可落地的策略单元。做出来的效果是你不用拍脑袋说“我感觉有个群体适合追投”而是数据自己告诉你“这边有4类人每一类的消费习惯和转化特征是这些”。项目用sklearn搭建完整代码和数据集都放在压缩包里适合正在学机器学习的学生、刚入门的数据分析师以及想用数据驱动投放决策的运营同学拿去直接改成自己的脚本。1. 项目整体设计与思路拆解1.1 广告数据聚类的业务价值广告投放里最经典的一个问题是预算怎么分。假设你一个月投放100万所有用户平均分配预算那一定亏。因为不同用户的行为差异极大有人看广告20次都不点有人第一次曝光就完成付费有人单笔客单价极高但几个月才复购一次有人虽然客单价低但几乎天天买。这几类人根本无法用同一个投放策略去对待。聚类分析在中间扮演的角色是“自动划版”。它不关心你给不给标签也不依赖你对业务有多深的认知它只看数据特征之间的真实分布关系然后把相似行为模式的人归到一起。这个过程中最大的价值不是“分了几个类”而是每一个类出来之后你都能提一个明确的问题这类人的转化为什么这么高那类人的消费为什么集中在凌晨带着问题去复盘数据才容易得出有效结论。对比一下传统手工人群划分。过去运营喜欢按年龄、性别、地域这类人口统计学属性去切人群但这种划分方式默认了“同一年龄段的人消费行为相似”这在大多数行业里都是不成立的。把行为特征直接喂给K-means做聚类等于让数据自己说话不再依赖预设的经验框框能发现不少反直觉的规律。1.2 为什么选K-means而不是其他聚类算法广告数据聚类场景下K-means几乎是首选。原因有两条。第一广告数据样本量大经常几百万行级别。K-means时间复杂度接近线性即使几十万样本也可以在十几秒到几十秒内完成聚类而层次聚类或者基于密度的DBSCAN在大样本下计算量会爆炸式增长。第二K-means的结果可解释性很强每个簇可以用质心向量的形式输出质心每一维对应一个特征的均值直接就能读出“这个簇曝光高但是点击低”之类结论对业务人员友好。K-means当然也有短板它对初始质心敏感对异常值和噪声不鲁棒而且只擅长发现“球形”的簇结构。但在广告场景里绝大多数特征可以统一量纲后近似呈球形分布而且我们关注的是投放策略分级不需要识别特别奇形怪状的簇所以这些短板在业务层面是可以接受甚至忽略的。反过来说如果一上来就上高斯混合模型或者谱聚类解释成本和调参成本都要高不少反而偏离了“快速拿到结论”的初衷。2. 数据预处理与特征工程2.1 广告数据能拿到哪些字段做K-means先要回答一个问题拿什么特征去聚特征选得对不对直接决定了聚类结果有没有业务意义。广告系统里能导出的用户行为字段大概分三组。第一组是用户曝光与点击类曝光次数、点击次数、点击率、最后一次点击距今的天数。第二组是转化与消费类转化次数、消费总额、客单价、最近一次购买距今的天数。第三组是活跃与渠道类日均活跃时长、常用登录时段可以转成数值比如把夜间占比单独抽出来、广告渠道编号这个一般不做聚类特征用来做回溯分析。真正放进K-means的特征应该控制在6到10个左右太少了区分度不够太多了会把簇切得过分细碎。以项目自带的广告投放样本数据为例最终进入聚类的字段包括exposure_cnt曝光次数、click_cnt点击次数、ctr点击率、conv_cnt转化次数、total_spend消费金额、avg_order_value客单价、recent_gap_days最近动作距今的天数和active_hours日均活跃时长。八个维度不算多但已经覆盖了从“拉新”到“促活”再到“收割”的关键链路。2.2 特征标准化这一步不做聚类白做广告数据里天然有一个问题不同字段的量纲差距太大。比如曝光次数可能是几万级消费金额可能是几千级而点击率是0到1的小数。K-means在计算欧氏距离时数值范围大的特征会完全压制数值范围小的特征。一个极端栗子如果曝光的量级是1万点击率的范围只有0.1那距离计算的结果几乎只由曝光次数决定点击率这个维度有和没有是一样的聚类出来的簇就变成了“按曝光高低分桶”。所以任何K-means项目第一件事就是标准化。对于广告类连续数值特征优先用StandardScaler做z-score标准化把每个特征变换到均值为0、方差为1的分布上。代码就几行from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_scaled scaler.fit_transform(df[feature_cols])有人会问能不能用MinMaxScaler缩放到0到1之间。可以但对广告数据来说StandardScaler通常效果更好因为MinMaxScaler会被极值影响比如一个用户的消费金额特别高会把整个字段的缩放比例压扁标准化的意义就被破坏了。另外一定要先切分数据集再fit scaler避免数据泄露的问题虽然是无监督场景但这个好习惯还是值得保留。3. K值怎么定肘部法则与轮廓系数3.1 手写一个K值寻优小脚本K-means最大的一个“用户干预点”就是K值。项目没有用拍脑袋的方式去定K而是同时跑了两套评估手段肘部法则Elbow Method和轮廓系数Silhouette Score。先说肘部法则它的思路是计算不同K值下所有样本到所属簇质心的距离平方和inertia随着K增大inertia一定变小但变小的速度会有一个从陡到缓的转折点这个点就是“肘部”对应的K就是比较合理的簇数量。实际写代码的时候直接把K从2扫到10保存每次的inertia值然后画折线图from sklearn.cluster import KMeans import matplotlib.pyplot as plt inertia_list [] K_range range(2, 11) for k in K_range: km KMeans(n_clustersk, random_state42, n_initauto) km.fit(X_scaled) inertia_list.append(km.inertia_) plt.plot(list(K_range), inertia_list, markero) plt.xlabel(K) plt.ylabel(Inertia) plt.title(Elbow Method) plt.show()3.2 怎么判断最终选几个簇肘部法则有一个经典的主观性转折点在图上不一定特别锐利。这种时候需要用轮廓系数来做交叉验证。轮廓系数对每个样本计算b - a/ max(a, b)其中a是样本与同簇其他样本的平均距离b是样本与最近的其他簇中样本的平均距离。系数取值范围在-1到1之间越接近1表示聚类效果越好簇内越紧凑、簇间越分离。跑完两个指标项目的样本数据呈现出来的结果很标准K为2到4时轮廓系数一路往上走inertia下降也很快K为5时轮廓系数开始掉头inertia下降趋于平缓。最终选择K4既保证了簇数量不过度细分又让每个簇的样本量足够支撑后续的投放策略分析。这里想强调一点K值不是越大越好K15确实可以把用户分得更细但分出来很多簇之间业务差异并不大营销团队也没法为15个簇单独设计15套素材。聚类最终要服务于决策所以K值选择要同时考虑统计指标和业务可落地性。4. K-means核心实现sklearn实操4.1 训练与核心参数在项目里聚类主体的代码很短但有几个参数值得单独拿出来说它们决定了聚类结果的质量和稳定性。from sklearn.cluster import KMeans km KMeans( n_clusters4, initk-means, n_init10, max_iter300, tol1e-4, random_state42 ) km.fit(X_scaled) df[cluster] km.labels_initk-means默认参数用了一种更聪明的质心初始化方式随机选第一个质心然后按距离加权的方式选后续质心可以大幅降低收敛到局部最优的概率。实际跑下来k-means比纯随机初始化耗时多一点点但聚出来的簇稳定得多。n_init10表示用不同的随机质心起始点跑10次每次跑完保留最优结果。早期sklearn版本默认是10新版默认改成了auto但为了结果可复现写死10比较稳。max_iter300单次运行的迭代上限一般300次足够数据量大时可以适当降到100速度会快不少。tol1e-4收敛阈值两次迭代之间质心变化小于这个值就停止。1e-4是一个合理的默认值改小了精度提升有限但耗时明显增加。random_state42固定随机种子。这个习惯非常关键不固定的话同一条数据每次跑出来的结果都可能不同复盘的时候根本没法对齐。标准化之后建议把聚类结果expose到原始DataFrame上也就是把km.labels_存成新的一列df[cluster]。后续算每个簇的均值、人数占比、消费占比直接groupby cluster就能搞定不需要额外维护索引映射。4.2 聚类结果解读给每个簇打标签聚类跑完只是第一步接下来的工作才是核心解读质心。质心km.cluster_centers_是标准化空间里的坐标直接看数值不是很直观建议把标准化后的均值还原到原始尺度。项目里用了一个简单办法直接按簇分组对每个聚类簇的原始特征做均值统计。项目这批广告数据K4聚类后四个簇呈现出非常清晰的差异这里列举一下特征均值的还原值示意数据簇编号曝光次数点击率转化次数消费金额客单价最近动作天数簇特征0870.0211.21561302.3新客试探期110240.0090.3429114.6高曝光低转化23120.0456.88801291.8忠诚重度用户3960.0120.19888.3沉默流失边缘四个簇的业务标签非常清晰。簇2是典型的高价值人群转化率高、复购间隔短是广告投放里最值得用高预算重点触达的人群。簇0是潜力新客曝光和消费都中等但点击率相对不错可能还处于了解产品的阶段适合推送新客专享权益来拉升转化。簇1问题最大曝光量巨大但点击率低可能素材匹配度不好也可能这部分人根本不是目标用户。簇3则处于沉睡边缘需要用召回策略。整个过程最关键的一步就是这种把质心数据还原回业务含义的过程。很多人跑完聚类就停下来了觉得拿到簇标签就是完成了其实聚类本身不产生价值对簇的合理解读和后续针对每个簇制定策略才是价值所在。这个项目在zip里附了一个result_profile.py脚本逻辑就是上面这套对每个簇计算特征均值、样本占比、消费贡献占比然后自动生成一张画像表可以直接输出到Excel给业务侧用。5. 常见问题与排查技巧5.1 K-means聚类结果不稳定怎么办如果同一份代码跑出来的簇标签每次都不一样排除random_state没固定的情况后大概率是数据分布本身的问题——存在比较严重的重叠区域或者标准差差异极大。遇到这种情况加n_init次数会有一定帮助把10改成20甚至50让算法在更多随机起点中选最优解。如果加n_init之后仍然不稳定建议检查数据里是否有极端异常值特别是消费金额特别高的少量样本会把质心拽得很远。可以用分位数截断或者IQR过滤的方式处理异常值。项目里处理过这样一个案例训练样本里有3个用户的消费金额达到十万级其余用户平均只有两三百标准化之后这3个样本变成了距离其他点二三十个标准差的离群点。它们会让其中一个簇的质心严重偏移导致这个簇几乎只包含这3个人其余用户全部被压缩到另一个簇。处理方式是把消费金额字段做95分位数封顶然后再标准化聚类结果才恢复正常。5.2 类别型特征能直接放进K-means吗这是一个高频问题。广告数据里经常有“渠道类型”“地区”“用户终端”这类文本特征有些人会图省事直接用LabelEncoder转成数字扔进去。这样做是不对的因为编码后的数字会隐含人为设定的顺序大小关系比如安卓0、iOS1、Web2K-means在算欧氏距离时就会认为Web和iOS的距离是1而Web和安卓的距离是2这个顺序是编码时随意定义的没有任何业务依据。类别型特征一共两种处理思路。第一种是一般规律把它从聚类特征里去掉单独做聚类后的交叉分析。这是最推荐的做法因为聚类本身是找行为规律渠道、地区这类属性更适合作为簇标签的回溯维度去解释“这簇人来自哪里”而不是参与到相似度计算中。第二种是如果确实要把类别特征放进模型可以用One-Hot编码展开成多个0/1列但这样会稀释连续特征在距离计算里的权重所以还需要配合特征加权复杂度会高不少。在广告场景里我强烈建议走第一种思路干净直接结果也容易解释。5.3 zip项目解压后环境配置的三个坑这个项目的zip包下载后最容易出问题的地方不在代码本身而在运行环境的配置。第一个坑是sklearn版本不对。老版本sklearn里KMeans的n_init参数默认值是10新版默认改成了auto如果代码里直接写n_initauto在旧版本环境会直接抛异常。建议先检查环境里的版本代码里干脆显式写成n_init10这样跨版本都不会出错。第二个坑是压缩包解压后路径带中文或者空格。sklearn在pandas读csv时一般不受影响但如果你后续要把模型结果保存成pickle文件中文路径在部分操作系统上会报编码错误。项目目录最好全部用英文字母命名这是很多初学同学没意识到的细节。第三个坑是zip文件在GitHub下载后丢失可执行权限这在Windows下问题不大但Mac和Linux环境下如果用了多进程并行偶尔会遇到权限问题解决方式是在终端里手动执行chmod -R 755把目录权限放开。5.4 聚类之后怎么做业务落地如果说聚类分析是“找到人群”那后续的投放策略才是“把人群变现”。项目zip里附了一个marketing_suggestion.py脚本做的事情并不复杂就是根据每个簇的画像自动生成建议。具体逻辑分三步第一步计算每个簇的消费贡献占比、人数占比、人均消费金额第二步按人均消费金额和转化率两个维度给簇划分策略优先级优先级A代表重点投放B代表日常维护C代表控制预算第三步根据最近动作天数判断生命周期阶段比如簇2最近动作天数只有1.8天属于“成熟活跃期”策略是维持曝光频次簇3最近动作天数8.3天属于流失预警策略换成召回权益。这三步做完直接把结果输出成Excel表投放人员拿到表就能看到每个簇该用什么策略。实操小技巧直接改自己的业务数据如果你拿到的不是广告数据换个场景也能直接用这个zip里的流程只需要改两处feature_cols换成你的业务特征列以及后面打标签时根据自己的行业定义每个簇的含义。比如电商可以换成浏览深度、加购次数、下单金额、退货率内容平台可以换成阅读时长、点赞评论数、分享次数、跨品类阅读率。K-means不挑行业挑的是你的特征有没有选对以及最后一步解读有没有做透。我自己在实际操作中的一个习惯是每次聚类完先看一眼每个簇的样本量是不是极度不均衡。如果某个簇的样本量只有整体的1%但消费占比却特别高那说明它很有可能是细分高价值人群值得单独拉出来做深度分析反过来如果某个簇占了80%的样本但特征值全部趋近于平均值那这个簇大概率没有业务区分度可能需要增加特征维度重新聚类。这种基于业务直觉的校验是任何统计指标都替代不了的。最后再提醒一次拿到zip第一件事不是解压就开跑而是先确认运行环境。Python版本在3.8及以上安装pandas、numpy、scikit-learn、matplotlib这几个基础库然后跑一下result_profile.py能正常出图出表再开始换自己的数据。环境这关过了整个流程跑完往往只需要几分钟。本文还有配套的精品资源点击获取