学术, 机器学习

主成分分析PCA的原理以及降维实现

主成分分析(Principal Component Analysis, PCA)是一种常用的数据降维方法。主要思想:因为数据的大部分变化都包含在具有较大方差的方向上,所以选择这些方向能够最大程度地保留数据的结构和特征。选择最大方差的主成分意味着我们可以用较少的特征来表示原始数据,从而实现降维。

PCA的原理和步骤(具体的数学公式这里不给出):

  1. 计算协方差矩阵:PCA 通过计算特征之间的协方差来找到数据中的主要方向。
  2. 计算特征值和特征向量:对协方差矩阵进行特征值分解,其中特征值表示了数据中的方差,而特征向量则表示了数据的主要方向。
  3. 选择主成分和投影:将原始数据投影到所选的主成分上,得到新的低维表示,其中投影过程就是将原始数据与每个主成分进行内积。

在Python中,可以使用 sklearn 库中的 PCA 类来实现。官方文档为:https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html

示例代码如下:

"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/39020
"""

import numpy as np
from sklearn.decomposition import PCA

# 创建一个人造数据集,包含10个样本,每个样本有4个特征
X = np.array([[2, 1, 3, 4],
              [3, 5, 2, 8],
              [4, 3, 6, 5],
              [6, 7, 3, 9],
              [5, 4, 7, 6],
              [7, 8, 5, 10],
              [8, 6, 9, 7],
              [9, 10, 6, 11],
              [10, 8, 11, 8],
              [11, 12, 8, 12]])

# 测试一

pca = PCA()  # 创建PCA对象,保留所有主成分
X_transformed = pca.fit_transform(X)  # 对数据进行PCA变换

# 输出原始数据和变换后的数据
print("Original Data:")
print(X)
print(X.shape)
print("\nTransformed Data:")
print(X_transformed)
print(X_transformed.shape)

# 输出各个主成分所解释的方差比例
print("\nExplained Variance Ratio:")
print(pca.explained_variance_ratio_)

print('\n---\n')

# 测试二

pca = PCA(n_components=2)  # 创建PCA对象,保留前2个主成分
X_transformed = pca.fit_transform(X)  # 对数据进行PCA变换

# 输出原始数据和变换后的数据
print("Original Data:")
print(X)
print(X.shape)
print("\nTransformed Data:")
print(X_transformed)
print(X_transformed.shape)

# 输出各个主成分所解释的方差比例
print("\nExplained Variance Ratio:")
print(pca.explained_variance_ratio_)

运行结果:

Original Data:
[[ 2  1  3  4]
 [ 3  5  2  8]
 [ 4  3  6  5]
 [ 6  7  3  9]
 [ 5  4  7  6]
 [ 7  8  5 10]
 [ 8  6  9  7]
 [ 9 10  6 11]
 [10  8 11  8]
 [11 12  8 12]]
(10, 4)

Transformed Data:
[[ 8.60996003e+00  2.12090562e-01  4.83309097e-01 -4.26318534e-03]
 [ 4.21693342e+00 -3.48363328e+00 -5.36026982e-01 -6.66846297e-02]
 [ 4.79257814e+00  1.94798475e+00 -1.40188957e-01 -1.64003729e-01]
 [ 5.12940611e-01 -3.16929056e+00  5.49779860e-01 -1.52117788e-02]
91849e-01  2.05779667e-02]
 [-4.68094412e+00  4.23031713e+00  3.17243827e-02 -4.66122158e-02]
 [-8.39111057e+00 -1.08154491e+00 -2.94007140e-02 -1.69291494e-01]]
(10, 4)

Explained Variance Ratio:
[7.75856885e-01 2.20117503e-01 3.56498848e-03 4.60623724e-04]

---

Original Data:
[[ 2  1  3  4]
 [ 3  5  2  8]
 [ 4  3  6  5]
 [ 6  7  3  9]
 [ 5  4  7  6]
 [ 7  8  5 10]
 [ 8  6  9  7]
 [ 9 10  6 11]
 [10  8 11  8]
 [11 12  8 12]]
(10, 4)

Transformed Data:
[[ 8.60996003  0.21209056]
 [ 4.21693342 -3.48363328]
 [ 4.79257814  1.94798475]
 [ 0.51294061 -3.16929056]
 [ 2.84043058  2.18008023]
 [-1.78063703 -2.12912598]
 [-1.20499231  3.30249205]
 [-4.91515876 -2.00937   ]
 [-4.68094412  4.23031713]
 [-8.39111057 -1.08154491]]
(10, 2)

Explained Variance Ratio:
[0.77585688 0.2201175 ]

在进行主成分分析(PCA)之前,通常建议对数据进行标准化处理,原因如下:

  • 特征尺度的差异:如果原始数据中不同特征的尺度差异很大(例如一个特征的取值范围是0到1,另一个特征的取值范围是0到1000),那么PCA在计算协方差矩阵时,将会给予数值较大的那些特征更大的权重。这可能导致主成分主要捕获了那些数值较大特征的变化,而忽略了其他特征的信息。
  • 数值稳定性:标准化可以提高PCA计算的数值稳定性。如果原始数据中存在异常值或离群点,那么它们会对协方差矩阵的计算产生很大影响,从而影响主成分的计算结果。标准化或归一化可以减轻异常值的影响。

在某些特殊情况下,如果你已经确保数据的尺度差异不大,或者你希望保留原始数据的分布形状,那么可以选择不进行标准化或归一化。对于主成分分析来说,最常用的标准化方法是使用 StandardScaler 进行标准正态化,官方文档为:https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html

示例代码如下(代码和前面的差不多,只是增加了数据标准化的内容):

"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/39020
"""

import numpy as np
from sklearn.decomposition import PCA

# 创建一个人造数据集,包含10个样本,每个样本有4个特征
X = np.array([[2, 1, 3, 4],
              [3, 5, 2, 8],
              [4, 3, 6, 5],
              [6, 7, 3, 9],
              [5, 4, 7, 6],
              [7, 8, 5, 10],
              [8, 6, 9, 7],
              [9, 10, 6, 11],
              [10, 8, 11, 8],
              [11, 12, 8, 12]])

# 测试一

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()  # 创建StandardScaler对象
X_scaled = scaler.fit_transform(X)  # 对原始数据X进行标准化

pca = PCA() # 创建PCA对象,保留所有主成分
X_transformed = pca.fit_transform(X_scaled) # 对数据进行PCA变换

# 输出原始数据和变换后的数据
print("Original Data:")
print(X)
print(X.shape)
print("\nTransformed Data:")
print(X_transformed)
print(X_transformed.shape)

# 输出各个主成分所解释的方差比例
print("\nExplained Variance Ratio:")
print(pca.explained_variance_ratio_)

print('\n---\n')

# 测试二

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()  # 创建StandardScaler对象
X_scaled = scaler.fit_transform(X)  # 对原始数据X进行标准化

pca = PCA(n_components=2)  # 创建PCA对象,保留前2个主成分
X_transformed = pca.fit_transform(X_scaled)  # 对数据进行PCA变换

# 输出原始数据和变换后的数据
print("Original Data:")
print(X)
print(X.shape)
print("\nTransformed Data:")
print(X_transformed)
print(X_transformed.shape)

# 输出各个主成分所解释的方差比例
print("\nExplained Variance Ratio:")
print(pca.explained_variance_ratio_)

运行结果:

Original Data:
[[ 2  1  3  4]
 [ 3  5  2  8]
 [ 4  3  6  5]
 [ 6  7  3  9]
 [ 5  4  7  6]
 [ 7  8  5 10]
 [ 8  6  9  7]
 [ 9 10  6 11]
 [10  8 11  8]
 [11 12  8 12]]
(10, 4)

Transformed Data:
[[ 3.04399644e+00  6.66466960e-02  1.74600648e-01  1.21241701e-03]  
 [ 1.45187335e+00 -1.30409405e+00 -1.92134468e-01 -2.61626892e-02]  
 [ 1.70479059e+00  7.21578572e-01 -4.52877553e-02 -5.77489458e-02]  
 [ 1.76156297e-01 -1.17407594e+00  2.00693088e-01 -2.86517435e-03]  
 [ 9.97956050e-01  7.98834801e-01 -1.59537624e-01  1.97321412e-02]  
 [-6.60285646e-01 -8.00955443e-01 -8.88669841e-02  8.28452600e-02]  
 [-4.07368404e-01  1.22471718e+00  5.79797283e-02  5.12590033e-02]  
 [-1.74027669e+00 -7.37752105e-01  4.18650192e-02  7.42520241e-03]  
 [-1.61696685e+00  1.58378479e+00  1.34015282e-02 -1.59317068e-02]  
 [-2.94987513e+00 -3.78684497e-01 -2.71318084e-03 -5.97655078e-02]] 
(10, 4)

Explained Variance Ratio:
[7.56348575e-01 2.39497155e-01 3.70951555e-03 4.44753874e-04]       

---

Original Data:
[[ 2  1  3  4]
 [ 3  5  2  8]
 [ 4  3  6  5]
 [ 6  7  3  9]
 [ 5  4  7  6]
 [ 7  8  5 10]
 [ 8  6  9  7]
 [ 9 10  6 11]
 [10  8 11  8]
 [11 12  8 12]]
(10, 4)

Transformed Data:
[[ 3.04399644  0.0666467 ]
 [ 1.45187335 -1.30409405]
 [ 1.70479059  0.72157857]
 [ 0.1761563  -1.17407594]
 [ 0.99795605  0.7988348 ]
 [-0.66028565 -0.80095544]
 [-0.4073684   1.22471718]
 [-1.74027669 -0.7377521 ]
 [-1.61696685  1.58378479]
 [-2.94987513 -0.3786845 ]]
(10, 2)

Explained Variance Ratio:
[0.75634858 0.23949716]
313 次浏览

【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code