scikit-learn Olivetti Faces 数据集完全指南:fetch_olivetti_faces 的加载、预处理与实战应用
2026/9/19 20:55:04 网站建设 项目流程

scikit-learn Olivetti Faces 数据集完全指南:fetch_olivetti_faces 的加载、预处理与实战应用

【免费下载链接】scikit-learnscikit-learn: machine learning in Python项目地址: https://gitcode.com/gh_mirrors/sc/scikit-learn

本指南深入剖析 scikit-learn 内置的 Olivetti Faces 人脸数据集:从它在 1992–1994 年间由 AT&T Laboratories Cambridge 采集的历史渊源,到fetch_olivetti_faces函数的下载、缓存、归一化全流程,再到其在 PCA/NMF 分解与人脸补全等经典任务中的用法,帮助你全面掌握这份机器学习入门的"黄金标准"人脸数据。

数据集背景:AT&T 实验室的人脸采集工程

Olivetti Faces 数据集(也称 ORL 人脸库)的图片于1992 年 4 月至 1994 年 4 月之间在 AT&T Laboratories Cambridge(剑桥 AT&T 实验室)拍摄,由sklearn.datasets.fetch_olivetti_faces函数负责下载并缓存数据归档。仓库内对应的描述文档为 sklearn/datasets/descr/olivetti_faces.rst,加载器源码位于 sklearn/datasets/_olivetti_faces.py。

按照原始网站的描述,该数据集的采集规范如下:

  • 共有40 位不同的受试者(subject),每人拍摄10 张不同图像;
  • 对部分受试者,图像在不同时间拍摄,并有意变化了光照、面部表情(睁眼/闭眼、微笑/不微笑)与面部细节(戴眼镜/不戴眼镜);
  • 所有图像均以深色均匀背景拍摄,受试者保持直立、正面的姿态(允许少量侧移容差)。

这是一组刻意引入真实世界变异性(光照、表情、配饰)的人脸样本,因此非常适合验证算法对类内变化的鲁棒性。

数据特征一览

原文档给出了该数据集的官方特征表:

属性数值
Classes(类别数)40
Samples total(样本总数)400
Dimensionality(维度)4096
Features(特征类型)real,取值介于 0 与 1 之间

关于原始格式与预处理,原文档明确说明:

  • 原始图像被量化到256 级灰度,以无符号 8 位整数uint8)存储;
  • 加载器会把整数转换为[0, 1] 区间上的浮点值,这更便于众多算法直接处理;
  • 数据集中的target是从0 到 39的整数,标识每张图中的人物身份;
  • 由于每个类别仅有 10 个样本,这个体量相对较小的数据集从无监督或半监督视角来看更有研究价值;
  • 原始数据集图像尺寸为92×112,而本仓库提供的版本为64×64图像。

加载方式与返回结构

基本调用

from sklearn.datasets import fetch_olivetti_faces olivetti_faces = fetch_olivetti_faces() # 扁平化特征矩阵:(400, 4096) print(olivetti_faces.data.shape) # 原始 64x64 图像张量:(400, 64, 64) print(olivetti_faces.images.shape) # 标签(人物 ID,0-39):(400,) print(olivetti_faces.target.shape)

首次调用时函数会打印下载信息:

downloading Olivetti faces from https://ndownloader.figshare.com/files/5976027 to ~/scikit_learn_data

默认情况下,函数返回一个字典风格的Bunch对象(见 sklearn/utils/_bunch.py),包含以下属性:

属性形状说明
data(400, 4096)每行是一条**展平(ravelled)**的 64×64 人脸图像
images(400, 64, 64)保持二维空间结构的人脸图像,对应 40 位受试者
target(400,)每张图对应的标签,取值 0–39,即 Subject ID
DESCRstr数据集完整描述文本

若设置return_X_y=True(自 0.22 版本起支持),则直接返回(data, target)二元组,适合直接接入fit(X, y)接口。

fetch_olivetti_faces 完整参数详解

从源码 sklearn/datasets/_olivetti_faces.py 可以看到函数的完整签名,全部参数均以关键字形式传递(*之后):

def fetch_olivetti_faces( *, data_home=None, shuffle=False, random_state=0, download_if_missing=True, return_X_y=False, n_retries=3, delay=1.0, ):
参数默认值说明
data_homeNone指定数据集下载与缓存目录;默认存放在~/scikit_learn_data子目录中(由get_data_home解析,见 sklearn/datasets/_base.py)
shuffleFalseTrue时打乱数据集顺序,避免同一人的图像连续排列
random_state0控制打乱的随机数生成;传入整数可获得跨多次调用可复现的输出
download_if_missingTrueFalse且本地无数据时抛出OSError,而不是尝试联网下载
return_X_yFalseTrue时返回(data, target)元组(0.22 版本新增)
n_retries3遇到 HTTP 错误时的重试次数(1.5 版本新增)
delay1.0每次重试之间的等待秒数(1.5 版本新增)

值得注意的是,n_retriesdelay两个参数在 1.5 版本才引入,用于增强下载过程的网络健壮性。所有参数都经过@validate_params装饰器做类型校验(见 sklearn/utils/_param_validation.py),例如n_retries必须是>= 1的整数、delay必须是> 0的实数。

数据缓存机制

源码展示了一个精妙的缓存管线(sklearn/datasets/_olivetti_faces.py):

  1. 数据主文件元数据FACES是一个RemoteFileMetadata对象,记录了文件名olivettifaces.mat、下载地址与SHA-256 校验和b612fb967f2dc77c9c62d3e1266e0c73d5fca46a4b8906c18e454d41af987794,用于校验下载完整性;
  2. 首次调用时下载 MATLAB 格式的olivettifaces.mat,用scipy.io.loadmat解析后立即删除原始.mat文件,并将人脸矩阵以joblib.dump(..., compress=6)压缩序列化为olivetti.pkz缓存;
  3. 后续调用检测到缓存文件存在时直接joblib.load,不再访问网络。

源码级预处理管线:从 uint8 到 [0,1] 浮点

加载完成后,数据会经过统一的预处理(sklearn/datasets/_olivetti_faces.py):

# 转为 float32(原始 uint8 只有 1 字节精度,float32 已足够) faces = np.float32(faces) # 全局最小-最大归一化到 [0, 1] faces = faces - faces.min() faces /= faces.max() # 恢复 64x64 空间结构并转置修正轴向 faces = faces.reshape((400, 64, 64)).transpose(0, 2, 1) # 每类 10 张图,类别连续排列:target = i // 10 target = np.array([i // 10 for i in range(400)])

这段代码揭示了三个关键技术点:

  • 数据精度:由于原始数据只有 1 字节(8 bit)灰度精度,float32足够承载全部信息,避免了不必要的内存开销;
  • 归一化:通过最小-最大缩放将像素值映射到[0, 1],这正是原文档特征表中"Features: real, between 0 and 1"的来源;
  • 标签构造target = i // 10意味着在未打乱的情况下,每连续 10 张图属于同一位受试者,shuffle=True则会用check_random_state(random_state).permutation打乱样本与标签的对应顺序。

数据获取的工程细节与测试验证

测试覆盖

仓库为这一加载器提供了专门的单元测试 sklearn/datasets/tests/test_olivetti_faces.py,验证内容包括:

  • 返回对象为Bunch,且包含dataimagestargetDESCR四个键;
  • 形状分别为(400, 4096)(400, 64, 64)(400,)
  • target的独立取值恰好为np.arange(40),即覆盖全部 40 个类别;
  • DESCR.. _olivetti_faces_dataset:开头,说明它直接装载了本文所解析的 RST 描述文件;
  • return_X_y=True行为符合数据集通用约定。

网络测试开关

由于该数据集需要联网下载,测试基建在 sklearn/conftest.py 中提供了fetch_olivetti_faces_fxtfixture:默认设置download_if_missing=False,仅当环境变量SKLEARN_SKIP_NETWORK_TESTS=0时才真正联网获取数据,否则跳过网络相关测试——这是 CI 环境(如 build_tools/github/test_script.sh)中保证测试可离线运行的标准做法。

实战案例一:人脸分解(Eigenfaces / NMF / ICA)

由于每类样本极少(10 张),Olivetti Faces 最经典的用途是无监督降维与分解。官方示例 examples/decomposition/plot_faces_decomposition.py 在同一份数据上对比了多种矩阵分解方法:

from numpy.random import RandomState from sklearn import cluster, decomposition from sklearn.datasets import fetch_olivetti_faces rng = RandomState(0) faces, _ = fetch_olivetti_faces(return_X_y=True, shuffle=True, random_state=rng) n_samples, n_features = faces.shape # 全局中心化(按特征均值) + 局部中心化(按样本均值) faces_centered = faces - faces.mean(axis=0) faces_centered -= faces_centered.mean(axis=1).reshape(n_samples, -1) # 本征脸:PCA + 随机化 SVD pca = decomposition.PCA(n_components=6, svd_solver="randomized", whiten=True) pca.fit(faces_centered) # 非负矩阵分解(要求数据非负,直接作用于原始数据) nmf = decomposition.NMF(n_components=6, tol=5e-3) nmf.fit(faces) # 独立成分分析 ica = decomposition.FastICA(n_components=6, max_iter=400, whiten="arbitrary-variance", tol=15e-5) ica.fit(faces_centered)

示例中还依次演示了MiniBatchSparsePCAMiniBatchDictionaryLearningMiniBatchKMeans聚类中心与FactorAnalysis的应用,每种方法抽取 6 个 4096 维分量,再以 64×64 图像形式可视化,直观对比"本征脸"与"字典原子"的差异。注意 PCA/ICA/字典学习前通常需要中心化,而 NMF 要求非负输入,因此直接使用归一化后的原始数据。

实战案例二:多输出回归的人脸补全

另一个经典应用是用上半张脸预测下半张脸,展示多输出回归器。官方示例 examples/miscellaneous/plot_multioutput_face_completion.py 的核心流程:

from sklearn.datasets import fetch_olivetti_faces from sklearn.ensemble import ExtraTreesRegressor from sklearn.linear_model import LinearRegression, RidgeCV from sklearn.neighbors import KNeighborsRegressor data, targets = fetch_olivetti_faces(return_X_y=True) # 按人物身份划分:前 30 人训练,后 10 人测试(测试集人物完全独立) train = data[targets < 30] test = data[targets >= 30] n_pixels = data.shape[1] # 输入:上半张脸;输出:下半张脸(均为 2048 维多输出目标) X_train = train[:, : (n_pixels + 1) // 2] y_train = train[:, n_pixels // 2 :] X_test = test[:, : (n_pixels + 1) // 2] y_test = test[:, n_pixels // 2 :] for name, estimator in { "Extra trees": ExtraTreesRegressor(n_estimators=10, max_features=32, random_state=0), "K-nn": KNeighborsRegressor(), "Linear regression": LinearRegression(), "Ridge": RidgeCV(), }.items(): estimator.fit(X_train, y_train)

该示例还有一个值得借鉴的建模原则:按人物 ID 划分训练/测试集targets < 30targets >= 30),确保测试时面对的是训练中从未出现过的人脸,从而真实评估模型的泛化能力。类似的按人划分思路也出现在 examples/cluster/plot_dict_face_patches.py 中。

使用注意事项

  • 存储位置:默认数据缓存在~/scikit_learn_data下(olivetti.pkz文件),可通过data_home参数指定其他目录;
  • 网络依赖:首次加载需要联网下载约数 MB 的 MATLAB 数据文件;离线环境请预先缓存或设置download_if_missing=False(此时本地无数据会抛出OSError);
  • 引用致谢:按原文档要求,使用这些图像时请注明出处并致谢 AT&T Laboratories CambridgeDESCR属性中同样包含这一说明);
  • 数据尺寸:加载后务必以images(400, 64, 64)形态查看原始空间结构,以data(400, 4096)形态用于算法拟合;
  • 适用场景:由于每类仅 10 个样本、总体仅 400 张,它更适合人脸分解、特征学习、字典学习、半监督/无监督研究等任务,而非直接作为大规模监督分类基准。

小结

Olivetti Faces 是 scikit-learn 中最具代表性的人脸数据集之一:40 位受试者、每人 10 张、64×64 灰度、像素值归一化到 [0,1]。通过fetch_olivetti_faces及其完备的参数体系(shufflerandom_statereturn_X_yn_retries等),你可以一键获得缓存完备、格式统一、可直接进入机器学习管线的数据。结合 sklearn/datasets/_olivetti_faces.py 的源码与 examples/decomposition/plot_faces_decomposition.py、examples/miscellaneous/plot_multioutput_face_completion.py 等示例,无论是入门人脸分解、验证降维算法,还是研究多输出回归与半监督学习,它都是一份可靠、轻量且富有历史意义的实验数据。

【免费下载链接】scikit-learnscikit-learn: machine learning in Python项目地址: https://gitcode.com/gh_mirrors/sc/scikit-learn

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询