简介
在本实验中,我们将使用谱双聚类(Spectral Biclustering)算法对数据进行聚类,该算法会同时考虑矩阵的行(样本)和列(特征)。其目的不仅是识别样本之间的模式,还包括样本子集内部的模式,从而能够检测数据中的局部结构。这使得谱双聚类特别适用于特征顺序或排列固定的数据集,如图像、时间序列或基因组数据。我们将使用 scikit-learn 库生成棋盘数据集,并使用谱双聚类算法对其进行双聚类。
虚拟机使用提示
虚拟机启动完成后,点击左上角切换到“笔记本”标签页,以访问 Jupyter Notebook 进行练习。
有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。
如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。
生成样本数据
我们使用 make_checkerboard 函数生成样本数据。shape=(300, 300) 内的每个像素都以其颜色表示来自均匀分布的值。噪声是从正态分布中添加的,其中为 noise 选择的值是标准差。
from sklearn.datasets import make_checkerboard
from matplotlib import pyplot as plt
n_clusters = (4, 3)
data, rows, columns = make_checkerboard(
shape=(300, 300), n_clusters=n_clusters, noise=10, shuffle=False, random_state=42
)
plt.matshow(data, cmap=plt.cm.Blues)
plt.title("Original dataset")
_ = plt.show()
打乱数据
我们打乱数据,目的是之后使用“谱双聚类(SpectralBiclustering)”对其进行重构。
import numpy as np
## 创建打乱后的行索引和列索引列表
rng = np.random.RandomState(0)
row_idx_shuffled = rng.permutation(data.shape[0])
col_idx_shuffled = rng.permutation(data.shape[1])
## 重新定义打乱后的数据并绘图。
data = data[row_idx_shuffled][:, col_idx_shuffled]
plt.matshow(data, cmap=plt.cm.Blues)
plt.title("Shuffled dataset")
_ = plt.show()
拟合“谱双聚类(SpectralBiclustering)”
我们拟合模型,并将得到的聚类结果与真实情况进行比较。请注意,在创建模型时,我们指定了与用于创建数据集相同数量的聚类(n_clusters = (4, 3)),这将有助于获得良好的结果。
from sklearn.cluster import SpectralBiclustering
from sklearn.metrics import consensus_score
model = SpectralBiclustering(n_clusters=n_clusters, method="log", random_state=0)
model.fit(data)
## 计算两组双聚类的相似度
score = consensus_score(
model.biclusters_, (rows[:, row_idx_shuffled], columns[:, col_idx_shuffled])
)
print(f"一致性得分:{score:.1f}")
绘制结果
现在,我们根据“谱双聚类(SpectralBiclustering)”模型分配的行和列标签,按升序重新排列数据,然后再次绘图。row_labels_ 的范围是从 0 到 3,而 column_labels_ 的范围是从 0 到 2,这表示每行共有 4 个聚类,每列共有 3 个聚类。
## 先对行进行重新排序,然后对列进行重新排序。
reordered_rows = data[np.argsort(model.row_labels_)]
reordered_data = reordered_rows[:, np.argsort(model.column_labels_)]
plt.matshow(reordered_data, cmap=plt.cm.Blues)
plt.title("After biclustering; rearranged to show biclusters")
_ = plt.show()
作为最后一步,我们想要展示模型分配的行标签和列标签之间的关系。因此,我们使用 numpy.outer 创建一个网格,它接受排序后的 row_labels_ 和 column_labels_,并给每个标签加 1,以确保标签从 1 开始而不是 0,以便更好地可视化。
plt.matshow(
np.outer(np.sort(model.row_labels_) + 1, np.sort(model.column_labels_) + 1),
cmap=plt.cm.Blues,
)
plt.title("Checkerboard structure of rearranged data")
plt.show()
总结
在这个实验中,我们学习了如何使用谱双聚类算法,通过同时考虑矩阵的行(样本)和列(特征)来对数据进行聚类。我们生成了一个棋盘格数据集,并使用谱双聚类算法对其进行双聚类。我们还对结果进行了可视化,以展示模型分配的行标签和列标签之间的关系。