云计算百科
云计算领域专业知识百科平台

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

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

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


写在前面

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

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

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

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


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

1. 跟监督学习的区别

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

2. 三大任务

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

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

下面逐个讲。


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

1. 什么是聚类

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

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

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

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

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

  • 你告诉机器"分K组"(K是你定的数字)
  • 机器随机放K个"中心点"
  • 每条数据找离自己最近的中心点,归到那一组
  • 每组重新算中心点(组内所有点的平均位置)
  • 重复步骤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万个用户的消费数据,想把用户自动分群,做精细化运营。

    import pandas as pd
    import numpy as np
    from sklearn.cluster import KMeans
    from sklearn.preprocessing import StandardScaler
    import matplotlib.pyplot as plt

    # ========== 第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)
    for k in K_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维画散点图 直观看到数据分布和聚类
    模型加速 降维后再训练模型 减少计算量,训练更快
    特征压缩 把相关特征合并 减少冗余,降低过拟合风险
    大模型中的Embedding 768维向量降到更低维 减少存储和检索压力(RAG中常用)

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

    from sklearn.decomposition import PCA
    from sklearn.datasets import load_iris
    import matplotlib.pyplot as plt

    # 加载鸢尾花数据集(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']
    for i, color in enumerate(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. 异常检测实战

    from sklearn.ensemble import IsolationForest
    import numpy as np

    # 模拟正常交易数据(金额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 Forest
    model = IsolationForest(contamination=0.05, random_state=42)
    model.fit(normal_data)

    # 预测异常
    predictions = model.predict(anomalies)
    for i, pred in enumerate(predictions):
    status = "异常 ⚠️" if pred == 1 else "正常 ✅"
    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群

    第二步:人工看看每群的特征,给每群起名字(高价值/低价值/潜力/流失风险/新用户)

    第三步:用这些带标签的数据训练监督学习模型

    第四步:新用户来了,模型自动判断属于哪一群

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


    六、一个常见的认知误区

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

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

  • 没有标准答案,效果难评估。 你把用户分成了5群,但"分得对不对"没有客观标准,只能靠业务人员判断"这个分群有没有用"
  • 参数更难调。 K-Means的K设多少、DBSCAN的密度阈值设多少,都需要反复试
  • 结果不稳定。 同样的数据,不同参数可能得到完全不同的结果
  • 需要更多业务理解。 机器分完群后,你得解释"这群人有什么特征",这需要对业务的理解
  • 所以无监督学习不是"偷懒"的方案,而是"探索"的方案。 它适合用来发现你不知道的规律,而不是替代监督学习做预测。


    七、本章涉及算法速查表

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

    本章小结

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

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

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 第6章 无监督学习:没有标准答案怎么办
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!