5 无监督学习:聚类与降维

2025年08月15日

无监督学习:聚类与降维

💡 学习重点:掌握无监督学习的核心算法,理解聚类和降维技术在数据挖掘中的应用。

 

 

无监督学习概述

与监督学习不同,无监督学习处理的是没有标签的数据,目标是发现数据中的隐藏模式和结构。

无监督学习就像是在没有答案的情况下,让机器自己发现数据中的规律和模式。

ℹ️ 无监督学习的主要任务
聚类:将相似的数据点分组
降维:减少数据的特征数量
异常检测:识别异常或离群点
关联规则:发现数据间的关联关系

聚类算法

1. K-Means聚类

K-Means是最经典的聚类算法,通过迭代优化将数据分为K个簇。

算法步骤
1. 随机初始化K个聚类中心
2. 将每个点分配到最近的聚类中心
3. 更新聚类中心为簇内点的均值
4. 重复步骤2-3直到收敛

# K-Means聚类示例
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np

# 生成聚类数据
X, y_true = make_blobs(n_samples=300, centers=4, 
                       cluster_std=0.60, random_state=0)

# K-Means聚类
kmeans = KMeans(n_clusters=4, random_state=42)
y_pred = kmeans.fit_predict(X)

# 可视化结果
plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap="viridis")
plt.title("真实聚类")

plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap="viridis")
plt.scatter(kmeans.cluster_centers_[:, 0], 
           kmeans.cluster_centers_[:, 1], 
           marker="x", s=200, linewidths=3, color="red")
plt.title("K-Means聚类结果")
plt.show()

print(f"聚类中心:
{kmeans.cluster_centers_}")

 

🔐K-Means特点

2. 层次聚类

层次聚类不需要预先指定聚类数量,通过构建聚类树来展示数据的层次结构。

# 层次聚类示例
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
from scipy.cluster.hierarchy import fcluster

# 层次聚类
hierarchical = AgglomerativeClustering(n_clusters=3, linkage="ward")
y_hierarchical = hierarchical.fit_predict(X)

# 绘制树状图
linkage_matrix = linkage(X, method="ward")
plt.figure(figsize=(10, 6))
dendrogram(linkage_matrix)
plt.title("层次聚类树状图")
plt.show()

3. DBSCAN聚类

DBSCAN可以发现任意形状的聚类,并自动识别噪声点。

DBSCAN优势
• 不需要预设聚类数量
• 可以发现任意形状的聚类
• 能够识别噪声点和离群值

# DBSCAN聚类
from sklearn.cluster import DBSCAN

# DBSCAN聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
y_dbscan = dbscan.fit_predict(X)

# 统计聚类结果
n_clusters = len(set(y_dbscan)) - (1 if -1 in y_dbscan else 0)
n_noise = list(y_dbscan).count(-1)

print(f"聚类数量: {n_clusters}")
print(f"噪声点数量: {n_noise}")

降维算法

1. 主成分分析(PCA)

PCA通过线性变换将数据投影到低维空间,保留最重要的信息。

PCA的核心思想是找到数据变化最大的方向(主成分),用较少的维度表示原始数据。

# PCA降维示例
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt

# 加载手写数字数据集
digits = load_digits()
X = digits.data  # 64维特征
y = digits.target

print(f"原始数据形状: {X.shape}")

# PCA降维到2维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print(f"降维后数据形状: {X_pca.shape}")
print(f"解释方差比: {pca.explained_variance_ratio_}")
print(f"累计解释方差: {pca.explained_variance_ratio_.sum():.3f}")

# 可视化降维结果
plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap="tab10")
plt.colorbar(scatter)
plt.title("PCA降维可视化(手写数字)")
plt.xlabel(f"第一主成分 (解释方差: {pca.explained_variance_ratio_[0]:.3f})")
plt.ylabel(f"第二主成分 (解释方差: {pca.explained_variance_ratio_[1]:.3f})")
plt.show()

2. t-SNE降维

t-SNE特别适合数据可视化,能够保持数据的局部结构。

# t-SNE降维
from sklearn.manifold import TSNE

# t-SNE降维(注意:t-SNE计算较慢)
tsne = TSNE(n_components=2, random_state=42, perplexity=30)
X_tsne = tsne.fit_transform(X[:1000])  # 使用部分数据

plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y[:1000], cmap="tab10")
plt.colorbar(scatter)
plt.title("t-SNE降维可视化")
plt.show()

🔐降维算法对比

聚类评估

内部评估指标

ℹ️ 轮廓系数(Silhouette Score):衡量聚类质量的重要指标

# 聚类评估
from sklearn.metrics import silhouette_score, adjusted_rand_score

# 轮廓系数
silhouette_avg = silhouette_score(X, y_pred)
print(f"轮廓系数: {silhouette_avg:.3f}")

# 如果有真实标签,可以计算调整兰德指数
ari = adjusted_rand_score(y_true, y_pred)
print(f"调整兰德指数: {ari:.3f}")

肘部法则选择K值

# 肘部法则选择最优K值
inertias = []
K_range = range(1, 11)

for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(X)
    inertias.append(kmeans.inertia_)

plt.figure(figsize=(10, 6))
plt.plot(K_range, inertias, "bo-")
plt.xlabel("聚类数量 K")
plt.ylabel("簇内平方和 (Inertia)")
plt.title("肘部法则选择最优K值")
plt.grid(True)
plt.show()

实际应用案例

客户细分分析

业务场景:电商平台根据用户行为进行客户细分

# 客户细分案例
import pandas as pd

# 模拟客户数据
np.random.seed(42)
n_customers = 1000

customer_data = pd.DataFrame({
    "年龄": np.random.normal(35, 10, n_customers),
    "年收入": np.random.normal(50000, 15000, n_customers),
    "消费金额": np.random.normal(2000, 800, n_customers),
    "购买频次": np.random.poisson(12, n_customers),
    "会员年限": np.random.exponential(2, n_customers)
})

# 数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(customer_data)

# K-Means聚类
kmeans = KMeans(n_clusters=4, random_state=42)
customer_segments = kmeans.fit_predict(X_scaled)

# 分析各个细分群体
customer_data["细分群体"] = customer_segments
segment_analysis = customer_data.groupby("细分群体").mean()
print("客户细分分析结果:")
print(segment_analysis)

图像压缩应用

# 使用K-Means进行图像压缩
from sklearn.cluster import KMeans
import numpy as np

def compress_image(image, n_colors):
    """使用K-Means压缩图像颜色"""
    # 重塑图像数据
    data = image.reshape((-1, 3))
    
    # K-Means聚类
    kmeans = KMeans(n_clusters=n_colors, random_state=42)
    kmeans.fit(data)
    
    # 用聚类中心替换原始颜色
    compressed_data = kmeans.cluster_centers_[kmeans.labels_]
    
    # 重塑回原始形状
    compressed_image = compressed_data.reshape(image.shape)
    
    return compressed_image.astype(np.uint8)

# 使用示例
# original_image = plt.imread("example.jpg")
# compressed = compress_image(original_image, n_colors=16)

⚠️ 实践建议
• 聚类前要进行数据标准化
• 选择合适的距离度量和聚类数量
• 结合业务知识解释聚类结果
• 降维时要平衡信息保留和计算效率

本章小结

无监督学习是数据挖掘的重要工具,通过聚类和降维技术可以发现数据中的隐藏模式,为业务决策提供有价值的洞察。


下一章我们将学习深度学习基础...