目录
一、简介
主成分分析(Principal Component Analysis,PCA)是一种常用的统计方法,它可以通过线性变换将原始数据变换为一组各维度线性无关的表示,通常用于降维和数据的预处理。
二、PCA
2.1 概念
PCA的目的是从原始数据中提取出最重要的特征,通过这些特征来简化数据的复杂性,同时尽可能保留原始数据的信息。主成分是原始变量的线性组合,它们按照方差大小排序,第一主成分解释了数据中最大的方差,第二主成分解释了次大的方差,以此类推。每个主成分都是原始数据的一个新的特征轴,这些轴彼此正交,意味着它们之间的相关性为零。
2.2 数据中心化
对于原始数据集 XX 中的每个属性 jj,计算其平均值 并从每个属性中减去该平均值,以实现数据中心化。对于数据集中的每个样本 (其中 i = 1, 2, ..., ni=1,2,...,n 表示样本数量),属性(其中 j = 1, 2, ..., pj=1,2,...,p 表示属性数量)的数据中心化可以通过以下公式表示:
其中 是数据中心化后的值, 是原始值, 是属性的平均值。
2.3 计算协方差矩阵
协方差矩阵 可以通过以下公式计算:
其中 XX 是数据中心化后的数据矩阵, 是 的转置。
2.4 特征分解
对协方差矩阵 进行特征分解,得到特征值 和特征向量 :
特征向量 vv 表示主成分的方向,特征值 表示在该方向上数据的方差大小。
2.5 选择主成分
根据特征值的大小,选择前 个最大的特征值对应的特征向量作为主成分。这些特征向量构成了新的特征空间。
2.6 构造新的数据表示
将数据中心化后的数据投影到选定的主成分上,得到降维后的数据表示 :
其中 是选取的前 个特征向量组成的矩阵。
三、代码实现
3.1 总代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn .datasets import make_blobs
from sklearn.decomposition import PCA
def create_data(num_samples=100, num_features=2, centers=2, random_state=42):
X, y = make_blobs(n_samples=num_samples, n_features=num_features, centers=centers, random_state=random_state)
return X, y
def show_data(X, y):
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
def visualize_svm(X, y, svm):
def get_hyperplane_value(x, w, b, offset):
return (-w[0] * x + b + offset) / w[1]
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
x = np.linspace(xlim[0], xlim[1], 30)
y_pred = get_hyperplane_value(x, svm.w, svm.b, 0)
margin_plus = get_hyperplane_value(x, svm.w, svm.b, 1)
margin_minus = get_hyperplane_value(x, svm.w, svm.b, -1)
plt.plot(x, y_pred, 'k-')
plt.plot(x, margin_plus, 'k--')
plt.plot(x, margin_minus, 'k--')
plt.legend()
plt.show()
class SVM:
def __init__(self, lr=0.001, lambda_param=0.01, num_step=1000):
'''
:param lr: 学习率
:param lambda_param: 正则化参数
:param num_step: 步数
'''
self.lr = lr
self.lambda_param = lambda_param
self.num_step = num_step
self.w = None
self.b = None
def fit(self, X, y):
#初始化权重和偏置
num_samples, num_features = X.shape
self.w = np.zeros(num_features)
self.b = 0
#将标签从 0/1 转换为 -1/1。SVM 要求标签为 -1 和 1。
y_ = np.where(y <= 0, -1, 1)
#梯度下降
for _ in range(self.num_step):
for idx, x_i in enumerate(X):
#检查样本是否满足分类条件,更新权重和偏置
if y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1:
self.w -= self.lr * (2 * self.lambda_param * self.w)
else:
self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))
self.b -= self.lr * y_[idx]
def predict(self, X):
pred = np.dot(X, self.w) + self.b
return np.sign(pred)
X, y = create_data(num_features=10)
y = np.where(y==0, -1, 1)
print(X.shape)
pca = PCA(n_components=2)
X = pca.fit_transform(X)
show_data(X, y)
svm = SVM()
svm.fit(X, y)
visualize_svm(X, y, svm)
3.2 实现图像
四、优缺点分析
4.1 优点
-
数据降维:PCA能够将高维数据集转换为低维数据集,这有助于简化数据,减少计算量和存储需求。
-
去除多重共线性:在多变量分析中,变量之间可能存在多重共线性问题,PCA通过提取主成分来减少变量间的相关性。
-
信息保留:PCA能够保留数据中的大部分重要信息,因为它是根据数据本身的方差来选择主成分的。
-
无需监督学习:PCA是一种无监督学习技术,不需要类别标签,适用于无法获得标签信息的数据。
-
易于解释:主成分是原始变量的线性组合,这使得每个主成分都有实际意义,可以解释为数据中的主要变化方向。
-
易于实现:PCA的算法相对简单,易于实现,并且有现成的库和工具可以快速应用。
4.2 缺点
-
线性假设:PCA假设数据的主要结构是线性的,如果数据中存在非线性关系,PCA可能无法有效地提取特征。
-
对噪声敏感:PCA试图最大化数据方差,这可能导致它对噪声敏感,特别是在噪声方差较大的情况下。
-
信息损失:虽然PCA试图保留大部分信息,但在降维过程中总会有一定程度的信息损失,尤其是在维数减少很多的情况下。
-
特征解释:当主成分是原始变量的复杂组合时,主成分的解释可能变得困难,这降低了PCA的可解释性。
-
计算成本:对于大规模数据集,计算协方差矩阵和进行特征分解的计算成本可能很高。
-
数据标准化:PCA对数据的尺度非常敏感,因此在应用PCA之前需要进行数据标准化,这可能会引入额外的复杂性。
五、总结
主成分分析(PCA)是一种常用的统计方法,它通过线性变换将原始数据转换为一组各维度线性无关的表示,用于降维和数据的预处理。PCA的工作原理是通过计算数据中心化后属性的协方差矩阵,进行特征分解,选择最重要的特征向量作为主成分,并将原始数据投影到这些主成分上形成新的数据集。PCA的主要优点包括数据降维、去除多重共线性、信息保留、无需监督学习、易于解释和易于实现。然而,PCA也存在一些缺点,如线性假设、对噪声敏感、信息损失、特征解释困难、计算成本高和对数据标准化的需求。在应用PCA时,需要注意其适用条件,PCA是一种线性降维技术,可能不适用于非线性数据结构。