第205集 无监督学习基础
1. 无监督学习概述
无监督学习(Unsupervised Learning)是机器学习的重要分支,它处理没有标签的数据,通过算法自动发现数据中的模式、结构和关系。
1.1 无监督学习的特点
- 没有标签:数据只有特征,没有对应的标签
- 自动发现结构:算法自主发现数据中的隐藏模式
- 探索性分析:帮助理解数据的内在结构
- 数据预处理:用于特征工程和数据降维
1.2 无监督学习的主要类型
- 聚类:将相似的数据点分组
- 降维:减少数据的维度,保留关键信息
- 关联规则学习:发现数据之间的关联关系
- 异常检测:识别数据中的异常值
2. 聚类算法
聚类(Clustering)是无监督学习中最常用的技术,它将相似的数据点分到同一组(簇),不同的数据点分到不同的组。
2.1 K-means聚类
K-means是最简单、最常用的聚类算法之一。
2.1.1 算法原理
- 随机选择K个初始质心
- 将每个数据点分配到最近的质心所在的簇
- 重新计算每个簇的质心
- 重复步骤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 算法原理
- 从任意未访问的数据点开始
- 找到该点的ε邻域内的所有点
- 如果邻域内点的数量超过min_samples,则形成一个簇
- 递归地为该簇中的所有点执行上述操作
- 如果邻域内点的数量少于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 算法原理
- 计算数据的协方差矩阵
- 对协方差矩阵进行特征值分解
- 选择最大的k个特征值对应的特征向量作为主成分
- 将原始数据投影到这些主成分上,得到降维后的数据
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 算法原理
- 计算高维空间中数据点之间的相似度
- 计算低维空间中数据点之间的相似度
- 通过优化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 算法原理
- 找出所有频繁项集
- 从频繁项集中生成关联规则
- 根据置信度和提升度筛选规则
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 分析步骤
- 数据预处理
- 使用K-means聚类算法对客户进行细分
- 分析每个簇的特征
- 制定针对性的营销策略
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)
- 异常检测:识别数据中的异常值
无监督学习在数据挖掘、客户细分、推荐系统、图像分析等领域有广泛的应用。选择合适的无监督学习算法需要考虑数据的特性、任务的要求和计算资源等因素。
在下一集中,我们将学习强化学习的基础概念和应用。