1.导入数据包
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import GridSearchCV
2.加载数据集
导入sklearn中的人脸数据,需要越过那堵墙,否则会报错。
data = datasets.fetch_lfw_people(resize = 1, min_faces_per_person = 70)
data
取出其中的数据进行查看:
X = data['data']
y = data['target']
faces = data['images']
target_names = data['target_names']
display(X.shape,y.shape,faces.shape,target_names)
随机取出一个人脸:
# 随机选取一个人的图片并通过索引获取名字
index = np.random.randint(0,1288,size = 1)[0]
face = faces[index]
#根据索引获取名字
name = y[index]
print(target_names[name])
display(face.shape)
plt.imshow(face, cmap = 'gray')
plt.imshow()
X
:输入数据。可以是二维数组、三维数组、PIL图像对象、matplotlib路径对象等。cmap
:颜色映射。用于控制图像中不同数值所对应的颜色。可以选择内置的颜色映射,如gray
、hot
、jet
等,也可以自定义颜色映射。norm
:用于控制数值的归一化方式。可以选择Normalize
、LogNorm
等归一化方法。aspect
:控制图像纵横比(aspect ratio)。可以设置为auto
或一个数字。interpolation
:插值方法。用于控制图像的平滑程度和细节程度。可以选择nearest
、bilinear
、bicubic
等插值方法。alpha
:图像透明度。取值范围为0~1。origin
:坐标轴原点的位置。可以设置为upper
或lower
。extent
:控制显示的数据范围。可以设置为[xmin, xmax, ymin, ymax]
。vmin
、vmax
:控制颜色映射的值域范围。filternorm 和 filterrad
:用于图像滤波的对象。可以设置为None
、antigrain
、freetype
等。imlim
: 用于指定图像显示范围。resample
:用于指定图像重采样方式。url
:用于指定图像链接。
3.直接使用SVM模型建模
由于原来的数据很大,而且数据量多,我们首先对原始数据进行PCA降维
%%time
# 由于原来的数据很大,而且数据量多,我们首先对原始数据进行PCA降维
## %%time
# 进行数据的降维
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X)
display(X.shape,X_pca.shape)
在jupyter遇到 UsageError: Line magic function `%%time` not found.时,要把%%time放在这个代码块的首行顶格
然后对降维后的数据集进行训练和预测结果:
其中的C代表的是惩罚系数,用来防止过拟合,我们先用默认的初始值测试下性能
%%time
# 降维之后的数据
X_train,X_test,y_train,y_test,faces_train,faces_test = train_test_split(X_pca,y,faces)
# C为惩罚项,越大,容忍错误越小
# C越大,趋势:想方设发,把数据分开,容易造成过拟合
svc = SVC(C=1)
svc.fit(X_train,y_train)
# 训练数据效果很好,测试数据效果不好就是过拟合现象
print('训练数据的得分:',svc.score(X_train,y_train))
print('测试数据的得分:',svc.score(X_test,y_test))
# 算法的预测值
y_pred = svc.predict(X_test)
4.数据可视化
然后我们随机加载50张图片,并可视化查看预测结果
plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
plt.subplot(10,5,i+1) # 子视图
plt.imshow(faces_test[i],cmap = 'gray')
plt.axis('off') # 刻度关闭
# 贴上标签,并且对比实际数据和预测数据
true_name = target_names[y_test[i]].split(' ')[-1]
predict_name = target_names[y_pred[i]].split(' ')[-1]
plt.title(f'True:{true_name}\nPred:{predict_name}')
plt.figure()
- num : 图像编号或名称,数字为编号,字符串为名称
- figsize : 指定figure的宽和高,单位为英寸
- dpi : 指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80
- facecolor : 背景的颜色
- edgecolor : 边框颜色
- frameon : 是否显示边框
plt.subplot(nrows, ncols, index)
- 第一个代表行数
- 第二个代表列数
- 第三个代表索引位置。
预测结果如下(红框代表预测错误):
预测错误占比:16/50
5.网络搜索优化确定最佳性能
# 从结果来看,预测效果并不是很好,sklearn为我们集成好了网络搜索确定最佳性能的方法,
# 只要吧要传进的参数填进去,它会为我们自动搭配获得最优参数。
%%time
svc = SVC()
# C为惩罚系数(防止过拟合),kernel为核函数类型,tol为停止训练的误差值、精度
params = {'C':np.logspace(-10,10,50),'kernel':['linear', 'poly', 'rbf', 'sigmoid'],'tol':[0.01,0.001,0.0001]}
gc = GridSearchCV(estimator = svc,param_grid = params,cv = 5)
gc.fit(X_pca,y)
gc.best_params_
从结果可以看出:
最优惩罚系数C为0.014563484775012445
最优核函数类型是linear线性模型
最优精度为0.001.
6.使用最佳性能SVM建模
svc = SVC(C = 0.014563484775012445,kernel='linear',tol = 0.01)
# 随机划分的
X_pca_train,X_pca_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
svc.fit(X_pca_train,y_train)
print('训练数据得分:',svc.score(X_pca_train,y_train))
print('测试数据的得分:',svc.score(X_pca_test,y_test))
y_pred = svc.predict(X_pca_test)
plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
plt.subplot(10,5,i + 1) # 子视图
plt.imshow(faces_test[i],cmap = 'gray')
plt.axis('off') # 刻度关闭
# 贴上标签,并且对比实际数据和预测数据
true_name = target_names[y_test[i]].split(' ')[-1]
predict_name = target_names[y_pred[i]].split(' ')[-1]
plt.title(f'True:{true_name}\nPred:{predict_name}')
预测结果如下:
预测错误占比:5/50,大大提升了准确率。
优化后的完整代码:
from sklearn.decomposition import PCA
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import GridSearchCV
data = datasets.fetch_lfw_people(resize = 1, min_faces_per_person = 70)
# 进行数据的降维
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X)
display(X.shape,X_pca.shape)
svc = SVC()
# C为惩罚系数(防止过拟合),kernel为核函数类型,tol为停止训练的误差值、精度
params = {'C':np.logspace(-10,10,50),'kernel':['linear', 'poly', 'rbf', 'sigmoid'],'tol':[0.01,0.001,0.0001]}
gc = GridSearchCV(estimator = svc,param_grid = params,cv = 5)
gc.fit(X_pca,y)
gc.best_params_
svc = SVC(C = 0.014563484775012445,kernel='linear',tol = 0.01)
# 随机划分的
X_pca_train,X_pca_test,y_train,y_test, faces_train,faces_test = train_test_split(X_pca,y,faces)
svc.fit(X_pca_train,y_train)
print('训练数据得分:',svc.score(X_pca_train,y_train))
print('测试数据的得分:',svc.score(X_pca_test,y_test))
y_pred = svc.predict(X_pca_test)
plt.figure(figsize=(5 * 2, 10 * 3))
for i in range(50):
plt.subplot(10,5,i + 1) # 子视图
plt.imshow(faces_test[i],cmap = 'gray')
plt.axis('off') # 刻度关闭
# 贴上标签,并且对比实际数据和预测数据
true_name = target_names[y_test[i]].split(' ')[-1]
predict_name = target_names[y_pred[i]].split(' ')[-1]
plt.title(f'True:{true_name}\nPred:{predict_name}')