24.11.9

实验七:K 均值聚类算法实现与测试
一、实验目的
深入理解 K 均值聚类算法的算法原理,进而理解无监督学习的意义,能够使用 Python语言实现 K 均值聚类算法的训练与测试,并且使用五折交叉验证算法进行模型训练与评估。
二、实验内容
(1)从 scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注意同分布取样);
(2)使用训练集训练 K 均值聚类算法,类别数为 3;
(3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选择;
(4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验七的部分。
三、算法步骤、代码、及结果

  1. 算法伪代码
    加载 Iris 数据集,得到特征矩阵和标签向量。
    使用训练集和测试集比例划分数据集,确保类别分布一致。
    初始化 K-means 聚类模型,设置聚类类别数为 3。
    在训练集上训练该模型。
    输出聚类中心和训练集聚类标签
    输出 K-means 算法生成的聚类中心。
    输出训练集的聚类标签。
    使用五折交叉验证预测聚类标签,评估模型的稳定性。
    使用匈牙利算法对聚类标签进行重新映射,以最大化真实标签与聚类标签的一致性。
    输出交叉验证后的评估报告,展示每个类别的精度、召回率和 F1 分数。
    对测试集进行预测,得到聚类标签。
    使用相同的标签映射方法调整测试集的聚类标签。
    输出测试集的分类评估报告,评估聚类性能。
  2. 算法主要代码
    完整源代码\调用库方法(函数参数说明)
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.cluster import KMeans
    from sklearn.metrics import accuracy_score, classification_report
    from sklearn.model_selection import cross_val_predict
    from scipy.optimize import linear_sum_assignment
    import numpy as np

加载 Iris 数据集

iris = load_iris()
X = iris.data
y = iris.target

留出 1/3 数据作为测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3, random_state=42, stratify=y)

train_test_split主要参数:

sklearn.model_selection.train_test_split(*arrays, test_size=None, train_size=None, random_state=None, shuffle=True, stratify=None)

arrays:待划分的特征矩阵 X 和标签向量 y

test_size:测试集比例,默认为 None

取值范围:(0, 1) 表示比例;整数表示测试集样本数;若为 None,则自动计算

train_size:训练集比例,默认为 None。若 test_size 和 train_size 均为 None,则默认 test_size=0.25

random_state:随机种子,整型值使得结果可复现

shuffle:布尔值,是否在划分前打乱数据,默认为 True

stratify:按特定分布划分数据。通常为标签 y,保证训练集和测试集中类别分布一致

print(f"训练集样本数: {len(X_train)}, 测试集样本数: {len(X_test)}")

定义 K 均值模型

kmeans = KMeans(n_clusters=3, random_state=42)

KMeans主要参数:

KMeans(n_clusters=3, random_state=42)

n_clusters=3: 聚类的类别数。

random_state=42: 随机种子,保证结果可复现。

init='k-means++': 默认值,初始化聚类中心,减少收敛时间。

max_iter=300: 最大迭代次数,默认值 300。

n_init=10: 默认值,运行算法的次数,取最优结果。

在训练集上训练 K 均值模型

kmeans.fit(X_train)

输出聚类结果

print(f"聚类中心:\n{kmeans.cluster_centers_}")
print(f"训练集的聚类标签:\n{kmeans.labels_}")

使用五折交叉验证获取聚类标签

y_pred_cv = cross_val_predict(kmeans, X_train, y_train, cv=5)

cross_validate主要参数:

sklearn.model_selection.cross_validate(estimator, X, y=None, *, scoring=None, cv=None, n_jobs=None, verbose=0, fit_params=None, return_train_score=False, return_estimator=False, error_score=nan)

estimator:用于训练的模型,如 LogisticRegression()

X:特征矩阵

y:标签向量

scoring:评估指标,默认为 None,即使用模型默认评分标准

可选单个指标(如 'accuracy')或列表(如 ['accuracy', 'precision_macro'])

cv:交叉验证折数,默认值 5

n_jobs:并行计算的线程数,默认为 None

-1 表示使用所有可用CPU

return_train_score:是否返回训练集分数,默认为 False

通过真实标签对聚类结果重新编号

def map_clusters_to_labels(y_true, y_pred):
cost_matrix = np.zeros((len(np.unique(y_true)), len(np.unique(y_pred))))
for i in range(len(np.unique(y_true))):
for j in range(len(np.unique(y_pred))):
cost_matrix[i, j] = np.sum((y_true == i) & (y_pred == j))
row_ind, col_ind = linear_sum_assignment(-cost_matrix)
mapping = dict(zip(col_ind, row_ind))
return np.array([mapping[label] for label in y_pred])

linear_sum_assignment(来自 scipy.optimize)

功能: 用于解决匈牙利算法问题(最优化匹配问题),如将预测的聚类标签重新映射到真实标签

参数说明

cost_matrix: 成本矩阵,形状为 [n_classes, n_clusters]

每个元素表示从真实类别映射到某聚类类别的代价

本例中代价矩阵为负数(-cost_matrix),因为我们希望最大化匹配样本数量

返回值:

row_ind: 成本矩阵行的索引

col_ind: 成本矩阵列的索引

调整交叉验证预测结果

y_pred_cv_adjusted = map_clusters_to_labels(y_train, y_pred_cv)

输出评估指标

print("五折交叉验证结果:")
print(classification_report(y_train, y_pred_cv_adjusted, target_names=iris.target_names))

在测试集上预测

y_pred_test = kmeans.predict(X_test)

调整预测结果

y_pred_test_adjusted = map_clusters_to_labels(y_test, y_pred_test)

输出测试集性能报告

print("测试集性能报告:")
print(classification_report(y_test, y_pred_test_adjusted, target_names=iris.target_names))

classification_report主要参数:

sklearn.metrics.classification_report(y_true, y_pred, *, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False, zero_division='warn')

y_true:真实标签

y_pred:预测标签

target_names:类别标签的名称

digits:结果小数位数,默认为 2

output_dict:是否以字典形式返回,默认为 False

  1. 训练结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)

四、心得体会
通过本次实验,我深入理解了K均值聚类算法的原理,包括簇中心初始化、样本分配以及中心更新的迭代过程,同时体会到无监督学习在数据分析中的重要意义。在实践中,我使用Python实现了K均值聚类算法的训练与测试,并结合五折交叉验证对模型进行了训练与评估。这次实验让我认识到无监督学习的应用价值,以及如何通过合理的超参数设置(如K值的选择)提高聚类效果,进一步增强了我对数据结构和分布的理解能力。

posted @ 2024-11-09 17:13  起名字真难_qmz  阅读(16)  评论(0)    收藏  举报