前言
很快就密集地学习机器学习15天了,这章是作业,使用 scikit-learn 的人脸数据集 (fetch_lfw_people) 来进行分类问题的解决和超参数调优,也是对自己学习的验证,学得很开心~
数据集介绍与概览
人脸数据集 (fetch_lfw_people) 里面大概有 1万多张照片,以不同人来进行分类是有5700多类。
在下面的程序码中,主要是加载 fetch_lfw_people 数据集,并通过对数据集进行提取,来减少数据集的量(设置仅保留具有至少60个不同图片的人的图片),这样达成要求的就只有8个人,1348张照片。
from sklearn.datasets import fetch_lfw_people
import matplotlib.pyplot as plt
%matplotlib inline
# 设置 参数 min_faces_per_person=60 来对数据集提取,仅保留具有至少60个不同图片的人的图片
# 默认 参数 resize=0.5 用于调整每张脸部图片尺寸的比率
# 默认 参数 slice_=(slice(70, 195, None), slice(78, 172, None))
# 提供自定义2D切片(高度,宽度)以提取jpeg文件的“interest”部分,并避免使用背景的统计相关性
faces = fetch_lfw_people(min_faces_per_person=60)
# 显示 符合至少40个不同图片的人的姓名(标签)
# 有8个人符合条件
# 是 'Donald Rumsfeld' 'George W Bush' 'Gerhard Schroeder' 'Gloria Macapagal Arroyo'
print("满足条件的人有:", str(len(faces.target_names)), " 个")
print("分别是:", faces.target_names)
# 显示 选择后数据集的形状,为 (804, 62, 47)
print("数据集的形状:", faces.images.shape)
# 查看数据集 前4张人脸 和 姓名(标签)
fig, ax = plt.subplots(1,4)
fig.subplots_adjust(left=0.00625, right=1.2)
for i, axi in enumerate(ax.flat):
axi.imshow(faces.images[i], cmap='bone')
axi.set(xticks=[], yticks=[], xlabel=faces.target_names[faces.target[i]])
满足条件的人有: 8 个
分别是: ['Ariel Sharon' 'Colin Powell' 'Donald Rumsfeld' 'George W Bush'
'Gerhard Schroeder' 'Hugo Chavez' 'Junichiro Koizumi' 'Tony Blair']
数据集的形状 (1348, 62, 47)
初步 对数据集进行分类和超参数调优
在这里分类的模型上,选择 支持向量分类(SVC) 来作为分类器。而其中的超参数包括 惩罚系数(svc_c) 、核函数(svc_kernel) 、核系数(svc__gamma) 只有‘rbf’, ‘poly’ 和‘sigmoid’这三种核函数需要核系数
同时使用了 交叉验证 与 随机网格搜索 来找出最优的超参数
在这里 选择 从 线性支持向量分类 和 径向基支持向量分类 去 比较哪种 更合适
from sklearn.pipeline import make_pipeline # 使用管道,把预处理和模型形成一个流程
from sklearn.preprocessing import StandardScaler # 标准化数据
from sklearn.svm import SVC # 支持向量分类
from sklearn.model_selection import RandomizedSearchCV # 随机网格搜索
X_faces = faces.data
y_faces = faces.target
faces_svc = make_pipeline(StandardScaler(), SVC(random_state=1))
# 浮点数,默认= 1.0
# 正则化参数。正则化的强度与C成反比。必须严格为正。此惩罚系数是l2惩罚系数的平方
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
# 径向基核函数 kernel='rbf'
# 线性核函数 kernel='linear'
# 惩罚系数 'svc__C':param_range
param_grid = [{
'svc__C':param_range,'svc__kernel':['linear']}, {
'svc__C':param_range,'svc__gamma':param_range,