主成分分析(PCA)的数学原理与Python实现

主成分分析(PCA)是一种常用的数据降维技术,特别适用于线性数据集。它是一种非参数化且简单的方法,却能产生强大的结果。本文将探讨PCA的数学基础,并提供从零开始的Python实现。

理解PCA之前需要了解的几个概念

在深入讨论PCA之前,需要先了解以下几个概念:

协方差(Covariance):协方差用于描述两个变量之间的关系。如果协方差为正,则两个变量倾向于朝相同方向变化;如果协方差为负,则两个变量倾向于朝相反方向变化;如果协方差为0,则表明两个属性之间不存在关系。

方差(Variance):方差表示数据的离散程度,即数据值与均值的距离。

PCA的基本步骤

PCA的基本步骤可以总结如下,将详细探讨这些步骤:

  • 数据标准化
  • 计算协方差矩阵
  • 计算特征向量和特征值
  • 选择主成分的数量
  • 将主成分与原始数据相乘,创建新的转换数据集

创建一个简单的数据示例

import pandas as pd import numpy as np import matplotlib.pyplot as plt data = np.array([[1000 ,500],[2000, 800],[3000 ,1100],[4000 ,1500],[5000 ,1800],[8000,1900]]) df = pd.DataFrame(data,columns = ['Salary','Expense'])

接下来,将使用散点图来检查数据的分布并可视化相关性。

import seaborn as sns plot = sns.lmplot(x='Salary', y='Expense', data=df, ci=None) plt.title("Salary vs Expense")

协方差矩阵的计算

由于数据中有两个属性,即工资和支出,因此协方差矩阵的形状将是2×2。请注意下面的协方差和方差的公式。如果x和y相同,则它将为同一属性产生方差。因此,在上述协方差矩阵中,对角线元素将产生工资和支出的方差。此外,协方差的一个属性是它是对称的,即协方差(x,y) = 协方差(y,x),这告诉协方差(工资,支出) = 协方差(支出,工资)。

特征向量和特征值:PCA背后的魔法师

这些术语听起来相当复杂,但并不难理解。这些术语在PCA中扮演着最重要的角色。

特征向量(Eigenvector):特征向量是一个非零向量,当受到线性变换时,只改变大小而不改变方向。这意味着如果将一个非零向量与上述协方差矩阵相乘,结果将是初始向量的缩放版本,而该缩放值就是特征值。

数学上,当一个特征向量与一个向量相乘时,将给出特征向量和一个标量值的乘积。

A * v = lambda * v

其中A是任何矩阵,v是特征向量,lambda是特征值。

数据标准化对PCA至关重要

import warnings warnings.filterwarnings('ignore') from sklearn.preprocessing import StandardScaler ss = StandardScaler() scaled = ss.fit_transform(data) scaled

现在已经得到了标准化后的数据,接下来将计算协方差矩阵并计算特征值和特征向量。

from numpy import linalg cov = np.cov(scaled[:,0], scaled[:,1]) val, vec = linalg.eig(cov) print("Below we have eigenvectors from the covariance matrix") print(vec) print("Eigen Values for corresponding eigenvector") print(val)

现在有了特征值和对应的特征向量。特征向量矩阵的不同列表示不同的特征向量。将选择与最高特征值对应的特征向量,这是第一个主成分。

每个成分解释的方差

var_exp_1 = print('Total variance explained by first principal component is',round(val[0]/val.sum(),2)) var_exp_2 = print('Total variance explained by second principal component is',round(val[1]/val.sum(),2))

当选择了一定数量的特征向量(具有较大特征值)并形成一个由这些向量组成的矩阵时,这个矩阵被称为特征向量。

需要注意的重要一点是,主成分是不相关的,因为它们是正交的,即它们是相互垂直的。

final_data = np.dot(scaled, np.array(vec.T[0])) print(final_data) from sklearn.decomposition import PCA pca = PCA(n_components=1) pca.fit(scaled) print("Variance explained by principal component is", pca.explained_variance_ratio_) print("Final output after PCA", pca.transform(scaled)[:,0])
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485