在编程领域,处理大型数据集是一个常见且具有挑战性的任务。本文将探讨如何利用scikit-learn的在线API来分块处理一个由20x20图像块组成的面孔数据集。将通过逐个加载图像,并从中随机提取50个图像块。当累积到500个这样的图像块(使用10张图像)后,将运行在线KMeans对象MiniBatchKMeans的partial_fit方法。
MiniBatchKMeans的verbose设置使能够看到在连续调用partial_fit方法时,一些聚类中心是如何被重新分配的。这是因为它们所代表的图像块数量变得太低,选择一个新的随机聚类中心更为合适。
from sklearn import datasets
faces = datasets.fetch_olivetti_faces()
首先,使用scikit-learn的datasets模块来加载Olivetti面孔数据集。这个数据集包含了多个不同人的面孔图像,将使用这些图像来训练模型。
import time
import numpy as np
from sklearn.cluster import MiniBatchKMeans
from sklearn.feature_extraction.image import extract_patches_2d
print("Learning the dictionary... ")
rng = np.random.RandomState(0)
kmeans = MiniBatchKMeans(n_clusters=81, random_state=rng, verbose=True, n_init=3)
patch_size = (20, 20)
buffer = []
t0 = time.time()
# 在线学习部分:循环遍历整个数据集6次
index = 0
for _ in range(6):
for img in faces.images:
data = extract_patches_2d(img, patch_size, max_patches=50, random_state=rng)
data = np.reshape(data, (len(data), -1))
buffer.append(data)
index += 1
if index % 10 == 0:
data = np.concatenate(buffer, axis=0)
data -= np.mean(data, axis=0)
data /= np.std(data, axis=0)
kmeans.partial_fit(data)
buffer = []
if index % 100 == 0:
print("Partial fit of %4i out of %i" % (index, 6*len(faces.images)))
dt = time.time() - t0
print("done in %.2f s." % dt)
在这段代码中,首先导入了必要的库,并设置了随机数生成器的种子,以确保结果的可重复性。然后,创建了一个MiniBatchKMeans对象,设置了聚类的数量、随机状态和verbose参数。定义了图像块的大小,并初始化了一个空的缓冲区来存储提取的图像块。
接下来,进入一个循环,遍历数据集中的每张图像,并从中提取50个随机图像块。这些图像块被添加到缓冲区中。每当缓冲区中累积了10张图像的数据时,就将这些数据合并,然后进行标准化处理,最后使用partial_fit方法来更新聚类中心。
在每次迭代中,还打印出当前的进度,以便跟踪学习过程。这个过程会重复6次,以确保模型有足够的数据来学习。
import matplotlib.pyplot as plt
plt.figure(figsize=(4.2, 4))
for i, patch in enumerate(kmeans.cluster_centers_):
plt.subplot(9, 9, i + 1)
plt.imshow(patch.reshape(patch_size), cmap=plt.cm.gray, interpolation="nearest")
plt.xticks(())
plt.yticks(())
plt.suptitle("Patches of faces\nTrain time %.1f s on %d patches" % (dt, 8*len(faces.images)), fontsize=16)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)
plt.show()
最后,使用matplotlib库来绘制学习到的图像块。为每个聚类中心创建一个子图,并显示对应的图像块。还设置了标题,显示了训练时间和处理的图像块数量。