机器学习——PCA
主成分分析(Principal Component Analysis,简称PCA)是一种用于数据降维的技术,旨在通过线性变换将原始数据映射到一个新的坐标系中。在这个新的坐标系中,数据的方差被最大化,这意味着我们将保留尽可能多的原始数据信息。PCA的关键思想是通过找到数据中的主成分,将数据在这些主成分上进行投影,从而实现数据的降维。首先,对原始数据进行标准化处理,确保每个特征的均值为零,标准差为一。
目录
1.PCA的定义和原理
主成分分析(Principal Component Analysis,简称PCA)是一种用于数据降维的技术,旨在通过线性变换将原始数据映射到一个新的坐标系中。在这个新的坐标系中,数据的方差被最大化,这意味着我们将保留尽可能多的原始数据信息。PCA的关键思想是通过找到数据中的主成分,将数据在这些主成分上进行投影,从而实现数据的降维。
具体而言,PCA的过程包括以下步骤:
-
标准化数据: 首先,对原始数据进行标准化处理,确保每个特征的均值为零,标准差为一。这一步骤是为了消除不同特征之间的量纲差异,使得每个特征对PCA的贡献相对均等。
-
计算协方差矩阵: 利用标准化后的数据,计算特征之间的协方差矩阵。协方差矩阵反映了特征之间的关联程度,是PCA的基础。
-
计算特征值和特征向量: 对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。特征向量表示了数据变换后的新坐标轴方向,而特征值则表示了在这个方向上的方差大小。
-
选择主成分: 将特征值从大到小排列,选择其中最大的k个特征值对应的特征向量作为主成分,其中k是希望保留的维度数。
-
数据投影: 将原始数据投影到所选的主成分上,得到降维后的数据。
目标:通过线性变换提取数据中的主要信息
PCA的最终目标是通过线性变换找到一个新的坐标系,使得在新坐标系中数据的方差最大。通过选择方差最大的主成分,我们能够保留原始数据中包含的大部分信息,而忽略掉方差较小的次要信息。
这个目标的直观解释是,我们希望在新的坐标系中,数据的“重要性”集中在少数几个主成分上。这样一来,我们可以用较少的特征来表示数据,从而实现降维的效果。同时,由于选择的是方差最大的主成分,我们保留了数据中的主要变化趋势,有助于保持数据的特征。这使得PCA成为处理高维数据的有力工具,可以用于数据可视化、去噪、特征选择等多个领域。
2PCA的数学基础
2.1方差
我们知道数值的分散程度,可以用数学上的方差来表述。一个变量的方差可以看做是每个元素与变量均值的差的平方和的均值,即:
为了方便处理,我们将每个变量的均值都化为 0 ,因此方差可以直接用每个元素的平方和除以元素个数表示:
于是上面的问题被形式化表述为:寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。
2.2 协方差矩阵的概念
在PCA中,协方差矩阵是一个关键的数学工具。协方差矩阵用来描述两个或多个随机变量之间的关系。对于一个包含n个特征的数据集,其协方差矩阵记作Σ(希腊字母sigma)。
协方差矩阵的元素(i,j)表示第i个和第j个特征之间的协方差。协方差描述了两个变量一起变化的趋势:如果两个变量一起增加或一起减少,它们之间的协方差为正;如果一个增加而另一个减少,协方差为负;如果它们之间没有关系,协方差为零。
对于标准化后的数据矩阵X,协方差矩阵Σ的计算公式如下:
其中,n 是样本数量, 是矩阵 X 的转置。
2.3特征值和特征向量的解释
协方差矩阵的特征值(eigenvalues)和特征向量(eigenvectors)是PCA的核心。它们提供了一个新的基础,其中数据的方差最大。
-
特征值: 协方差矩阵的特征值是一个数,表示在对应特征向量方向上的方差。特征值的大小决定了在该方向上数据的变化程度,越大表示方差越大。
-
特征向量: 协方差矩阵的特征向量是一个向量,描述了变换后的坐标系中的方向。每个特征向量都对应一个特征值,而且特征向量的长度为1。
协方差矩阵的特征值和特征向量满足以下方程:
其中, 是特征向量,λ 是特征值。这个方程表示协方差矩阵乘以特征向量等于特征值乘以特征向量。
特征值和特征向量的计算通过解特征方程得到,即:
其中,det 表示矩阵的行列式,I 是单位矩阵。解这个方程得到的特征值和对应的特征向量即为协方差矩阵的特征值和特征向量。
通过计算协方差矩阵的特征值和特征向量,我们得到一组特征值(降序排列)和对应的特征向量。这组特征值和特征向量表示了数据变换后的主成分。
3.PCA的工作流程
3.1. 标准化数据
PCA的第一步是对原始数据进行标准化处理,确保每个特征的均值为零,标准差为一。标准化消除了不同特征之间的量纲差异,使得每个特征对PCA的贡献相对均等。标准化后的数据矩阵记为 X。
3.2 计算协方差矩阵
通过标准化后的数据矩阵 X,计算协方差矩阵 Σ。协方差矩阵描述了数据中每对特征之间的关系,是PCA的数学基础。协方差矩阵的元素 表示第i个和第j个特征之间的协方差。
3.3.计算特征值和特征向量
对协方差矩阵 ΣΣ 进行特征值分解,得到特征值(λ) 和对应的特征向量(v)。特征值和特征向量满足以下方程:
这一步的目的是找到数据中的主成分,即在哪些方向上数据变化最为显著。
3.4. 选择主成分
按照特征值的大小降序排列,选择前k个特征值对应的特征向量作为主成分。这一步决定了我们希望保留的维度数,即降维后的数据将包含的主要信息。
3.5. 数据投影
构建变换矩阵 W,其列是选择的前k个特征向量。将原始数据矩阵 X 与变换矩阵 W 相乘,即 X⋅W,得到降维后的数据矩阵 。在新的坐标系中,每一行表示一个样本在主成分方向上的投影,实现了数据的降维。
4.PCA的应用场景
4.1. 数据压缩与降维
背景: 在许多实际场景中,数据集往往包含大量冗余信息,而且高维度的数据可能会导致计算和存储成本的增加。
应用: PCA可以被用来降低数据的维度,去除冗余特征,从而实现数据的压缩。通过保留数据中最重要的成分,可以在减少维度的同时尽量保留原始数据集的主要信息,为后续的分析和建模提供更高效的数据。
4.2. 去除数据中的噪声
背景: 实际采集到的数据常常包含噪声,这些噪声可能来自于传感器误差、采样误差等。噪声对于建模和分析会产生负面影响。
应用: PCA可以帮助去除数据中的噪声。通过保留方差较大的主成分,可以将噪声的影响降到最低。这使得在数据预处理阶段,PCA成为一种有力的工具,帮助提高模型的稳健性和鲁棒性。
4.3. 可视化高维数据
背景: 在高维数据中理解变量之间的关系通常是一项挑战。我们人类往往难以在超过三个维度的空间中直观理解数据。
应用: PCA提供了一种可视化高维数据的方法。通过将数据投影到前几个主成分所定义的平面上,我们可以在更低维度的空间中展示数据的主要特征。这样的可视化不仅有助于理解数据的结构,还可以用于探索数据集中的模式和趋势。
5.人脸识别实例
该人脸识别使用ORL_Faces数据集进行处理
导入库:
import cv2
import os
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report
from sklearn.preprocessing import StandardScaler
# 加载人脸数据集
def imgarray():
path = r"C:\Users\Brenty\Desktop\Face\ORL_Faces"
ImgList = []
for i in range(1, 41):
for j in range(1, 11):
imgPath = os.path.join(path, f"s{i}", f"{j}.pgm")
img = cv2.imread(imgPath)
if img is not None:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ImgList.append(img)
else:
print(f"无法读取图像:{imgPath}")
if not ImgList:
print("未成功读取任何图像,请检查文件路径和格式。")
else:
print(f"成功读取 {len(ImgList)} 张图像。")
ImgList = np.array(ImgList)
return ImgList
这是一个函数 imgarray()
,用于加载人脸数据集。它遍历了一个包含40个子文件夹(s1到s40),每个子文件夹包含10张图像。每张图像以.pgm
格式命名。图像读取后转换为灰度图,并将其添加到ImgList
列表中。
# 划分数据集
faces = imgarray()
labels = np.array([i for i in range(1, 41) for _ in range(10)])
X_train, X_test, y_train, y_test = train_test_split(
faces.reshape((faces.shape[0], -1)), labels, random_state=42)
调用 imgarray()
函数加载人脸数据集,并创建相应的标签。然后使用 train_test_split
将数据集划分为训练集和测试集。
# 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
对数据进行标准化处理,使其均值为0,方差为1。
# PCA降维
n_components = 150
pca = PCA(n_components=n_components, whiten=True).fit(X_train)
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
使用PCA对数据进行降维,选择了150个主成分。降维后的数据存储在 X_train_pca
和 X_test_pca
中。
# 使用KNN分类器
knn_classifier = KNeighborsClassifier(n_neighbors=5)
knn_classifier.fit(X_train_pca, y_train)
# 在测试集上进行预测
y_pred = knn_classifier.predict(X_test_pca)
# 打印分类报告
print("Classification Report:\n", classification_report(y_test, y_pred))
# 显示一些原始图像和降维后的图像
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
for i in range(n_row * n_col):
plt.subplot(n_row, n_col, i + 1)
plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
plt.title(titles[i], size=12)
plt.xticks(())
plt.yticks(())
eigenfaces = pca.components_.reshape((n_components, faces.shape[1], faces.shape[2]))
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, faces.shape[1], faces.shape[2])
plt.show()
打印模型的分类报告,包括精确度、召回率等指标。定义了一个用于显示原始图像和降维后图像的函数 plot_gallery
,然后使用PCA提取的特征进行可视化。最后,通过plt.show()
显示图像。
结果:
6.总结
优点:
-
降维: PCA通过投影数据到新的坐标系,实现了数据的降维,保留了大部分原始数据的信息。
-
去相关性: PCA通过变换数据,去除了数据在新坐标轴上的相关性,有助于消除冗余信息。
-
简化模型: 通过减少特征数量,PCA可以简化模型,提高模型的泛化能力,避免过拟合。
-
特征提取: PCA不仅降维,还能提取数据中的关键特征,帮助理解数据的结构和模式。
缺点:
-
线性假设: PCA对数据的线性可分性有假设,对于非线性数据的处理效果可能较差。
-
信息损失: 降维会导致信息损失,需要谨慎选择保留的主成分数量。
-
敏感性: 对数据缩放较为敏感,通常需要在应用前进行标准化处理。
-
计算复杂度: 处理大规模数据集时,计算复杂度可能较高,可考虑使用近似方法。
-
解释性差: 主成分是原始特征的线性组合,可能难以解释与实际问题的关系。
主成分分析(Principal Component Analysis,PCA)是一种广泛应用的降维技术,具有一系列优点和缺点。在实际应用中,选择使用PCA需要根据具体问题的特点和数据的性质,综合考虑其优缺点。正确使用PCA能够有效提高数据处理的效率和模型的性能。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)