大数跨境

彻底讲透!无监督学习 !

彻底讲透!无监督学习 ! 机器学习和人工智能AI
2026-09-14
8

哈喽,大家好~

如果训练数据没有标签,机器学习模型还能学到东西吗?

当然可以!~

只不过这一次,模型不再对着标准答案学习,而是自己观察数据之间的相似性,尝试发现隐藏的结构。

今儿我们就来聊聊无监督学习:它是什么、常见模型如何工作~

什么是无监督学习?

监督学习的数据通常长这样:

身高
年龄
是否购买
175
25
160
32

其中“是否购买”就是标签。

而无监督学习只有前面的特征,没有最后的答案。比如我们拿到一批用户的消费金额、购买频率、访问时长,却不知道他们分别属于哪类用户。

这时候,模型会根据样本之间的距离、密度或分布,自动把相似的数据归到一起。

你可以这样理解:监督学习像“拿着答案做题”,无监督学习像“自己整理一堆没有标签的资料”。

常见的无监督学习任务包括:

  • 聚类:把相似样本分组,例如 K-Means、DBSCAN。
  • 降维:保留主要信息,压缩特征,例如 PCA。
  • 异常检测:找出和大多数样本明显不同的数据。

K-Means 的核心原理

K-Means 是最经典的聚类算法之一。

它需要我们提前指定聚类数量  ,然后不断重复下面几步:

  1. 随机选择   个中心点。
  2. 计算每个样本与各中心点的距离,把样本分配给最近的中心。
  3. 重新计算每个簇的平均位置,作为新的中心点。
  4. 重复执行,直到中心点变化很小。

它的目标是让同一簇中的样本尽量靠近。对应的损失函数是:

这里,  表示第   个簇,  是这个簇的中心,  是某个样本。

一句话概括:K-Means 会不断调整分组,让每组数据尽量“抱团”。

比如有三类用户,消费金额分别集中在 100、500、2000 元附近,即使没有用户标签,K-Means 也有机会把这三群人分出来。

不过,K-Means 对特征尺度比较敏感。年龄和收入放在一起时,收入的数值范围可能远大于年龄,所以实际使用前通常要进行标准化。

用户分群案例

下面构造一份二维数据,把用户分成三类。第一张图展示聚类结果和决策区域,第二张图展示每个样本的轮廓系数。

轮廓系数越接近 1,说明样本越接近自己的簇、并且远离其他簇;如果接近 0,说明它处在两个簇的边界附近。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score

X, _ = make_blobs(
    n_samples=2600, centers=[[-3-2], [03], [4-1]],
    cluster_std=[1.21.01.4], random_state=42
)
X = StandardScaler().fit_transform(X)

model = KMeans(n_clusters=3, n_init=20, random_state=42)
labels = model.fit_predict(X)
score = silhouette_score(X, labels)
centers = model.cluster_centers_

fig, ax = plt.subplots(12, figsize=(135))

# 聚类区域
xx, yy = np.meshgrid(
    np.linspace(X[:, 0].min()-1, X[:, 0].max()+1300),
    np.linspace(X[:, 1].min()-1, X[:, 1].max()+1300)
)
grid = np.c_[xx.ravel(), yy.ravel()]
Z = model.predict(grid).reshape(xx.shape)

ax[0].contourf(xx, yy, Z, alpha=.22,
               levels=np.arange(4)-.5,
               colors=["#ff4d6d""#00c2ff""#ffd166"])
ax[0].scatter(X[:, 0], X[:, 1], c=labels, cmap="turbo",
              s=25, edgecolor="white", linewidth=.3)
ax[0].scatter(centers[:, 0], centers[:, 1], c="black",
              marker="X", s=180, label="cluster center")
ax[0].set_title("K-Means Clusters")
ax[0].legend()

# 轮廓系数
sil = silhouette_samples(X, labels)
y = 10
for k, color in zip(range(3), ["#ff4d6d""#00c2ff""#ffd166"]):
    values = np.sort(sil[labels == k])
    ax[1].fill_betweenx(np.arange(y, y+len(values)), 0, values,
                         color=color, alpha=.85)
    y += len(values) + 10
ax[1].axvline(score, color="black", ls="--",
              label=f"mean={score:.2f}")
ax[1].set_title("Silhouette Analysis")
ax[1].set_xlabel("silhouette coefficient")
ax[1].legend()

plt.tight_layout()
plt.show()

左图中背景表示模型认为各个区域属于哪个簇,黑色叉号是每个簇的中心。你可以观察样本是否形成了明显的三团,以及不同颜色之间有没有大量重叠。

右图是轮廓系数分析。每一段对应一个聚类,横向越长代表这个样本分得越自然。如果某一簇大量样本接近 0,说明当前的   可能不合适。

注意点

第一,  不是随便指定的。可以尝试不同的  ,结合轮廓系数、肘部法则和业务理解共同判断。

第二,聚类结果不一定代表真实类别。模型找到的是数据中的相似结构,最终还需要结合业务解释这些簇到底意味着什么。

第三,异常值会影响中心位置。如果数据中存在极端样本,可以考虑 DBSCAN、层次聚类,或者先进行异常值处理。

第四,特征工程同样重要。用户分群时,单纯使用原始金额不一定有效,加入“月均消费”“购买频率”“最近一次购买间隔”等特征,通常更容易得到有价值的分组。

最后

无监督学习不依赖人工标签,而是从数据本身寻找相似性、结构和异常点。K-Means 通过不断更新聚类中心,让同一组样本尽量靠近;轮廓系数则可以帮助我们判断聚类是否合理。

接下来大家可以尝试把 K-Means 换成 DBSCAN,观察它如何识别噪声;也可以增加特征,再用 PCA 将高维数据压缩到二维进行可视化。

总之就是说,无监督学习的重点不只是“分成几组”,更是理解这些组背后代表的真实含义。

【声明】内容源于网络
0
0
机器学习和人工智能AI
让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
内容 390
粉丝 0
机器学习和人工智能AI 让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
总阅读5.8k
粉丝0
内容390