PCA 中特征重要性的度量

Posted

技术标签:

【中文标题】PCA 中特征重要性的度量【英文标题】:Measure of Feature Importance in PCA 【发布时间】:2021-07-15 21:15:40 【问题描述】:

我正在做主成分分析 (PCA),我想找出对结果贡献最大的特征。

我的直觉是总结特征对单个组件的单个贡献的所有绝对值。

import numpy as np
from sklearn.decomposition import PCA

X = np.array([[-1, -1, 4, 1], [-2, -1, 4, 2], [-3, -2, 4, 3], [1, 1, 4, 4], [2, 1, 4, 5], [3, 2, 4, 6]])
pca = PCA(n_components=0.95, whiten=True, svd_solver='full').fit(X)
pca.components_
array([[ 0.71417303,  0.46711713,  0.        ,  0.52130459],
       [-0.46602418, -0.23839061, -0.        ,  0.85205128]])
np.sum(np.abs(pca.components_), axis=0)
array([1.18019721, 0.70550774, 0.        , 1.37335586])

在我看来,这可以衡量每个原始特征的重要性。请注意,第三个特征的重要性为零,因为我故意创建了一个只是常量值的列。

PCA 是否有更好的“重要性衡量标准”?

【问题讨论】:

据我了解,PCA 组件是按照它们解释数据差异的程度排序的。因此,如果您的预测取决于特征的方差,则使用前几个组件就足够了。我不认为总结这些值表明您的功能的重要性。 这可能就是你要找的Feature/Variable importance after a PCA analysis 【参考方案1】:

PCA 的重要性度量在explained_variance_ratio_ 中。该数组提供了每个组件解释的方差百分比。它按组件的重要性降序排序,当所有组件都被使用时,总和为 1,或者超过请求阈值的最小可能值。在您的示例中,您将阈值设置为 95%(应解释的方差),因此数组总和将为 0.9949522861608583,因为第一个组件解释了 92.021143% 和第二个 7.474085% 的方差,因此您收到了 2 个组件。

components_ 是存储特征空间中最大方差的方向的数组。它的尺寸是n_components_ n_features_。这是您在应用transform() 时将数据点乘以得到数据的降维投影。

更新

为了获得原始特征对每个主成分的贡献百分比,您只需对components_ 进行归一化,因为它们设置了原始向量对投影的贡献量。

r = np.abs(pca.components_.T)
r/r.sum(axis=0)

array([[0.41946155, 0.29941172],
       [0.27435603, 0.15316146],
       [0.        , 0.        ],
       [0.30618242, 0.54742682]])

如您所见,第三个功能对 PC 没有帮助。

如果您需要原始特征对解释方差的总贡献,则需要考虑每个 PC 贡献(即explained_variance_ratio_):

ev = np.abs(pca.components_.T).dot(pca.explained_variance_ratio_)
ttl_ev = pca.explained_variance_ratio_.sum()*ev/ev.sum()
print(ttl_ev)

[0.40908847 0.26463667 0.         0.32122715]

【讨论】:

有帮助!也欣赏这个实际的例子。 感谢您的回答,但这不是我想要的。我对主要成分的重要性不感兴趣。我对构成主要组件的各个特征的重要性感兴趣。【参考方案2】:

如果您只是单纯地将 PC 与 np.sum(np.abs(pca.components_), axis=0) 相加,则假定所有 PC 都同等重要,这很少是真的。要使用 PCA 进行粗略的特征选择,请在丢弃低贡献的 PC 后和/或按其相对贡献缩放 PC 后求和。

这是一个直观的示例,突出显示了为什么简单的总和不能按预期工作。

给定 20 个特征的 3 个观察值(可视化为三个 5x4 热图):

>>> print(X.T)
[[2 1 1 1 1 1 1 1 1 4 1 1 1 4 1 1 1 1 1 2]
 [1 1 1 1 1 1 1 1 1 4 1 1 1 6 3 1 1 1 1 2]
 [1 1 1 2 1 1 1 1 1 5 2 1 1 5 1 1 1 1 1 2]]

这些是生成的 PC:

>>> pca = PCA(n_components=None, whiten=True, svd_solver='full').fit(X.T)

请注意,PC3 在(2,1) 处的震级很高,但如果我们检查它的解释方差,它的贡献约为 0:

>>> print(pca.explained_variance_ratio_)
array([0.6638886943392722, 0.3361113056607279, 2.2971091700327738e-32])

这会导致在对未缩放的 PC 求和(左)与对按其解释的方差比缩放的 PC 求和(右)时出现特征选择差异:

>>> unscaled = np.sum(np.abs(pca.components_), axis=0)
>>> scaled = np.sum(pca.explained_variance_ratio_[:, None] * np.abs(pca.components_), axis=0)

使用未缩放的总和(左),无意义的 PC3 仍被赋予 33% 的权重。这导致(2,1) 被认为是最重要的特征,但如果我们回顾原始数据,(2,1) 提供的观测值区分度很低。

使用比例和(右),PC1 和 PC2 分别有 66% 和 33% 的权重。现在(3,1)(3,2) 是最重要的特征,它们实际上与原始数据进行了跟踪。

【讨论】:

以上是关于PCA 中特征重要性的度量的主要内容,如果未能解决你的问题,请参考以下文章

随机森林进行特征重要性度量的详细说明

PCA 恢复数据帧中最重要的特征

特征工程之特征选择----降维算法PCA重要参数

PCA 后的最优特征选择技术?

如何在 sklearn:: LGBMClassifier() 中为 LightGBM 分类器的 feature_importances_ 中设置“增益”作为特征重要性度量

PCA算法