1. 引言
主成分分析(Principal Component Analysis,PCA)是一种常用的降维技术,用于在保留数据主要信息的同时减少数据的维度。通过将原始特征转化为一组互相不相关的主成分,PCA可以帮助我们更好地理解数据的结构和模式。
2. 主成分
主成分是原始特征的线性组合,具有最大的方差。第一个主成分包含最大方差,第二个主成分在与第一个主成分不相关的方向上包含次大方差,以此类推。
3. 数学基础
在理解PCA之前,我们需要了解一些基本的数学概念。PCA的核心在于协方差矩阵、特征向量和特征值。协方差矩阵描述了不同特征之间的关系,而特征向量和特征值则是PCA转换的关键元素。数学公式如下:
协方差矩阵:
特征值方程:
4. PCA的步骤
实施PCA的步骤包括:
- 数据标准化: 将数据按特征进行标准化,确保每个特征的均值为0,方差为1。
- 计算协方差矩阵: 利用标准化后的数据计算协方差矩阵。
- 求解特征值和特征向量: 对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。
- 选择主成分: 根据特征值的大小选择保留的主成分数量。
- 构建新特征空间: 使用选定的主成分构建新的特征空间。
5.理解
PCA技术主要是通过投影来实现高维数据转换为低维,并且能够能够最大程度地保留原始数据的信息。而要实现降维操作的话,就是要找到数据中方差最大的方向,例如第一个主成分是原始数据中方差最大的方向,第二个主成分是在与第一个主成分不相关的方向上具有最大方差的方向。
至于如何确定主成分,就是通过协方差矩阵中的特征值和特征向量来确定了数据里主要的大小和方向。最后通过特征值的大小来确定该主成分是否该保留,最后实现降维的操作。较大的特征值对应的主成分携带更多信息,因此我们选择保留前几个特征值较大的主成分。
例如在二维空间中,PCA就是寻找一条直线,使得数据点到这条直线的投影距离平方和最小,这样的直线就是第一主成分。
6.实现
def PCA(data,r):
data=np.float32(np.mat(data))
rows,cols=np.shape(data)
data_mean=np.mean(data,0)#对列求平均值
A=data-np.tile(data_mean,(rows,1))#将所有样例减去对应均值得到A
C=A*A.T #得到协方差矩阵
D,V=np.linalg.eig(C)#求协方差矩阵的特征值和特征向量
V_r=V[:,0:r]#按列取前r个特征向量
V_r=A.T*V_r#小矩阵特征向量向大矩阵特征向量过渡
for i in range(r):
V_r[:,i]=V_r[:,i]/np.linalg.norm(V_r[:,i])#特征向量归一化
final_data=A*V_r
return final_data,data_mean,V_r
import cv2
import os
import numpy as np
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
def load_faces_data(data_folder):
images = []
labels = []
label = 0
for filename in os.listdir(data_folder):
image_path = os.path.join(data_folder, filename)
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if image is not None:
image = cv2.resize(image, (100, 100))
image_flat = image.flatten()
images.append(image_flat)
labels.append(label)
return np.array(images), np.array(labels)
data_folder = r"E:\face\ABERDEEN_Face\ABERDEEN"
X, y = load_faces_data(data_folder)
n_components = 50
pca = PCA(n_components=n_components)
X_pca = pca.fit_transform(X)
# 输出PCA的方差比例
explained_variance_ratio = pca.explained_variance_ratio_
print("每个主成分的解释方差比例:")
print(explained_variance_ratio)
# 创建并训练 K 近邻分类器
knn_classifier = KNeighborsClassifier(n_neighbors=3)
knn_classifier.fit(X_pca, y)
# 输出输入维度
print("X_pca的形状:", X_pca.shape)
print("knn_classifier的输入维度:", knn_classifier.n_features_in_)
# 预测整个文件夹中的所有图像
predictions = knn_classifier.predict(X_pca)
# 打印每张图像的预测结果
for filename, prediction in zip(os.listdir(data_folder), predictions):
print(f"图像 {filename} 的预测结果为:Person {prediction}")