课程 3:关联规则、分类与聚类算法

1. 关联规则挖掘

关联规则挖掘是一种用于发现大型数据集中隐藏的有趣关系的技术。发现的关系以“规则”的形式表达。一个常见的应用是市场篮子分析,用于发现顾客经常一起购买的商品。

Apriori 算法

Apriori 是一种用于学习关联规则的经典算法。它设计用于处理包含事务的数据库(例如,顾客购买的商品集合)。Apriori 使用“自下而上”的方法,频繁项集逐个项目扩展(这一步称为候选项集生成),然后根据数据测试候选项集组。

核心概念:

  • 支持度 (Support):表示项集在数据集中的出现频率。
    支持度(X) = (包含 X 的事务数量) / (总事务数量)
  • 置信度 (Confidence):衡量规则的可靠性。对于规则 X → Y,置信度是当 X 发生时 Y 发生的概率。
    置信度(X → Y) = 支持度(X ∪ Y) / 支持度(X)
  • 提升度 (Lift):衡量当 X 被购买时,Y 被购买的可能性比 Y 被随机购买的可能性高多少。
    提升度(X → Y) = 支持度(X ∪ Y) / (支持度(X) * 支持度(Y))
    提升度 > 1 表示正相关,< 1 表示负相关,= 1 表示无关联。

Python 示例 (使用 mlxtend)

您需要安装 mlxtendpip install mlxtend

import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules

# 示例交易数据
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
           ['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
           ['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
           ['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
           ['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]

# 将数据转换为所需格式
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df_trans = pd.DataFrame(te_ary, columns=te.columns_)
print("编码后的交易 DataFrame:\n", df_trans.head()) # "Encoded Transaction DataFrame:"

# 使用 Apriori 查找频繁项集
frequent_itemsets = apriori(df_trans, min_support=0.5, use_colnames=True) # min_support 已针对小型数据集调整
print("\n频繁项集 (min_support=0.5):\n", frequent_itemsets) # "Frequent Itemsets (min_support=0.5):"

# 生成关联规则
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.7)
print("\n关联规则 (min_confidence=0.7):\n", rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']]) # "Association Rules (min_confidence=0.7):"

2. 分类算法

分类是一种监督学习任务,其目标是基于过去的观察为新实例预测类别标签(或离散值)。算法从标记数据集(训练数据)中学习,然后为未标记数据(测试数据)分配标签。

决策树

决策树是一种类似流程图的结构,其中每个内部节点代表对属性的“测试”(例如,硬币掷出正面还是反面),每个分支代表测试的结果,每个叶节点代表类别标签(在计算所有属性后做出的决策)。从根到叶的路径代表分类规则。

优点:

  • 易于理解和解释。树可以可视化。
  • 需要的数据准备工作很少(例如,不需要特征缩放)。
  • 可以处理数值型和类别型数据。

缺点:

  • 可能创建过于复杂的树,泛化能力不佳(过拟合)。
  • 可能不稳定,因为数据中的微小变化可能导致生成完全不同的树。

Python 示例 (scikit-learn):

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn import metrics

# 加载示例数据集 (Iris)
iris = load_iris()
X = iris.data
y = iris.target

# 将数据分割为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)

# 创建决策树分类器对象
clf = DecisionTreeClassifier()

# 训练决策树分类器
clf = clf.fit(X_train,y_train)

# 预测测试数据集的响应
y_pred = clf.predict(X_test)

print("决策树准确率:", metrics.accuracy_score(y_test, y_pred)) # "Decision Tree Accuracy:"

# 可视化 (可选, 需要 graphviz 和 pydotplus)
# from sklearn.tree import export_graphviz
# from six import StringIO # Python 2/3 compatibility for StringIO
# from IPython.display import Image  
# import pydotplus
# dot_data = StringIO()
# export_graphviz(clf, out_file=dot_data,
#                 filled=True, rounded=True,
#                 special_characters=True, feature_names = iris.feature_names,class_names=iris.target_names)
# graph = pydotplus.graph_from_dot_data(dot_data.getvalue())  
# Image(graph.create_png()) # 这行代码会在 Jupyter Notebook 中显示树
print("要可视化决策树,通常会使用 graphviz。") # "To visualize the tree, you would typically use graphviz."

随机森林

随机森林是一种集成学习方法,它通过在训练时构建多个决策树,并输出作为众数类别(分类)或平均预测(回归)的各个树的类别。它纠正了决策树对其训练集过拟合的倾向。

它如何改进决策树:

  • 减少过拟合:通过平均多个树,减少了方差,从而减少了过拟合的趋势。
  • 更高的准确性:通常比单个决策树提供更高的准确性。
  • 鲁棒性:对特定的训练数据不那么敏感。

Python 示例 (scikit-learn):

from sklearn.ensemble import RandomForestClassifier
# 使用决策树示例中的 X_train, X_test, y_train, y_test

# 创建随机森林分类器对象
rf_clf = RandomForestClassifier(n_estimators=100, random_state=42) # n_estimators = 树的数量

# 训练随机森林分类器
rf_clf.fit(X_train, y_train)

# 预测测试数据集的响应
y_pred_rf = rf_clf.predict(X_test)

print("随机森林准确率:", metrics.accuracy_score(y_test, y_pred_rf)) # "Random Forest Accuracy:"

3. 聚类算法

聚类是一种无监督学习任务,涉及将一组数据点分成若干组(簇),使得同一组中的对象彼此更相似,而与其他组中的对象更不相似。目标是在没有先验标签知识的情况下发现数据中的固有分组。

K-均值聚类 (K-means Clustering)

K-均值是一种迭代算法,它试图将数据集划分为 K 个预定义的、不重叠的子组(簇),其中每个数据点仅属于一个组。

算法步骤:

  1. 初始化:随机选择或使用特定策略选择 K 个初始质心(簇中心)。
  2. 分配步骤:将每个数据点分配给最近的质心。
  3. 更新步骤:将质心重新计算为分配给该簇的所有数据点的均值。
  4. 重复步骤 2 和 3,直到质心不再发生显著变化或达到最大迭代次数。

选择 K:

簇的数量 K 是一个超参数。“肘部法则”(Elbow Method)是找到一个好的 K 的常用技术,即针对不同的 K 值绘制每个点到其分配中心的平方距离总和(惯性),并选择曲线的“肘部”。

Python 示例 (scikit-learn):

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs # 用于生成样本数据
import matplotlib.pyplot as plt # 用于可视化

# 生成用于聚类的样本数据
X_cluster, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.70, random_state=0)

# 创建 KMeans 对象
kmeans = KMeans(n_clusters=4, random_state=0, n_init='auto') # n_init='auto' 以抑制警告

# 拟合 KMeans 模型
kmeans.fit(X_cluster)

# 获取簇标签和质心
labels = kmeans.labels_
centroids = kmeans.cluster_centers_

print("K-均值聚类标签 (前 10 个):", labels[:10]) # "K-means cluster labels (first 10):"
print("K-均值质心:\n", centroids) # "K-means centroids:"

# 绘制簇 (可选, 用于可视化)
plt.figure(figsize=(8, 6))
plt.scatter(X_cluster[:, 0], X_cluster[:, 1], c=labels, cmap='viridis', marker='o', s=50, alpha=0.7)
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', marker='x', s=200) # 标记质心
plt.title('K-均值聚类') # 'K-means Clustering'
plt.xlabel('特征 1') # 'Feature 1'
plt.ylabel('特征 2') # 'Feature 2'
# plt.show() # 如果在本地运行,取消注释以显示绘图
print("绘图将显示4个不同的簇,其中心用红色标记。") # "Plot would show 4 distinct clusters with their centers marked in red."

层次聚类 (Hierarchical Clustering)

层次聚类构建一个簇的层次结构。主要有两种类型:

  • 凝聚型(自下而上):每个观测值从其自身的簇开始,随着层次结构的向上移动,成对的簇被合并。
  • 分裂型(自上而下):所有观测值从一个簇开始,随着层次结构的向下移动,递归地进行分裂。(凝聚型更常见)。

结果通常使用树状图(dendrogram)进行可视化,这是一种树状图表,记录了合并或分裂的顺序。

Python 示例 (scikit-learn 用于凝聚型聚类):

from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage # 用于树状图
# 使用 K-means 示例中的 X_cluster

# 创建凝聚型聚类对象
agg_clustering = AgglomerativeClustering(n_clusters=4) # 指定簇的数量或距离阈值

# 拟合模型
agg_labels = agg_clustering.fit_predict(X_cluster)

print("凝聚型聚类标签 (前 10 个):", agg_labels[:10]) # "Agglomerative Clustering labels (first 10):"

# 使用树状图进行可视化 (使用 scipy)
# Z = linkage(X_cluster, method='ward') # 'ward' 最小化每个簇内的方差
# plt.figure(figsize=(10, 7))
# dendrogram(Z)
# plt.title('层次聚类树状图') # 'Hierarchical Clustering Dendrogram'
# plt.xlabel('样本索引') # 'Sample index'
# plt.ylabel('距离') # 'Distance'
# plt.show() # 如果在本地运行,取消注释以显示绘图
print("树状图将直观地表示层次聚类结构。") # "A dendrogram plot would visually represent the hierarchical clustering structure."

本课程介绍了机器学习的三个重要领域:使用 Apriori 查找关联规则,使用决策树和随机森林对数据进行分类,以及使用 K-均值和层次聚类对数据进行分组。这些算法是许多数据科学任务的基础。