主成分分析
相关概念
方差
方差是一个用来衡量一组数据离散程度的统计量,它是各样本与样本均值的差的平方和的平均值。方差越大,表示数据的离散程度越大。
方差公式:
s 2 = ∑ i = 1 n ( x i − x ) 2 ) n − 1 s^2 = \frac{\sum_{i=1}^{n}(x_i - x)^2)}{n - 1} s2=n−1∑i=1n(xi−x)2)
协方差
协方差是一个用来衡量两个随机变量之间相关性或线性关系的统计量,它描述了两个随机变量的变化趋势是否一致。协方差的值可以为正、负或零,分别表示正相关、负相关或无相关。绝对值越大,表示两个随机变量的相关性越强。
然而,协方差的值无法直接比较,因为它受到随机变量尺度的影响。为了消除尺度影响,可以使用相关系数来衡量两个随机变量的相关性。
协方差公式:
c o v ( X , Y ) = ∑ i = 1 n ( X i − X ˉ ) ( Y i − Y ˉ ) n − 1 cov(X, Y) = \frac{\sum_{i=1}^{n}(X_i - \bar{X})(Y_i - \bar{Y})}{n - 1} cov(X,Y)=n−1∑i=1n(Xi−Xˉ)(Yi−Yˉ)
协方差矩阵
协方差矩阵是一个对称矩阵,用来衡量多个随机变量之间的相关性或线性关系。它描述了多个随机变量之间的变化趋势是否一致。
协方差矩阵可以用来衡量多个随机变量之间的相关性,可以通过观察矩阵中的元素值来判断变量之间的关系。对角线上的元素表示每个随机变量的方差,非对角线上的元素表示不同随机变量之间的协方差。
特征值和特征向量
在线性代数中,特征值和特征向量是矩阵的重要概念。
特征值(eigenvalue)是一个标量,表示线性变换中的一个重要性质。对于一个n×n的方阵A,如果存在一个非零向量v使得满足以下条件:
A v = λ v Av = λv Av=λv
其中,v是一个非零向量,λ是一个标量,则λ被称为矩阵A的特征值,v被称为对应于特征值λ的特征向量。
特征向量(eigenvector)是与特征值相关联的向量。特征向量是指在线性变换中,只发生伸缩而不改变方向的向量。特征向量可以通过特征值方程来求解。
特征值和特征向量的重要性在于它们提供了矩阵的重要性质和结构信息。通过求解特征值和特征向量,可以得到矩阵的主要特征、主要方向以及变换的性质。在数据分析和机器学习中,特征值和特征向量经常被用于数据降维、特征提取和数据压缩等任务。
主成分分析
数据降维
数据降维是指通过保留数据中最重要的信息,将高维数据转换为低维表示的过程。在实际应用中,高维数据可能存在冗余、噪声或者维度灾难等问题,这时候可以使用数据降维技术来减少数据的维度,从而简化数据分析和处理的复杂性。数据降维可以帮助我们在处理和分析大规模高维数据时更加高效和准确,同时可以减少存储空间和计算成本。
数据降维的主要目的是在尽量保留原始数据的关键特征的前提下,减少数据的维度。常见的数据降维方法包括主成分分析(PCA)、因子分析(FA)、独立成分分析(ICA)、线性判别分析(LDA)、奇异值分解(SVD)等。
主成分分析原理
主成分分析(Principal Component Analysis,PCA)是一种常用的无监督学习方法,主要用于数据降维和特征提取。其目的是通过线性变换将原始数据投影到一组新的正交特征上,使得投影后的数据具有最大的方差。这样可以保留最重要的信息,并且去除冗余的维度。换句话说,PCA试图找到最能够解释数据变异性的主要方向(主成分),这些主成分是数据中最重要的特征,通过按照方差大小递减的顺序选择,可以实现降维。
主成分分析可以把具有相关性的高维变量转换为线性无关的低维变量,称为主成分。主成分能够尽可能保留原始数据的信息。
矩阵的主成分就是其协方差矩阵对应的特征向量,按照对应的特征值大小进行排序,最大的特征值就是第一主成分,其次是第二主成分,依次类推。
主成分分析过程
主成分分析的步骤如下:
- 对数据进行标准化,使得每个特征的均值为0,方差为1。
- 计算协方差矩阵,反映不同特征之间的相关性。
- 对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。
- 将特征值按照大小排序,选择前k个特征值对应的特征向量作为主成分。
- 将原始数据与选取的主成分相乘,得到降维后的数据。
sklearn库中的PCA
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)
- n_components -- PCA算法中所要保留的主成分个数n,即保留下来的特征个数n;
int或string类型,缺省时默认为None,即所有成分被保留;
赋值为int,比如n_components=1,则将把原始数据降到一个维度;
赋值为string,比如n_components='mle',则将自动选取特征个数n,使得满足所要求的方差百分比。 - copy -- bool类型,True或者False,缺省时默认为True;
该参数表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行的运算;若为False,则运行PCA算法后,原始训练数据的值会发生改变,因为是在原始数据上进行的降维计算。 - whiten -- bool类型,缺省时默认为False;
白化,使得每个特征具有相同的方差。如果为True,它会将分量向量标准化为单位方差,这在某些情况下可用于预测模型(默认为False)。
PCA对象的方法:
- fit(X, y=None)
fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的"训练"这一步骤。因为PCA是无监督学习算法,此处y自然等于None;
fit(X),表示用数据X来训练PCA模型;
pca.fit(X),表示用X对pca这个对象进行训练。 - fit_transform(X)
用X来训练PCA模型,同时返回降维后的数据;
newX=pca.fit_transform(X),newX就是降维后的数据。 - transform(X)
将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform()方法来降维。
主成分分析实现案例
已知鸢尾花数据是四维的,共三类样本。要求使用PCA算法对鸢尾花数据进行降维,并实现二维平面上的可视化。
代码实现:
python
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA # 导入PCA模块
from sklearn.datasets import load_iris # 导入鸢尾花数据集模块
# 加载数据
data = load_iris() # 以字典形式加载鸢尾花数据集
X = data.data # 使用X表示数据集中的属性数据
y = data.target # 使用y表示数据集中的标签
# 使用PCA算法进行数据降维
pca = PCA(n_components=2) # 创建PCA对象,设置降维后主成分个数为2
reduced_X = pca.fit_transform(X) # 对原始数据进行降维,降维后数据保存在reduced_X中
# 按类别对降维后的数据进行保存
red_x, red_y = [], [] # 第一类数据点
green_x, green_y = [], [] # 第二类数据点
blue_x, blue_y = [], [] # 第三类数据点
for i in range(len(reduced_X)): # 按照鸢尾花的类别将降维后的数据点保存在不同的列表中
if y[i] == 0:
red_x.append(reduced_X[i][0])
red_y.append(reduced_X[i][1])
elif y[i] == 1:
green_x.append(reduced_X[i][0])
green_y.append(reduced_X[i][1])
else:
blue_x.append(reduced_X[i][0])
blue_y.append(reduced_X[i][1])
# 降维后数据点的可视化
plt.scatter(red_x, red_y, c='r', marker='x')
plt.scatter(green_x, green_y, c='g', marker='D')
plt.scatter(blue_x, blue_y, c='b', marker='.')
plt.show()
更详细的代码实现:
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
# 数据标准化
# PCA算法对数据的尺度敏感,因此在应用PCA之前,需要对数据进行标准化处理,使得每个特征的均值为0,方差为1
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0) # 标准化公式:(样本数据 - 样本均值) / 样本标准差
# 计算协方差矩阵
cov_matrix = np.cov(X.T)
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
# 选择主成分
explained_variance_ratio = eigenvalues / np.sum(eigenvalues)
# 降维
n_components = 2 # 选择降维后的维数
top_eigenvectors = eigenvectors[:, :n_components]
X_pca = X.dot(top_eigenvectors)
# 按类别对降维后的数据进行保存
red_x, red_y = [], [] # 第一类数据点
green_x, green_y = [], [] # 第二类数据点
blue_x, blue_y = [], [] # 第三类数据点
for i in range(len(X_pca)): # 按照鸢尾花的类别将降维后的数据点保存在不同的列表中
if y[i] == 0:
red_x.append(X_pca[i][0])
red_y.append(X_pca[i][1])
elif y[i] == 1:
green_x.append(X_pca[i][0])
green_y.append(X_pca[i][1])
else:
blue_x.append(X_pca[i][0])
blue_y.append(X_pca[i][1])
# 降维后数据点的可视化
plt.scatter(red_x, red_y, c='r', marker='x')
plt.scatter(green_x, green_y, c='g', marker='D')
plt.scatter(blue_x, blue_y, c='b', marker='.')
plt.show()