8.1 什么是无监督学习?
在机器学习的世界里,我们通常把算法分成两大类:
- 监督学习(Supervised Learning):有"老师"告诉模型正确答案。例如,给定一堆带标签的猫狗图片,我们训练一个模型识别新图片是猫还是狗。
- 无监督学习(Unsupervised Learning):没有"老师"提供答案,算法自己去发现数据的隐藏模式。例如,一群顾客的购物数据,我们不知道他们属于哪种消费类型,但算法可以自动把他们分组。
8.1.1 生活中的无监督学习案例
想象一下,你是一个商场经理,想搞一次促销活动,但你对顾客的消费习惯一无所知:
- 有些人每个月消费很多,可能是高端用户。
- 有些人买东西很少,可能是偶尔逛逛的顾客。
- 还有一些人可能专门来买折扣商品。
问题:如何给不同类型的顾客制定不同的营销策略?
- 你没有"顾客分类标签",只能靠算法自己去"看"数据的分布情况,把相似的顾客分到一组里。
- 这个过程就叫 聚类(Clustering) ,是无监督学习的核心任务之一。
8.1.2 机器学习中的无监督学习应用
无监督学习在现实中无处不在,比如:
- 新闻自动分类:不同主题的新闻(体育、财经、娱乐)自动分组,即使我们没有事先定义类别。
- 客户分群(Customer Segmentation):公司根据用户的消费行为,将客户分成不同群体,方便定制化营销。
- 异常检测(Anomaly Detection):银行使用无监督学习检测信用卡欺诈,比如发现"这个账户的交易模式突然异常"。
- 基因数据分析:生物研究中可以通过无监督学习找出基因之间的关联。
- 图像分割:将图像划分为不同区域,比如在医学影像中分割出肿瘤区域。
8.2 什么是 K-Means 聚类?
无监督学习中的聚类(Clustering) ,就是把相似的数据自动分成不同的**"组",这些组称为簇(Cluster)**。
K-Means 聚类是最常见的聚类算法之一。它的目标是:
- 将数据点自动分成 K 组(K 代表簇的数量)。
- 让同一组中的数据尽可能相似,而不同组的数据尽可能不同。
8.3 为什么要进行数据标准化?
K-Means 计算的是数据点之间的距离 ,如果不同特征的数据范围相差太大,可能导致某个特征的影响力过大,影响聚类效果。
8.3.1 代码示例
python
import pandas as pd
from sklearn.preprocessing import StandardScaler
# **步骤 1: 读取 CSV 文件**
data = pd.read_csv("Mall_Customers.csv")
# **步骤 2: 选择用于聚类的特征 (年收入 和 消费得分)**
X = data.iloc[:, [3, 4]].values # 选择 "Annual Income (k$)" 和 "Spending Score (1-100)"
# **步骤 3: 进行数据标准化**
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X) # 这里是 X_scaled 变量的定义
8.4 如何选择最佳 K 值?------肘部法则(Elbow Method)
8.4.1 为什么要找最佳 K?
在 K-Means 里,我们需要决定 K(分群数) ,但如何知道 K=3 还是 K=5 呢?
如果 K 太小,数据分得不够细;如果 K 太大,数据过度分割,失去意义。
8.4.2 肘部法则(Elbow Method)
肘部法则的核心思想
- 计算不同 K 值时,每个数据点到其簇中心的误差总和(WCSS,Within-Cluster Sum of Squares)。
- 随着 K 增大,误差(WCSS)会逐渐下降,因为数据点划分得更细,每个点更接近自己的中心点。
- 找到"肘部"拐点:WCSS 的下降速度从陡峭变得平缓的位置,就是最佳的 K 值。
8.4.3 直观类比
假设你在排队买奶茶:
- 如果只有 1 个收银员,所有人都排一个队,等待时间很长(类似 K=1)。
- 如果有 10 个收银员,每个人都几乎不用等(类似 K 很大)。
- 如果有 3-4 个收银员,队伍不会太长,也不会浪费资源(最佳 K 值)。
这就是肘部法则的思想:找到最经济、最有效的 K 值,而不是无限增加 K。
8.4.4 代码示例
python
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
wcss = [] # 存放误差总和
for i in range(1, 11): # 试探 K=1 到 K=10
kmeans = KMeans(n_clusters=i, random_state=42)
kmeans.fit(X_scaled)
wcss.append(kmeans.inertia_) # inertia_ 就是 WCSS 误差
# 解决中文显示问题
plt.rcParams["font.sans-serif"] = ["SimHei"] # Windows 和 Mac 可能需要不同字体
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 画出肘部法则图
plt.plot(range(1, 11), wcss, marker='o', linestyle='-')
plt.xlabel('K 值')
plt.ylabel('WCSS(误差总和)')
plt.title('肘部法则找最佳 K 值')
plt.show()
8.4.5 结果分析
运行后,我们可以在图上找到"最佳 K 值(肘部拐点)" 。
如果拐点在 K=5 ,那么 5 是最合适的分群数。
8.5 代码实战:用 K-Means 进行顾客分群
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# 读取 CSV 文件
data = pd.read_csv("Mall_Customers.csv")
# 只选择 年收入 和 消费得分 作为特征
X = data.iloc[:, [3, 4]].values
# 进行标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 运行 K-Means,根据上面的结论设置 K = 5
kmeans = KMeans(n_clusters=5, random_state=42)
clusters = kmeans.fit_predict(X_scaled)
# 画出聚类结果
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=clusters, cmap='rainbow')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='black', marker='X')
plt.xlabel('年收入(标准化后)')
plt.ylabel('消费得分(标准化后)')
plt.title('K-Means 聚类结果')
plt.show()
8.6 结果分析
- 不同颜色的点 代表不同的群组。
- 黑色 X 号 是每个群组的中心点。
- 这样,我们就完成了 K-Means 聚类,可以分析不同的顾客群体特征,比如:
- 高收入、高消费
- 低收入、低消费
- 中等收入、中等消费

8.7 总结
✅ 通过 K-Means 进行顾客分群 ,可以帮助商家更好地理解客户行为。
✅ 标准化数据 确保 K-Means 不会受到特征数值范围的影响。
✅ 肘部法则 帮助我们找到最佳的 K 值,使得分群更加合理。
🎯 下一步 :你可以尝试在电商平台、金融市场等真实场景应用 K-Means 聚类! 🚀