第205集 无监督学习基础

1. 无监督学习概述

无监督学习(Unsupervised Learning)是机器学习的重要分支,它处理没有标签的数据,通过算法自动发现数据中的模式、结构和关系。

1.1 无监督学习的特点

  • 没有标签:数据只有特征,没有对应的标签
  • 自动发现结构:算法自主发现数据中的隐藏模式
  • 探索性分析:帮助理解数据的内在结构
  • 数据预处理:用于特征工程和数据降维

1.2 无监督学习的主要类型

  • 聚类:将相似的数据点分组
  • 降维:减少数据的维度,保留关键信息
  • 关联规则学习:发现数据之间的关联关系
  • 异常检测:识别数据中的异常值

2. 聚类算法

聚类(Clustering)是无监督学习中最常用的技术,它将相似的数据点分到同一组(簇),不同的数据点分到不同的组。

2.1 K-means聚类

K-means是最简单、最常用的聚类算法之一。

2.1.1 算法原理

  1. 随机选择K个初始质心
  2. 将每个数据点分配到最近的质心所在的簇
  3. 重新计算每个簇的质心
  4. 重复步骤2和3,直到质心不再变化或达到最大迭代次数

2.1.2 优缺点

  • 优点:简单、快速、可伸缩性好
  • 缺点:需要预先指定K值、对初始质心敏感、对异常值敏感

2.1.3 代码示例

from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import numpy as np

# 加载数据
data = load_iris()
X = data.data

# 创建K-means模型
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(X)

# 获取聚类结果
labels = kmeans.labels_
centers = kmeans.cluster_centers_

print("聚类标签:", labels)
print("质心位置:", centers)

2.2 DBSCAN聚类

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法。

2.2.1 算法原理

  1. 从任意未访问的数据点开始
  2. 找到该点的ε邻域内的所有点
  3. 如果邻域内点的数量超过min_samples,则形成一个簇
  4. 递归地为该簇中的所有点执行上述操作
  5. 如果邻域内点的数量少于min_samples,则标记为噪声点

2.2.2 优缺点

  • 优点:不需要预先指定簇的数量、可以发现任意形状的簇、能够识别噪声点
  • 缺点:对参数ε和min_samples敏感、计算复杂度较高

2.2.3 代码示例

from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 创建DBSCAN模型
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan.fit(X_scaled)

# 获取聚类结果
labels = dbscan.labels_

print("聚类标签:", labels)
print("噪声点数量:", np.sum(labels == -1))

2.3 层次聚类

层次聚类(Hierarchical Clustering)通过构建嵌套的簇结构来进行聚类。

2.3.1 算法类型

  • 凝聚式:从每个数据点开始,逐步合并相似的簇
  • 分裂式:从一个包含所有数据点的簇开始,逐步分裂为更小的簇

2.3.2 优缺点

  • 优点:生成可视化的树状图(dendrogram)、不需要预先指定簇的数量
  • 缺点:计算复杂度高、对噪声和异常值敏感

2.3.3 代码示例

from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage

# 生成树状图
Z = linkage(X, 'ward')

plt.figure(figsize=(10, 7))
dendrogram(Z)
plt.title('层次聚类树状图')
plt.xlabel('样本索引')
plt.ylabel('距离')
plt.show()

# 创建凝聚式层次聚类模型
agg_cluster = AgglomerativeClustering(n_clusters=3)
agg_cluster.fit(X)

# 获取聚类结果
labels = agg_cluster.labels_

print("聚类标签:", labels)

3. 降维算法

降维(Dimensionality Reduction)是指将高维数据映射到低维空间,同时尽可能保留原始数据的关键信息。

3.1 主成分分析(PCA)

主成分分析(Principal Component Analysis)是最常用的降维技术之一。

3.1.1 算法原理

  1. 计算数据的协方差矩阵
  2. 对协方差矩阵进行特征值分解
  3. 选择最大的k个特征值对应的特征向量作为主成分
  4. 将原始数据投影到这些主成分上,得到降维后的数据

3.1.2 优缺点

  • 优点:降低数据维度、减少冗余、提高计算效率
  • 缺点:主成分的解释性较差、可能丢失一些信息

3.1.3 代码示例

from sklearn.decomposition import PCA

# 创建PCA模型
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print("原始数据形状:", X.shape)
print("降维后数据形状:", X_pca.shape)
print("解释方差比:", pca.explained_variance_ratio_)
print("累计解释方差比:", np.sum(pca.explained_variance_ratio_))

3.2 t-SNE降维

t分布随机邻域嵌入(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维技术,特别适合可视化。

3.2.1 算法原理

  1. 计算高维空间中数据点之间的相似度
  2. 计算低维空间中数据点之间的相似度
  3. 通过优化KL散度来最小化高维空间和低维空间之间的相似度差异

3.2.2 优缺点

  • 优点:可视化效果好、能够保留数据的局部结构
  • 缺点:计算复杂度高、不适合大规模数据、参数敏感

3.2.3 代码示例

from sklearn.manifold import TSNE

# 创建t-SNE模型
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X)

print("降维后数据形状:", X_tsne.shape)

# 可视化
plt.figure(figsize=(10, 7))
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=data.target)
plt.title('t-SNE降维可视化')
plt.colorbar()
plt.show()

4. 关联规则学习

关联规则学习(Association Rule Learning)用于发现数据项之间的关联关系。

4.1 Apriori算法

Apriori是最经典的关联规则学习算法。

4.1.1 基本概念

  • **支持度(Support)**:项集在数据集中出现的频率
  • **置信度(Confidence)**:规则A→B成立的概率
  • **提升度(Lift)**:规则A→B的强度

4.1.2 算法原理

  1. 找出所有频繁项集
  2. 从频繁项集中生成关联规则
  3. 根据置信度和提升度筛选规则

4.1.3 代码示例

from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules

# 示例交易数据
dataset = [
    ['牛奶', '面包', '鸡蛋'],
    ['牛奶', '面包', '饼干', '鸡蛋'],
    ['面包', '饼干'],
    ['牛奶', '面包', '鸡蛋', '火腿'],
    ['牛奶', '火腿']
]

# 转换为one-hot编码
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)

# 找出频繁项集
frequent_itemsets = apriori(df, min_support=0.4, use_colnames=True)

# 生成关联规则
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.7)

print("频繁项集:")
print(frequent_itemsets)

print("\n关联规则:")
print(rules)

5. 异常检测

异常检测(Anomaly Detection)用于识别数据中的异常值或离群点。

5.1 基于统计的异常检测

5.1.1 Z-分数方法

通过计算数据点的Z-分数来判断是否为异常值。

from scipy import stats

# 计算Z-分数
z_scores = stats.zscore(X)

# 识别异常值(Z-分数绝对值大于3)
anomalies = (np.abs(z_scores) > 3).any(axis=1)

print("异常值数量:", np.sum(anomalies))
print("异常值索引:", np.where(anomalies)[0])

5.2 基于聚类的异常检测

5.2.1 DBSCAN异常检测

使用DBSCAN算法的噪声点检测功能进行异常检测。

from sklearn.cluster import DBSCAN

# 创建DBSCAN模型
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan.fit(X)

# 获取异常值(标签为-1的样本)
anomalies = (dbscan.labels_ == -1)

print("异常值数量:", np.sum(anomalies))
print("异常值索引:", np.where(anomalies)[0])

6. 无监督学习的应用场景

6.1 聚类的应用

  • 客户细分:根据客户行为将客户分组
  • 图像分割:将图像分割为不同的区域
  • 文本分类:将文本自动分类到不同的主题
  • 生物信息学:对基因表达数据进行聚类分析

6.2 降维的应用

  • 数据可视化:将高维数据可视化
  • 特征选择:选择最相关的特征
  • 噪声去除:减少数据中的噪声
  • 计算效率提升:减少计算时间和内存消耗

6.3 关联规则的应用

  • 市场篮分析:分析顾客购买行为
  • 推荐系统:基于用户购买历史推荐商品
  • 网络分析:发现网络中的关联节点
  • 医学诊断:分析疾病与症状之间的关联

7. 无监督学习的最佳实践

7.1 数据预处理

  • 标准化:确保所有特征在相同的尺度上
  • 缺失值处理:删除或填充缺失值
  • 异常值处理:识别并处理异常值

7.2 模型选择

  • 根据任务选择:聚类、降维或关联规则
  • 根据数据特性选择:数据规模、维度、分布
  • 尝试多种算法:比较不同算法的效果

7.3 模型评估

  • 内部评估指标:轮廓系数、Calinski-Harabasz指数、Davies-Bouldin指数
  • 外部评估指标:如果有部分标签,可使用调整兰德指数(ARI)、调整互信息(AMI)
  • 可视化评估:通过可视化结果评估聚类质量

7.4 超参数调优

  • 网格搜索:尝试不同的超参数组合
  • 随机搜索:随机采样超参数组合
  • 贝叶斯优化:基于贝叶斯定理的超参数优化

8. 案例分析:客户细分

8.1 问题描述

某电商平台想要对客户进行细分,以便更好地了解客户需求,制定针对性的营销策略。

8.2 数据准备

使用客户的购买历史数据,包括:

  • 购买频率
  • 平均订单金额
  • 总消费金额
  • 最近一次购买时间

8.3 分析步骤

  1. 数据预处理
  2. 使用K-means聚类算法对客户进行细分
  3. 分析每个簇的特征
  4. 制定针对性的营销策略

8.4 代码实现

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

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

# 购买频率(0-100)
frequency = np.random.randint(1, 100, n_customers)

# 平均订单金额(0-1000)
avg_order_value = np.random.randint(10, 1000, n_customers)

# 总消费金额(0-50000)
total_spent = np.random.randint(100, 50000, n_customers)

# 最近一次购买时间(天数,0-365)
recency = np.random.randint(1, 365, n_customers)

# 创建DataFrame
df = pd.DataFrame({
    'frequency': frequency,
    'avg_order_value': avg_order_value,
    'total_spent': total_spent,
    'recency': recency
})

# 数据标准化
scaler = StandardScaler()
scaled_data = scaler.fit_transform(df)

# 使用肘部法则选择K值
inertias = []
for k in range(1, 11):
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(scaled_data)
    inertias.append(kmeans.inertia_)

# 绘制肘部图
plt.figure(figsize=(10, 7))
plt.plot(range(1, 11), inertias, marker='o')
plt.title('肘部法则')
plt.xlabel('K值')
plt.ylabel('惯性')
plt.grid(True)
plt.show()

# 使用K=4进行聚类
kmeans = KMeans(n_clusters=4, random_state=42)
clusters = kmeans.fit_predict(scaled_data)

# 将聚类结果添加到DataFrame
df['cluster'] = clusters

# 分析每个簇的特征
cluster_analysis = df.groupby('cluster').mean()
print(cluster_analysis)

# 可视化聚类结果
plt.figure(figsize=(10, 7))
plt.scatter(df['frequency'], df['total_spent'], c=df['cluster'], cmap='viridis')
plt.title('客户细分结果')
plt.xlabel('购买频率')
plt.ylabel('总消费金额')
plt.colorbar()
plt.show()

9. 总结

无监督学习是机器学习中非常重要的分支,它通过分析没有标签的数据来发现隐藏的模式和结构。主要技术包括:

  • 聚类:将相似的数据点分组(K-means, DBSCAN, 层次聚类)
  • 降维:减少数据的维度(PCA, t-SNE)
  • 关联规则学习:发现数据之间的关联关系(Apriori)
  • 异常检测:识别数据中的异常值

无监督学习在数据挖掘、客户细分、推荐系统、图像分析等领域有广泛的应用。选择合适的无监督学习算法需要考虑数据的特性、任务的要求和计算资源等因素。

在下一集中,我们将学习强化学习的基础概念和应用。

« 上一篇 监督学习基础