实验七:K均值聚类算法实现与测试

一、实验目的

深入理解K均值聚类算法的算法原理,进而理解无监督学习的意义,能够使用Python语言实现K均值聚类算法的训练与测试,并且使用五折交叉验证算法进行模型训练与评估。

二、实验内容

(1)从scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注意同分布取样);

(2)使用训练集训练K均值聚类算法,类别数为3;

(3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选择;

(4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验七的部分。

三、算法步骤、代码、及结果

  1. 算法伪代码
  2. 加载数据集
  3. 划分数据集
  4. 为 KMeans 聚类预测结果对齐标签
  5. 训练 KMeans 模型
  6. 五折交叉验证
  7. 在测试集上评估模型
  8. 算法主要代码

完整源代码\调用库方法(函数参数说明)

完整代码:

import numpy as np

from sklearn.model_selection import train_test_split, cross_val_score, KFold

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, adjusted_rand_score

from sklearn.datasets import load_iris

from sklearn.cluster import KMeans

from sklearn.preprocessing import LabelEncoder

 

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.33, random_state=42, stratify=y)

 

# 为了评估 KMeans 无监督学习模型,使用真实标签的重新排列

def align_labels(y_true, y_pred):

    label_encoder = LabelEncoder()

    y_true = label_encoder.fit_transform(y_true)

    y_pred_aligned = np.zeros_like(y_pred)

    for i in np.unique(y_pred):

        mask = y_pred == i

        y_pred_aligned[mask] = np.argmax(np.bincount(y_true[mask]))

    return y_pred_aligned

 

kmeans = KMeans(n_clusters=32)

kmeans.fit(X_train)

y_train_pred = align_labels(y_train, kmeans.predict(X_train))

 

kf = KFold(n_splits=5)

 

accuracy_scores = []

precision_scores = []

recall_scores = []

f1_scores = []

 

for train_index, val_index in kf.split(X_train):

    X_fold_train, X_fold_val = X_train[train_index], X_train[val_index]

    y_fold_train, y_fold_val = y_train[train_index], y_train[val_index]

 

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

    kmeans_fold.fit(X_fold_train)

    y_val_pred = align_labels(y_fold_val, kmeans_fold.predict(X_fold_val))

 

    accuracy_scores.append(accuracy_score(y_fold_val, y_val_pred))

    precision_scores.append(precision_score(y_fold_val, y_val_pred, average='weighted'))

    recall_scores.append(recall_score(y_fold_val, y_val_pred, average='weighted'))

    f1_scores.append(f1_score(y_fold_val, y_val_pred, average='weighted'))

 

print("五折交叉验证结果:")

print(f"准确率: {np.mean(accuracy_scores):.4f}")

print(f"精度: {np.mean(precision_scores):.4f}")

print(f"召回率: {np.mean(recall_scores):.4f}")

print(f"F1 值: {np.mean(f1_scores):.4f}")

 

y_test_pred = align_labels(y_test, kmeans.predict(X_test))

 

test_accuracy = accuracy_score(y_test, y_test_pred)

test_precision = precision_score(y_test, y_test_pred, average='weighted')

test_recall = recall_score(y_test, y_test_pred, average='weighted')

test_f1 = f1_score(y_test, y_test_pred, average='weighted')

 

print("\n测试集结果:")

print(f"准确率: {test_accuracy:.4f}")

print(f"精度: {test_precision:.4f}")

print(f"召回率: {test_recall:.4f}")

print(f"F1 值: {test_f1:.4f}")

 

参数说明:

1)train_test_split(X, y, test_size=0.33, random_state=42, stratify=y)

X:特征数据,二维数组(n_samples, n_features)。

y:目标标签,1D 数组(n_samples)。

test_size:测试集的比例。默认为 None,即根据 train_size 自动计算。此处设置为 0.33,表示测试集占 1/3,训练集占 2/3。

random_state:设置随机数种子,确保每次分割数据时一致。常用数值如 42。

stratify:保证数据集划分后每个类的比例相同。stratify=y 确保在划分数据时,训练集和测试集的类别比例一致。

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

n_clusters:聚类的类别数,表示要生成的簇的数目。此处设置为 3,表示数据要分为 3 类(与 iris 数据集中的类别数一致)。

random_state:用于初始化中心点的随机种子,确保每次训练得到的结果一致。此处设置为 42,使得每次模型训练时能够产生相同的结果。

  1. 3) KFold(n_splits=5, shuffle=True, random_state=42)

n_splits:数据分成的折数。此处设置为 5,表示将数据划分为 5 折进行交叉验证。

shuffle:是否打乱数据。True 表示打乱数据,False 表示不打乱。此处设置为 True,确保每次划分数据时不会因为顺序问题导致偏差。

random_state:设置随机种子,确保每次划分数据时能够得到一致的结果。

4)cross_val_score(model, X, y, cv=kf, scoring='accuracy')

model:要评估的模型,此处为 KMeans。

X:特征数据,二维数组(n_samples, n_features)。

y:目标标签,1D 数组(n_samples)。

cv:交叉验证策略。此处使用 KFold(n_splits=5),表示 5 折交叉验证。

scoring:评估指标。可以是:

'accuracy':准确率

'precision_weighted':精度,按类别加权平均

'recall_weighted':召回率,按类别加权平均

'f1_weighted':F1 值,按类别加权平均

  1. 5) accuracy_score(y_true, y_pred)、precision_score(y_true, y_pred, average='weighted')、recall_score(y_true, y_pred, average='weighted')、f1_score(y_true, y_pred, average='weighted')

y_true:真实标签,1D 数组(n_samples)。

y_pred:预测标签,1D 数组(n_samples)。

average:仅在多类分类时使用,表示如何计算加权平均:

'weighted':按每个类别的样本数量加权,适用于类不平衡的情况。

'micro':对所有类别计算全局的精度、召回率等,适用于类平衡的数据。

'macro':对每个类别计算精度、召回率等,再取平均值。

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

四、实验结果分析

  1. 测试结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)
  2. 对比分析

(1)五折交叉验证结果:

1.准确率:0.9100:模型在训练集上的平均准确率为 91.00%,说明模型在训练集上的聚类效果较好,能够较为准确地将样本归类。

2.精度:0.9047:精度较高,表示模型预测为正类的样本中,绝大部分是正确的,聚类结果较为精准。

3.召回率:0.9100:召回率为 91.00%,表示模型能够较好地识别出正类样本,聚类的覆盖范围较广。

4.F1 值:0.8955:F1 值综合考虑了精度和召回率,显示了较好的平衡,值接近 1,表明模型在训练集上的聚类性能较好。

(2)测试集结果:

1.准确率:0.9600:测试集上的准确率非常高,为 96.00%。这表明模型在测试集上表现良好,能够准确聚类样本。

2.精度:0.9642:精度非常高,表示模型在测试集上聚类结果的准确性较强。

3.召回率:0.9600:召回率为 96.00%,表示模型能够识别出大部分正类样本,聚类结果较好。

4.F1 值:0.9599:F1 值接近 1,显示了精度和召回率的较好平衡,表明模型在测试集上有着优异的聚类性能。

(3)分析:

1.五折交叉验证结果:

在交叉验证过程中,模型表现出较高的准确率、精度和召回率,但相对测试集来说,F1 值略低,说明交叉验证过程中可能出现了少量的误聚类或误匹配。

2.测试集结果:

测试集上的结果非常优秀,准确率、精度、召回率和 F1 值均达到了非常高的水平,表现出模型在测试集上的较强泛化能力。

测试集上的表现比交叉验证稍微好一些,说明模型在训练集和测试集上的表现非常一致,且没有明显的过拟合。

3.KMeans 聚类与评价:

由于 KMeans 是无监督学习算法,且评估时使用了对齐标签的方式,因此能较好地反映出模型的聚类质量。通过这种方式,我们可以在无监督的环境下使用准确率、精度、召回率和 F1 值等传统分类指标进行评估。

(4)总结:

模型表现:K均值聚类算法在五折交叉验证和测试集上的表现都相当优秀,准确率、精度、召回率和 F1 值均表现出较高的水平。

交叉验证与测试集:交叉验证结果略低于测试集,可能是由于交叉验证时的划分导致模型在不同折间的泛化能力稍有差异。

无监督学习的优势:通过无监督学习的聚类方式,K均值能够在没有标签信息的情况下,准确地将数据分为预定的类别,且评估指标表现出色。

 

posted on 2024-12-12 19:55  leapss  阅读(32)  评论(0)    收藏  举报