news 2026/7/27 7:03:33

第6章 无监督学习:没有标准答案怎么办

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第6章 无监督学习:没有标准答案怎么办

第6章 无监督学习:没有标准答案怎么办

一句话点题:监督学习是"做题对答案",无监督学习是"发一堆混在一起的扑克牌,没人告诉你怎么分,你自己整理"。没有标准答案,但机器照样能找出规律来。


写在前面

上一章我们学的监督学习有个前提:数据得有标签(标准答案)。

但现实中,大量数据是没有标签的。你有一堆用户行为日志,没人给每条记录标上"这是高价值用户"或"这是流失用户";你有几万条商品评论,没人标过"正面"或"负面";你有一堆传感器数据,没人告诉你哪条是"正常"哪条是"异常"。

标注数据费时费力——请人标1万条数据,可能要花几万块、花几周时间。

没有标签,机器还能学吗?能。这就是无监督学习干的事。


一、无监督学习到底在干什么

1. 跟监督学习的区别

监督学习无监督学习
有没有标签没有
目标学会预测(给新数据一个答案)发现结构(在数据里找规律)
比方做题对答案自己找规律分类
例子判断邮件是不是垃圾邮件把用户自动分成几群
能验证对错吗能(有标准答案)不能(没有标准答案,只能看"分得合不合理")

2. 三大任务

无监督学习主要干三件事:

任务干什么大白话典型应用
聚类把相似的数据分到一组自动分组用户分群、文档归类
降维把高维数据压缩到低维浓缩信息数据可视化、特征压缩
异常检测找出跟大多数不一样的数据找"异类"欺诈检测、故障预警

下面逐个讲。


二、聚类:让机器自动分组

1. 什么是聚类

聚类的目标很简单:把相似的东西放一起,不相似的分开。

你不需要告诉机器"分几类"或"怎么分",机器自己根据数据的特征来找天然的分群。

生活类比:你去一个陌生超市买水果,没人告诉你哪个是苹果哪个是梨。但你看一眼就能分出来——红的一堆、黄的一堆、长得不一样嘛。聚类就是让机器干这个事。

2. K-Means——最经典的聚类算法

K-Means(K均值)是最常用的聚类算法,原理非常直白:

  1. 你告诉机器"分K组"(K是你定的数字)
  2. 机器随机放K个"中心点"
  3. 每条数据找离自己最近的中心点,归到那一组
  4. 每组重新算中心点(组内所有点的平均位置)
  5. 重复步骤3和4,直到分组不再变化

用图来理解:

第1轮:随机放中心点 第2轮:重新分组 第3轮:稳定了 · · ☆① · · | ① · · | ① · ·· ··· · ··|·· · ·· | ·· ··· ···· → ···|···· → ··· | ···· ····· ☆② ·····|② ····· | ② · ·· · ··| · ·· | ☆③ ①②③ = 三个中心点 竖线 = 分界线 分组完成

大白话:你说"分3组",机器就把数据分成3堆,让每堆里的数据尽量相似,堆跟堆之间尽量不同。

3. K-Means的优缺点

优点缺点
简单、速度快你得自己定K(分几组)
大数据量也能扛只能找圆形的簇(形状怪的搞不定)
解释性好(中心点就是每组的"代表")对异常值敏感(一个离群点能把中心点拉偏)
使用广泛、工具成熟初始中心点随机放,每次结果可能不同

4. DBSCAN——不需要你定分几组的聚类

K-Means的痛点是你得提前告诉它"分几组",但你往往不知道该分几组。DBSCAN解决了这个问题。

DBSCAN的原理:密度大的地方就是一群,密度小的地方就是边界。它自动根据数据的密集程度来分群,不需要你指定组数。

生活类比:K-Means是你跟机器说"把这100个人分3组";DBSCAN是机器自己看"这30个人挤在一起算一组,那边50个人挤一起算一组,剩下20个散在各地的算异常"。

K-MeansDBSCAN
需要指定分几组吗需要不需要
能处理不规则形状吗不能
能识别异常点吗不能
速度中等
适合场景数据大致成圆形分布数据形状不规则、需要识别异常

5. 聚类实战:用户分群

一个常见的业务场景:你有1万个用户的消费数据,想把用户自动分群,做精细化运营。

importpandasaspdimportnumpyasnpfromsklearn.clusterimportKMeansfromsklearn.preprocessingimportStandardScalerimportmatplotlib.pyplotasplt# ========== 第1步:准备数据 ==========# 模拟用户消费数据np.random.seed(42)data={'月消费金额':np.concatenate([np.random.normal(500,100,300),# 低消费群体np.random.normal(3000,500,500),# 中等消费群体np.random.normal(8000,1000,200),# 高消费群体]),'月访问次数':np.concatenate([np.random.normal(5,2,300),# 低频用户np.random.normal(20,5,500),# 中频用户np.random.normal(40,8,200),# 高频用户])}df=pd.DataFrame(data)# ========== 第2步:数据标准化 ==========# 不同特征的量纲不同(消费金额几千、访问次数几十),必须标准化scaler=StandardScaler()X_scaled=scaler.fit_transform(df)# ========== 第3步:选K(用手肘法) ==========inertias=[]K_range=range(1,10)forkinK_range:kmeans=KMeans(n_clusters=k,random_state=42,n_init=10)kmeans.fit(X_scaled)inertias.append(kmeans.inertia_)# 手肘法:画图找"拐点",拐点对应的K就是最佳分组数plt.figure(figsize=(8,4))plt.plot(K_range,inertias,'bo-')plt.xlabel('K (分组数)')plt.ylabel('Inertia (组内方差)')plt.title('手肘法选K')plt.axvline(x=3,color='r',linestyle='--',label='最佳K=3')plt.legend()plt.tight_layout()plt.savefig('elbow.png',dpi=100)# ========== 第4步:训练模型 ==========kmeans=KMeans(n_clusters=3,random_state=42,n_init=10)df['群体']=kmeans.fit_predict(X_scaled)# ========== 第5步:分析结果 ==========print("各群体特征:")print(df.groupby('群体').agg({'月消费金额':['mean','count'],'月访问次数':'mean'}).round(0))# 输出结果示例:# 群体 月消费金额(mean) 月访问次数(mean) 人数# 0 502 5 300 ← 低频低消费# 1 3001 20 500 ← 中频中消费# 2 7998 40 200 ← 高频高消费

6. 手肘法——怎么确定分几组

K-Means最头疼的问题是"K设多少合适"。手肘法是最常用的解决方案:

原理:试不同的K值(1到10),算每个K对应的"组内方差"(每个点到自己中心点的距离之和)。K越大,方差越小(分组越细当然越紧凑)。但方差下降到某个点会突然变缓——这个拐点就像胳膊的"手肘",就是最佳K值。

Inertia | | · | · | · | · ← 拐点(手肘),K=3最佳 | · · · · · | └────────────────── K 1 2 3 4 5 6 7

大白话:分1组太粗、分10组太细,找个"刚好"的拐点。


三、降维:把高维数据压缩

1. 为什么需要降维

假设你有一个用户画像,有200个特征(年龄、性别、收入、消费频次、浏览时长、地域……)。这200个特征里:

  • 有些是冗余的("月收入"和"年收入"其实是一回事)
  • 有些是噪声("用户ID"对分析没有意义)
  • 有些维度太高没法可视化(你能画2维3维的图,但画不了200维的)

降维就是把200个特征压缩成10个或2个,同时尽量不丢失关键信息。

降维的好处大白话
减少计算量数据瘦身后跑得更快
去掉冗余把重复的信息合并
可视化降到2维3维就能画图看了
降噪去掉没用的特征,留下核心信息

2. PCA——最常用的降维方法

PCA(主成分分析)的原理用大白话说:找出数据中"信息量最大"的几个方向,把数据投影到这些方向上,用更少的维度表示原始数据。

生活类比:你拍一个3D的物体照片,从不同角度拍信息量不同——正面拍能看出形状,俯拍可能只能看到一个圆。PCA就是帮你找到"最能体现这个物体特征"的拍摄角度。

原始数据PCA降维后
维度200维2维
信息量100%~85%(损失15%)
可视化不行可以画散点图
计算速度

关键取舍:降维必然丢信息,问题是你愿意丢多少。通常降到能保留85%-95%信息量的维度就够了。

3. 降维的典型应用

应用场景怎么用价值
数据可视化200维降到2维画散点图直观看到数据分布和聚类
模型加速降维后再训练模型减少计算量,训练更快
特征压缩把相关特征合并减少冗余,降低过拟合风险
大模型中的Embedding768维向量降到更低维减少存储和检索压力(RAG中常用)

4. 降维实战:可视化高维数据

fromsklearn.decompositionimportPCAfromsklearn.datasetsimportload_irisimportmatplotlib.pyplotasplt# 加载鸢尾花数据集(4个特征:花萼长宽、花瓣长宽)iris=load_iris()X=iris.data# 4维y=iris.target# 3种花# PCA降到2维pca=PCA(n_components=2)X_2d=pca.fit_transform(X)print(f"原始维度:{X.shape[1]}维")print(f"降维后:{X_2d.shape[1]}维")print(f"保留信息量:{pca.explained_variance_ratio_.sum():.1%}")# 画图plt.figure(figsize=(8,5))colors=['red','green','blue']fori,colorinenumerate(colors):plt.scatter(X_2d[y==i,0],X_2d[y==i,1],c=color,label=iris.target_names[i])plt.xlabel('主成分1')plt.ylabel('主成分2')plt.title('PCA降维可视化')plt.legend()plt.tight_layout()plt.savefig('pca.png',dpi=100)

4维数据降到2维,保留了97.8%的信息量,还能画图看到三种花明显分成三堆——这就是降维的价值。


四、异常检测:找出"不对劲"的数据

1. 什么是异常检测

异常检测的目标:从大量数据中找出"跟大多数不一样"的少数数据。

这些"不一样"的数据往往是重要的:

  • 信用卡交易里的欺诈交易
  • 服务器日志里的异常请求
  • 工厂传感器数据里的设备故障前兆
  • 网络流量里的攻击行为

2. 为什么不用监督学习

你可能会想:用监督学习训练一个"正常vs异常"的分类器不就行了?

问题在于:

困难说明
异常样本太少欺诈交易可能只占0.01%,类别极不平衡
异常种类未知今天的欺诈手段和明天的不一样,你没法穷举
标注困难哪些是异常?很多时候事后才知道

所以异常检测通常用无监督方法:只学"正常长什么样",跟正常不一样的就是异常。

3. 常用方法

方法原理大白话适合场景
Isolation Forest随机切分数据,异常点容易被孤立异常点"人缘差",几下就单独切出来了通用异常检测
One-Class SVM学一个边界把正常数据包住画个圈,圈外的是异常边界清晰的场景
DBSCAN密度低的地方的点算异常不属于任何一群的就是异类兼顾聚类和异常检测
自编码器用神经网络学重建正常数据,重建误差大的就是异常只见过正常的,遇到异常就"不认识"了复杂高维数据

4. 异常检测实战

fromsklearn.ensembleimportIsolationForestimportnumpyasnp# 模拟正常交易数据(金额0-1000,频率1-10次/天)np.random.seed(42)normal_data=np.column_stack([np.random.normal(200,100,1000),# 交易金额np.random.normal(5,2,1000),# 日交易次数])# 模拟异常交易anomalies=np.array([[5000,50],# 大额高频[8000,1],# 超大额[50,30],# 小额超高频[3000,25],# 大额高频])# 训练Isolation Forestmodel=IsolationForest(contamination=0.05,random_state=42)model.fit(normal_data)# 预测异常predictions=model.predict(anomalies)fori,predinenumerate(predictions):status="异常 ⚠️"ifpred==-1else"正常 ✅"print(f"交易(金额={anomalies[i][0]:.0f}, 次数={anomalies[i][1]:.0f}) →{status}")# 预测正常数据(应该都判为正常)normal_pred=model.predict(normal_data[:10])print(f"\n正常数据检测:{sum(normal_pred==1)}/10 判为正常")

5. 异常检测的实践要点

要点说明
contamination参数预估异常比例,设高了误报多,设低了漏报多
特征选择选跟异常相关的特征,无关特征会干扰检测
阈值调优异常检测输出的是"异常分数",阈值设多少需要根据业务调
人工反馈检测出的异常需要人工确认,反馈结果用来持续优化

五、监督学习 vs 无监督学习:什么时候用哪个

判断维度用监督学习用无监督学习
有标签吗没有
目标明确吗明确(要预测什么)不明确(想探索数据)
能验证对错吗不能
效果评估有明确指标(准确率等)靠业务判断(分得合不合理)
典型场景垃圾邮件检测、房价预测用户分群、异常检测、数据探索

实践中的组合使用

很多时候不是二选一,而是先无监督、后监督

第一步:无监督聚类,把用户分成5群 ↓ 第二步:人工看看每群的特征,给每群起名字(高价值/低价值/潜力/流失风险/新用户) ↓ 第三步:用这些带标签的数据训练监督学习模型 ↓ 第四步:新用户来了,模型自动判断属于哪一群

这就是"半监督学习"的思路——用无监督方法生成标签,再用监督方法做预测。两全其美。


六、一个常见的认知误区

误区:“无监督学习不需要标签,所以更简单”

事实恰恰相反。无监督学习往往比监督学习更难用好,原因:

  1. 没有标准答案,效果难评估。你把用户分成了5群,但"分得对不对"没有客观标准,只能靠业务人员判断"这个分群有没有用"
  2. 参数更难调。K-Means的K设多少、DBSCAN的密度阈值设多少,都需要反复试
  3. 结果不稳定。同样的数据,不同参数可能得到完全不同的结果
  4. 需要更多业务理解。机器分完群后,你得解释"这群人有什么特征",这需要对业务的理解

所以无监督学习不是"偷懒"的方案,而是"探索"的方案。它适合用来发现你不知道的规律,而不是替代监督学习做预测。


七、本章涉及算法速查表

算法类型原理(一句话)适合场景
K-Means聚类找K个中心点,按距离分组用户分群、文档归类
DBSCAN聚类密度大的地方就是一群不规则形状、识别异常
层次聚类聚类自底向上或自顶向下逐步合并/拆分需要看分群层次关系的场景
PCA降维找信息量最大的方向投影数据可视化、特征压缩
t-SNE降维保持局部结构的非线性降维高维数据可视化(比PCA更精细)
Isolation Forest异常检测异常点容易被随机切分孤立通用异常检测
One-Class SVM异常检测学一个边界包住正常数据边界清晰的异常检测

本章小结

要点内容
无监督学习没有标签,让机器自己发现数据中的结构和规律
三大任务聚类(自动分组)、降维(压缩信息)、异常检测(找异类)
K-Means最经典聚类算法,需要指定K,手肘法选K
DBSCAN不需要指定分组数,能识别异常点,适合不规则形状
PCA最常用降维方法,用更少维度保留更多信息
异常检测只学"正常长什么样",跟正常不一样的就是异常
实践建议先无监督探索→人工标注→后监督预测;无监督不是偷懒而是探索
核心认知没有标准答案不代表没有规律,机器照样能找出隐藏的结构

下一章预告:第7章「特征工程:数据质量决定AI上限」—— "垃圾进垃圾出"是机器学习的铁律。同样的算法,好的特征工程能让效果提升30%以上。这章教你怎么从原始数据中"榨"出最有价值的特征。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/27 7:02:09

图像掩码解码

图像掩码解码 一、技术背景 YOLOv8/YOLO11实例分割模型采用了一种高效的掩码表示方式:原型掩码(Prototype Masks) 掩码系数(Mask Coefficients)。这种设计将掩码表示分解为两部分:一组与类别无关的原型掩码…

作者头像 李华
网站建设 2026/7/27 6:59:42

GTO优化CNN-LSTM在时间序列预测中的应用

1. 项目概述:当大猩猩部队遇上时间序列预测在时间序列预测领域,我们一直在寻找更强大的算法组合。最近我在Matlab中尝试了一种新颖的混合模型——将人工大猩猩部队优化器(GTO)与CNN-LSTM网络结合,用于多变量时间序列预…

作者头像 李华
网站建设 2026/7/27 6:59:35

AI双检系统:提升论文查重与AI内容识别的精准度

1. 项目概述:AI双检系统的核心价值去年帮导师审研究生论文时发现一个现象:超过60%的送审论文存在两个致命问题——传统查重率勉强合格但AI生成痕迹明显,或者AIGC检测过关却与其他文献高度雷同。这种"按下葫芦浮起瓢"的困境&#xf…

作者头像 李华
网站建设 2026/7/27 6:55:32

Docker容器化运维实战:镜像优化与集群管理

1. 容器化运维的核心挑战与解决思路第一次在生产环境部署Docker容器时,我遇到了镜像体积臃肿、启动缓慢的问题。一个简单的Python应用镜像竟然达到1.2GB,每次部署都要耗费近10分钟传输镜像。这促使我开始系统研究容器化运维的三个核心命题:如…

作者头像 李华
网站建设 2026/7/27 6:53:03

AI工具如何提升学术论文阅读效率

1. AI如何重塑学术论文阅读方式作为一名每天需要消化数十篇前沿论文的计算机视觉研究员,我深刻体会到传统论文阅读方式的局限性。直到三年前开始系统性地使用AI工具辅助阅读,我的研究效率才真正实现了质的飞跃。现在,我将分享如何构建一套完整…

作者头像 李华