操作平臺: windows10, python37, jupyter
任務目標: 使用SVC算法,識別人臉,姓名
1、導入圖片數據
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import sklearn.datasets as datasets
from sklearn.svm import SVC
#它加載圖片的位置在計算機用戶目錄下scikit_learn_data中,如果不存在它會自動從網上下載
faces = datasets.fetch_lfw_people(min_faces_per_person=70,resize=1) #只加載大於70張圖片的數據,resize原尺寸
faces
{'data': array([[254. , 254. , 254.66667 , ..., 87.666664, 86.333336,
86.333336],
[ 42. , 33. , 32.333332, ..., 122. , 148.33333 ,
185.33333 ],
[ 94. , 72. , 74. , ..., 182.66667 , 183. ,
182.33333 ],
...,
[ 85. , 85.666664, 85.333336, ..., 44. , 36.333332,
30.333334],
[ 49.666668, 49.666668, 48.333332, ..., 178.33333 , 166.66667 ,
126.333336],
[ 31.333334, 33.333332, 26.666666, ..., 48.333332, 63. ,
99. ]], dtype=float32),
'images': array([[[254. , 254. , 254.66667 , ..., 42. ,
38. , 39. ],
[254. , 254.33333 , 254. , ..., 43.333332,
38. , 39. ],
[254.66667 , 254.33333 , 253.33333 , ..., 44. ,
39. , 39. ],
...,
[ 44. , 41.333332, 42.333332, ..., 38.333332,
50.666668, 60.666668],
[ 47. , 45.333332, 51.333332, ..., 44.666668,
61.666668, 84.666664],
[ 46. , 45.333332, 47.333332, ..., 48.333332,
63. , 99. ]]], dtype=float32),
'target': array([5, 6, 3, ..., 5, 3, 5], dtype=int64),
'target_names': array(['Ariel Sharon', 'Colin Powell', 'Donald Rumsfeld', 'George W Bush',
'Gerhard Schroeder', 'Hugo Chavez', 'Tony Blair'], dtype='<U17'),
'DESCR': ".. _labeled_faces_in_the_wild_dataset:\ ...
結果分析: 我們導入的數據中有五個參數,分別爲data, images, target, target_names, DESCR。
取出目標值:
X = faces['data']
y = faces['target']
names = faces.target_names
image = faces['images']
image.shape
(1288, 125, 94)
2、隨機查看圖片
index = np.random.randint(1288,size = 1)[0]
plt.imshow(image[index],cmap = plt.cm.gray) #繪製圖片
print(y[index]) #文件夾
names[y[index]] #文件夾名稱,也就是人的名字
3
'George W Bush'
3、建模評估
%%time
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)
svc = SVC(kernel='rbf') #高斯分佈
svc.fit(X_train,y_train)
print(svc.score(X_test,y_test))
0.7906976744186046
Wall time: 32.1 s
結果分析: 該方法訓練測試數據大約耗時32秒,用時較長,準確率約80%。
4、PCA數據處理
4.1、數據脫敏處理
from sklearn.decomposition import PCA
# 主成分分析
# Principal component analysis (PCA)
# whiten = True 白化,歸一化
pca = PCA(n_components=0.9,whiten = True) #降低9倍
# 代表原來的數據,經過矩陣運算,結果屬性看不懂(屬性,沒有實際的物理意義),脫敏數據
X_pca = pca.fit_transform(X)
X_pca.shape
(1288, 116)
結果分析: 經過脫敏處理後,它的數據量下降,主要是因爲捨棄了一些沒有意義的值,但是它的結果屬性很是看不懂的,沒有物理意義。
4.2、建模評估
%%time
X_train, X_test, y_train, y_test = train_test_split(X_pca,y,test_size = 0.2)
svc = SVC()
svc.fit(X_train, y_train)
print(svc.score(X_test,y_test))
0.7829457364341085
Wall time: 405 ms
結果分析: 它的精確率沒有發生明顯的變化,但是使用的時間卻在明顯的提升。
5、過採樣技術處理
- 過採樣技術是通過原數據,來填充短缺數據的一種方法,可以讓比較少的數據升到多數據的量。
5.1、查看原始數據
for i in range(7):
print(names[i],(y == i).sum())
Ariel Sharon 77
Colin Powell 236
Donald Rumsfeld 121
George W Bush 530
Gerhard Schroeder 109
Hugo Chavez 71
Tony Blair 144
結果分析: 我們用來學習的數據一共有7個人,少的有71張圖片,多的有530張圖片,接下來將使用過採量技術,把所有數據都填充到530張人臉圖片。
5.2、過採量
- Synthetic Minority Over-sampling Technique(綜合少數過採樣技術)
from imblearn.over_sampling import SMOTE
smote = SMOTE()
X2,y2 = smote.fit_resample(X,y) #重新採樣
#查看採樣結果
for i in range(7):
print(names[i],(y2 == i).sum())
Ariel Sharon 530
Colin Powell 530
Donald Rumsfeld 530
George W Bush 530
Gerhard Schroeder 530
Hugo Chavez 530
Tony Blair 530
結果分析: 現在所有人的臉部照片都是530張了。
5.3、建模評估
%%time
X_train,X_test,y_train,y_test = train_test_split(X2_pca,y2,test_size = 0.2)
svc = SVC()
svc.fit(X_train,y_train)
print(svc.score(X_test,y_test))
0.9824797843665768
Wall time: 1.65 s
結果分析: 現在的準確率高達98%,並且只需要約1.6秒鐘,已經相當不錯了。
5.4、批量展示預測圖片
%%time
#切分訓練集和測試集
face_train,face_test,X_train,X_test,y_train,y_test = train_test_split(X2,X2_pca,y2,test_size = 0.2)
y_ = svc.predict(X_test) #預測
plt.figure(figsize=(10*2,10*3)) #設置畫布
for i in range(100):
ax = plt.subplot(10,10,i + 1)
face = face_test[i].reshape(125,94) #image.shape = (1288, 125, 94)
ax.imshow(face,cmap = 'gray') #展示圖片
ax.axis('off') #隱藏x,y軸
t = names[y_test[i]].split(' ')[-1] #真實名稱
p = names[y_[i]].split(' ')[-1] # 預測出來的名稱
ax.set_title('True:%s\nPredict:%s'%(t,p))