手撕 PCA 算法的代码时,我们可以按照以下步骤实现:
-
计算数据的均值向量:对每个特征列求平均值,得到一个均值向量。
-
数据标准化:将每个特征列减去对应的均值,得到零均值的数据。
-
计算协方差矩阵:将标准化后的数据进行协方差矩阵的计算。
-
计算特征值和特征向量:对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。
-
选择主成分:根据特征值的大小,选择前 k 个特征向量作为主成分,其中 k 是期望的降维维度。
-
数据投影:将标准化后的数据投影到选定的主成分上,得到降维后的数据。
下面是一个简单的手撕 PCA 算法的代码示例:
import numpy as np
def pca(X, k):
# 1. 计算均值向量
mean_vec = np.mean(X, axis=0)
# 2. 数据标准化
X_std = X - mean_vec
# 3. 计算协方差矩阵
cov_matrix = np.cov(X_std, rowvar=False)
# 4. 计算特征值和特征向量
eig_vals, eig_vecs = np.linalg.eig(cov_matrix)
# 5. 选择主成分
eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]
eig_pairs.sort(key=lambda x: x[0], reverse=True)
eig_vecs_selected = np.array([eig_pair[1] for eig_pair in eig_pairs[:k]])
# 6. 数据投影
X_pca = np.dot(X_std, eig_vecs_selected.T)
return X_pca
# 准备土壤样本数据
X = np.array([[6.5, 2.1, 10.3],
[7.2, 1.8, 9.5],
[5.8, 2.5, 11.2],
[6.9, 2.3, 10.6],
[6.1, 1.9, 9.8]])
# 指定降维维度
k = 1
# 应用 PCA 算法进行降维
X_pca = pca(X, k)
# 打印降维后的结果
print(X_pca)
运行以上代码,将得到 PCA 算法进行降维后的结果。
输出结果如下:
[[-0.00902328]
[ 1.08874048]
[-1.21619374]
[-0.08610633]
[ 0.22258288]]
可以看到,得到了降维后的结果 X_pca
,其中只保留了一列数据,即降至一维。这样就实现了简单的 PCA 算法的手撕代码。
数据投影
在主成分分析 (PCA) 中,数据投影是将原始数据映射到选定的主成分上,从而实现降维的过程。数据投影的目的是保留尽可能多的原始数据信息,同时减少数据的维度。
数据投影的过程可以通过矩阵乘法来实现。假设我们有一个标准化后的数据集 X,其中每一行表示一个样本,每一列表示一个特征。假设我们已经计算得到了主成分的特征向量组成的矩阵 V,其中每一列对应一个主成分。我们可以将数据集 X 与矩阵 V 进行乘法运算,得到投影后的数据集 Y。
下面是使用 NumPy 实现数据投影的示例代码:
import numpy as np
# 假设有一个标准化后的数据集 X
X = np.array([[1.2, 2.3, 4.5],
[3.4, 1.9, 2.7],
[2.1, 4.6, 3.2]])
# 假设已经计算得到主成分的特征向量组成的矩阵 V
V = np.array([[0.5, -0.2],
[-0.3, 0.8],
[0.2, 0.5]])
# 将数据集 X 投影到主成分上,得到降维后的数据集 Y
Y = np.dot(X, V)
# 输出降维后的数据集 Y
print(Y)
运行以上代码,将得到数据集 X 投影到主成分上得到的降维后的数据集 Y 的结果。
在以上示例中,原始数据集 X 是一个3x3的矩阵,主成分的特征向量矩阵 V 是一个3x2的矩阵。通过矩阵乘法运算 np.dot(X, V)
,将数据集 X 投影到主成分上,得到一个降维后的2维数据集 Y。每一行表示一个样本的投影结果,每一列表示一个主成分的投影结果。
注意,在进行数据投影前,需要对原始数据进行标准化处理,以确保各个特征具有相同的尺度。这有助于保持主成分分析的准确性和稳定性。
方差贡献率
如果你只关注方差贡献率最大的主成分,你可以选择不进行降维,而直接保留原始数据。如果你只选择方差贡献率最大的主成分进行投影,那么投影后的数据将丢失其他主成分所包含的信息。
在主成分分析中,方差贡献率是指每个主成分所解释的总方差的比例。通常,方差贡献率较大的主成分包含了原始数据中的大部分信息,而方差贡献率较小的主成分所解释的信息量较少。
如果你认为方差贡献率最大的主成分已经包含了足够的信息,你可以选择不进行降维,而直接使用原始数据。这样可以避免信息丢失,但可能会导致数据维度较高,增加计算复杂度和存储需求。
方差贡献率(Variance Contribution Rate)和累计贡献率(Cumulative Contribution Rate)是主成分分析中用来评估主成分重要性的指标。
方差贡献率指的是每个主成分所解释的数据方差的比例。它衡量了该主成分对总体方差的贡献程度,值越大表示该主成分包含的信息量越多。方差贡献率的计算公式为:
方差贡献率 = (特征值 / 总特征值) * 100%
其中,特征值表示主成分分析过程中得到的特征值(数据方差)列表,总特征值表示所有特征值的总和。
累计贡献率指的是前 k 个主成分的方差贡献率之和。它衡量了前 k 个主成分所解释的总方差的比例,可以用来确定保留多少个主成分。累计贡献率的计算公式为:
累计贡献率 = Σ(方差贡献率)
其中,Σ表示累计求和操作。累计贡献率通常以折线图的形式展示,可以通过观察图形来确定保留多少个主成分。
以下是一个示例,演示如何计算方差贡献率和累计贡献率:
import numpy as np
# 假设有一组特征值列表
eigenvalues = [5.2, 3.8, 2.6, 1.9, 1.4]
# 计算总特征值
total_eigenvalue = np.sum(eigenvalues)
# 计算方差贡献率
variance_contribution = [(eig / total_eigenvalue) * 100 for eig in eigenvalues]
# 计算累计贡献率
cumulative_contribution = np.cumsum(variance_contribution)
# 输出方差贡献率和累计贡献率
for i in range(len(eigenvalues)):
print(f"主成分 {i+1}: 方差贡献率 = {variance_contribution[i]:.2f}%, 累计贡献率 = {cumulative_contribution[i]:.2f}%")
在以上示例中,假设给定了一组特征值列表 eigenvalues
,通过计算总特征值 total_eigenvalue
,然后使用列表推导式计算了方差贡献率 variance_contribution
和累计贡献率 cumulative_contribution
。最后通过循环输出了每个主成分的方差贡献率和累计贡献率。
请注意,方差贡献率和累
计贡献率是用于评估主成分的重要性和确定保留的主成分数量,通常用于帮助决策者进行降维操作。
举例-方差贡献率-sklearn
假设我们有一组土壤样本数据,包含了pH值、有机质含量和养分含量三个指标。我们希望通过主成分分析(PCA)来评估土壤的综合质量状况。
首先,我们需要准备土壤样本数据集,其中每个样本都包含了pH值、有机质含量和养分含量这三个指标的数值。
示例数据集如下:
样本编号 pH值 有机质含量 养分含量
1 6.5 2.1 10.3
2 7.2 1.8 9.5
3 5.8 2.5 11.2
4 6.9 2.3 10.6
5 6.1 1.9 9.8
接下来,我们可以使用Python中的机器学习库(如scikit-learn)来进行主成分分析。
from sklearn.decomposition import PCA
# 准备土壤样本数据
X = [[6.5, 2.1, 10.3],
[7.2, 1.8, 9.5],
[5.8, 2.5, 11.2],
[6.9, 2.3, 10.6],
[6.1, 1.9, 9.8]]
# 创建PCA对象并拟合数据
pca = PCA()
pca.fit(X)
# 获取主成分的方差贡献率和累计贡献率
variance_ratio = pca.explained_variance_ratio_
cumulative_variance_ratio = np.cumsum(variance_ratio)
# 打印主成分的方差贡献率和累计贡献率
print("主成分的方差贡献率:", variance_ratio)
print("主成分的累计贡献率:", cumulative_variance_ratio)
运行以上代码,可以得到主成分的方差贡献率和累计贡献率。
输出结果如下:
主成分的方差贡献率: [7.96698450e-01 2.02971106e-01 3.30443966e-04]
主成分的累计贡献率: [0.79669845 0.99966956 1. ]
从方差贡献率和累计贡献率可以看出,第一个主成分解释了大约79.96%的数据方差,第二个主成分解释了大约20.29%的数据方差,而第三个主成分只解释了不到1%的数据方差。
通过主成分的方差贡献率和累计贡献率,可以评估每个主成分对于描述土壤样本数据的重要性。一般来说,我们会选择方差贡献率较高的主成分作为重要特征进行分析和评估。