# 人臉辨識 使用PCA與LDA
611021209 資工碩一 劉怡彣
## github 連結
https://github.com/claire100502051/PRHW2.git
## 問題描述
實作作方法與步驟:
1. 依據資料庫的影像格式,設計一個讀取pgm影像檔的函式。
2. 每張人臉影像均為92x112=10304的灰階影像,讀取後請將其轉為10304x1的向量,即成為一個樣本。
3. 資料庫共含有400張影像(40人,每人10張),訓練時請只用200張(每人取5張)。
4. 利用PCA計算此200張影像的轉換矩陣,設法將維度從10304降至10, 20, 30, 40, 50維
5. 以這些較低維度的樣本訓練出你所學過的任何分類器來進行辨識。
6. 請比較不同維度的辨識率,並統計混淆矩陣(Google一下這是什麼?)
7. 請以降維後的樣本,繼續利用FLD(LDA)找出另一轉換矩陣,利用此矩陣轉換降維後的樣本(毋需降維只須轉換)為有較佳的類別分離度之新樣本。
8. 以前述之辨識器再度評量辨識率以及統計混淆矩陣。
## 套件使用
```python=
import numpy as np
import os
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
```
## 資料預處理
**資料讀取與分類**
```python=
for i in range(1,41):
for j in range(1,11):
img = plt.imread('att_faces/s{}/{}.pgm'.format(i,j))
#print(img)
if(j<=5):
train.append(img)
train_t.append(i)
else:
test.append(img,)
test_t.append(i)
#print(img)
```
**轉換成一維陣列**
```python=
#1D
for img in train:
oneD=[]
for x in range(img.shape[0]):
for y in range(img.shape[1]):
oneD.append(img[x][y])
train_img.append(oneD)
for img in test:
oneD=[]
for x in range(img.shape[0]):
for y in range(img.shape[1]):
oneD.append(img[x][y])
test_img.append(oneD)
```
**轉換成np.array**
```python=
train_img = np.array(train_img)
test_img = np.array(test_img)
test_t = np.array(test_t)
train_t = np.array(train_t)
```
## 主程式
```python=
#GridSearchCV參數
param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
#PCA
pcaClf = GridSearchCV(SVC(kernel='linear', class_weight='balanced'),param_grid)
ldaClf = GridSearchCV(SVC(kernel='linear', class_weight='balanced'),param_grid)
for i in range(10,51,10):
print('\n'+str(i)+'\n')
mPCA = PCA(n_components=i).fit(train_img)
pca_tr = mPCA.transform(train_img)
pca_te = mPCA.transform(test_img)
pca_pre = pcaClf.fit(pca_tr,train_t)
pca_t_p = pca_pre.predict(pca_te)
pca_cm = confusion_matrix(test_t,pca_t_p)
#acc
#pca_acc = accuracy_score(pca_t_p,test_t)
pca_report = classification_report(test_t,pca_t_p)
print('--------------------------------------------------------------------------------------')
print("\nPCA confusion matrix")
print(pca_cm)
print('\nPCA report')
print(pca_report)
print('--------------------------------------------------------------------------------------')
#LDA
if(i<40):
mLDA = LDA(n_components = i).fit(pca_tr,train_t)
lda_tr = mLDA.transform(pca_tr)
lda_te = mLDA.transform(pca_te)
lda_pre = ldaClf.fit(lda_tr, train_t)
lda_t_p = lda_pre.predict(lda_te)
lda_cm = confusion_matrix(test_t,lda_t_p)
lda_report = classification_report(test_t,lda_t_p)
print("\nLDA confusion matrix")
print(lda_cm)
print('\nLDA report')
print(lda_report)
print('--------------------------------------------------------------------------------------')
```
## 實作結果
:::info
* precision= TP/(TP+FN)
* recall= TP/(TP+FP)
* f1-score = 2 * Precision * Recall / (Precision + Recall)
* macro avg: 每個類別的accuracy,precision,recall,f1-score的平均
* macro avg=(P_no+P_yes)/2
* weighted avg: 加權平均
:::
**10維:**
:::info
PCA:
confusion matrix
PCA confusion matrix
[[4 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
report
precision recall f1-score support
1 1.00 0.80 0.89 5
2 0.62 1.00 0.77 5
3 1.00 1.00 1.00 5
4 0.83 1.00 0.91 5
5 1.00 0.80 0.89 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 1.00 1.00 1.00 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.71 1.00 0.83 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 0.83 1.00 0.91 5
16 0.83 1.00 0.91 5
17 0.00 0.00 0.00 5
18 0.83 1.00 0.91 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 1.00 1.00 1.00 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 0.83 1.00 0.91 5
25 0.71 1.00 0.83 5
26 1.00 1.00 1.00 5
27 1.00 0.20 0.33 5
28 0.50 0.60 0.55 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 1.00 1.00 5
32 1.00 0.40 0.57 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 0.40 0.57 5
36 0.38 0.60 0.46 5
37 0.83 1.00 0.91 5
38 0.83 1.00 0.91 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.86 200
macro avg 0.89 0.86 0.85 200
weighted avg 0.89 0.86 0.85 200
LDA:
LDA confusion matrix
[[4 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
LDA report
precision recall f1-score support
1 1.00 0.80 0.89 5
2 1.00 1.00 1.00 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 1.00 1.00 5
6 1.00 1.00 1.00 5
7 0.83 1.00 0.91 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.60 0.75 5
11 0.83 1.00 0.91 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 0.83 1.00 0.91 5
16 0.83 1.00 0.91 5
17 0.00 0.00 0.00 5
18 1.00 1.00 1.00 5
19 1.00 1.00 1.00 5
20 1.00 0.80 0.89 5
21 1.00 1.00 1.00 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 1.00 1.00 1.00 5
25 0.83 1.00 0.91 5
26 1.00 0.80 0.89 5
27 1.00 0.40 0.57 5
28 0.43 0.60 0.50 5
29 0.83 1.00 0.91 5
30 1.00 1.00 1.00 5
31 1.00 1.00 1.00 5
32 1.00 0.60 0.75 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 0.80 0.89 5
36 0.50 0.80 0.62 5
37 0.83 1.00 0.91 5
38 0.83 1.00 0.91 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.89 200
macro avg 0.91 0.89 0.88 200
weighted avg 0.91 0.89 0.88 200
:::
**20維**
:::info
PCA:
PCA confusion matrix
[[5 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
PCA report
precision recall f1-score support
1 0.83 1.00 0.91 5
2 0.71 1.00 0.83 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 0.80 0.89 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.71 1.00 0.83 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 0.00 0.00 0.00 5
15 1.00 1.00 1.00 5
16 1.00 0.80 0.89 5
17 0.00 0.00 0.00 5
18 0.83 1.00 0.91 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 0.83 1.00 0.91 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 0.83 1.00 0.91 5
25 0.83 1.00 0.91 5
26 1.00 0.80 0.89 5
27 1.00 0.40 0.57 5
28 0.38 0.60 0.46 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 0.80 0.89 5
32 1.00 0.60 0.75 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 0.80 0.89 5
36 0.38 0.60 0.46 5
37 0.83 1.00 0.91 5
38 1.00 1.00 1.00 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.87 200
macro avg 0.88 0.87 0.86 200
weighted avg 0.88 0.87 0.86 200
LDA:
LDA confusion matrix
[[5 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 3 0]
[0 0 0 ... 0 0 5]]
LDA report
precision recall f1-score support
1 0.62 1.00 0.77 5
2 0.83 1.00 0.91 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 1.00 1.00 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.80 0.80 0.80 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 1.00 1.00 1.00 5
16 1.00 0.40 0.57 5
17 0.00 0.00 0.00 5
18 1.00 1.00 1.00 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 1.00 1.00 1.00 5
22 0.83 1.00 0.91 5
23 0.71 1.00 0.83 5
24 1.00 1.00 1.00 5
25 1.00 1.00 1.00 5
26 1.00 0.80 0.89 5
27 1.00 0.20 0.33 5
28 0.43 0.60 0.50 5
29 0.83 1.00 0.91 5
30 0.71 1.00 0.83 5
31 1.00 1.00 1.00 5
32 1.00 0.80 0.89 5
33 1.00 0.80 0.89 5
34 1.00 1.00 1.00 5
35 1.00 1.00 1.00 5
36 0.57 0.80 0.67 5
37 0.71 1.00 0.83 5
38 0.83 1.00 0.91 5
39 1.00 0.60 0.75 5
40 1.00 1.00 1.00 5
accuracy 0.86 200
macro avg 0.89 0.86 0.86 200
weighted avg 0.89 0.86 0.86 200
:::
**30維**
:::info
PCA:
PCA confusion matrix
[[5 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
PCA report
precision recall f1-score support
1 1.00 1.00 1.00 5
2 0.83 1.00 0.91 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 0.80 0.89 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.71 1.00 0.83 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 0.83 1.00 0.91 5
16 1.00 1.00 1.00 5
17 0.00 0.00 0.00 5
18 0.83 1.00 0.91 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 0.83 1.00 0.91 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 0.83 1.00 0.91 5
25 1.00 1.00 1.00 5
26 1.00 0.80 0.89 5
27 1.00 0.40 0.57 5
28 0.43 0.60 0.50 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 0.80 0.89 5
32 1.00 0.60 0.75 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 1.00 1.00 5
36 0.38 0.60 0.46 5
37 0.83 1.00 0.91 5
38 1.00 1.00 1.00 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.89 200
macro avg 0.91 0.89 0.88 200
weighted avg 0.91 0.89 0.88 200
LDA:
LDA confusion matrix
[[4 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
LDA report
precision recall f1-score support
1 0.80 0.80 0.80 5
2 0.83 1.00 0.91 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 1.00 1.00 5
6 1.00 1.00 1.00 5
7 1.00 0.80 0.89 5
8 1.00 1.00 1.00 5
9 1.00 1.00 1.00 5
10 1.00 1.00 1.00 5
11 0.80 0.80 0.80 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 1.00 1.00 1.00 5
16 1.00 0.80 0.89 5
17 0.00 0.00 0.00 5
18 1.00 1.00 1.00 5
19 1.00 0.80 0.89 5
20 1.00 0.80 0.89 5
21 0.71 1.00 0.83 5
22 0.83 1.00 0.91 5
23 0.83 1.00 0.91 5
24 1.00 1.00 1.00 5
25 1.00 1.00 1.00 5
26 1.00 1.00 1.00 5
27 1.00 0.20 0.33 5
28 0.57 0.80 0.67 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 0.80 0.89 5
32 1.00 0.80 0.89 5
33 1.00 0.80 0.89 5
34 1.00 1.00 1.00 5
35 1.00 1.00 1.00 5
36 0.50 0.80 0.62 5
37 0.83 1.00 0.91 5
38 0.83 1.00 0.91 5
39 1.00 1.00 1.00 5
40 0.83 1.00 0.91 5
accuracy 0.88 200
macro avg 0.91 0.88 0.88 200
weighted avg 0.91 0.88 0.88 200
:::
:::danger
* LDA模型在SKlearn 維度只到0~min(n_features, n_classes-1)之間的維度,本次的資料中最多的維度是39度,因此40維與50維的測試結果並不會有LDA
:::
**40維**
:::info
PCA:
PCA confusion matrix
[[5 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
PCA report
precision recall f1-score support
1 1.00 1.00 1.00 5
2 1.00 1.00 1.00 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 0.80 0.89 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.71 1.00 0.83 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 0.83 1.00 0.91 5
16 1.00 1.00 1.00 5
17 0.00 0.00 0.00 5
18 0.83 1.00 0.91 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 1.00 1.00 1.00 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 0.83 1.00 0.91 5
25 1.00 1.00 1.00 5
26 1.00 0.80 0.89 5
27 1.00 0.40 0.57 5
28 0.43 0.60 0.50 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 1.00 1.00 5
32 1.00 0.80 0.89 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 1.00 1.00 5
36 0.38 0.60 0.46 5
37 0.83 1.00 0.91 5
38 1.00 1.00 1.00 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.90 200
macro avg 0.92 0.89 0.89 200
weighted avg 0.92 0.90 0.89 200
:::
**50維**
:::info
PCA:
PCA confusion matrix
[[5 0 0 ... 0 0 0]
[0 5 0 ... 0 0 0]
[0 0 5 ... 0 0 0]
...
[0 0 0 ... 5 0 0]
[0 0 0 ... 0 5 0]
[0 0 0 ... 0 0 5]]
PCA report
precision recall f1-score support
1 1.00 1.00 1.00 5
2 1.00 1.00 1.00 5
3 1.00 1.00 1.00 5
4 1.00 1.00 1.00 5
5 1.00 1.00 1.00 5
6 1.00 1.00 1.00 5
7 1.00 1.00 1.00 5
8 0.83 1.00 0.91 5
9 1.00 1.00 1.00 5
10 1.00 0.80 0.89 5
11 0.71 1.00 0.83 5
12 1.00 1.00 1.00 5
13 1.00 1.00 1.00 5
14 1.00 0.20 0.33 5
15 0.83 1.00 0.91 5
16 1.00 1.00 1.00 5
17 0.00 0.00 0.00 5
18 1.00 1.00 1.00 5
19 1.00 0.80 0.89 5
20 1.00 1.00 1.00 5
21 1.00 1.00 1.00 5
22 1.00 1.00 1.00 5
23 1.00 1.00 1.00 5
24 0.83 1.00 0.91 5
25 1.00 1.00 1.00 5
26 1.00 0.80 0.89 5
27 1.00 0.40 0.57 5
28 0.43 0.60 0.50 5
29 1.00 1.00 1.00 5
30 1.00 1.00 1.00 5
31 1.00 1.00 1.00 5
32 1.00 0.80 0.89 5
33 1.00 1.00 1.00 5
34 1.00 1.00 1.00 5
35 1.00 1.00 1.00 5
36 0.38 0.60 0.46 5
37 0.83 1.00 0.91 5
38 1.00 1.00 1.00 5
39 1.00 1.00 1.00 5
40 1.00 1.00 1.00 5
accuracy 0.90 200
macro avg 0.92 0.90 0.90 200
weighted avg 0.92 0.90 0.90 200
:::
## 結果討論
:::success
針對本次的結果:
* 在PCA中,維度越高,準確率有上升的趨勢
* 在LDA中,維度與準確度沒有絕對的關聯,但不清楚是否是因為先處理了PCA後造成的
* 詢問過同學的結果,同學的結果是維度在10的時候LDA所分析的準確度是最高的
* 在各個維度的測試中PCA與LDA的準確度差距不超過3%
* 在這個資料集中,40維與50維的PCA準確度非常接近,再將維度往上的話感覺並不會出現差距很大的準確度
* 在經過PCA與LDA處理的資料集相較於只有用單一的PCA進行處理要來的準確
:::