使用sklearn在PCA中恢复解释名称_variance_ratio_的特征名称


77

我正在尝试从使用scikit-learn完成的PCA中恢复,这些功能被选择为相关

IRIS数据集的经典示例。

import pandas as pd
import pylab as pl
from sklearn import datasets
from sklearn.decomposition import PCA

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
df_norm = (df - df.mean()) / df.std()

# PCA
pca = PCA(n_components=2)
pca.fit_transform(df_norm.values)
print pca.explained_variance_ratio_

这返回

In [42]: pca.explained_variance_ratio_
Out[42]: array([ 0.72770452,  0.23030523])

如何恢复数据集中哪两个特征允许这两个已解释的方差? 换句话说,我如何在iris.feature_names中获取此功能的索引?

In [47]: print iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

在此先感谢您的帮助。


4
pca.components_是您要寻找的。
exAres

如果要single most important feature name在特定的PC上(或在所有PC上)使用该功能,请在此页末尾看到我的答案。
seralouk

Answers:


85

此信息包含在pca属性中:components_。如文档中所述,pca.components_输出一个数组[n_components, n_features],因此要了解组件如何与不同功能线性相关,您必须:

注意:每个系数代表特定的一对零件和特征之间的相关性

import pandas as pd
import pylab as pl
from sklearn import datasets
from sklearn.decomposition import PCA

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
from sklearn import preprocessing
data_scaled = pd.DataFrame(preprocessing.scale(df),columns = df.columns) 

# PCA
pca = PCA(n_components=2)
pca.fit_transform(data_scaled)

# Dump components relations with features:
print(pd.DataFrame(pca.components_,columns=data_scaled.columns,index = ['PC-1','PC-2']))

      sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)
PC-1           0.522372         -0.263355           0.581254          0.565611
PC-2          -0.372318         -0.925556          -0.021095         -0.065416

重要提示:作为附带说明,请注意PCA符号不会影响其解释,因为该符号不会影响每个组件中包含的差异。仅形成PCA尺寸的特征的相对符号很重要。实际上,如果再次运行PCA代码,则PCA尺寸可能会与符号相反。对此有一个直观的认识,请考虑一个向量及其在3-D空间中的负数-两者本质上都表示空间中的相同方向。检查此帖子以获取更多参考。


组件实际上是功能的组合,因此任何特定的功能(在某种程度上)都与不同的组件相关....
Rafa

3
因此,说您想知道哪个原始功能最重要,您是否应该对绝对值求和?我的意思是,从答案的最后一行开始:pd.DataFrame(pca.components_,columns = data_scaled.columns,index = ['PC-1','PC-2'])。abs()。sum (轴= 0),结果为:0.894690 1.188911 0.602349 0.631027。我们能否在此说出隔片的宽度最重要,其次是隔片的长度?
Guido

10
要了解哪些功能很重要,您需要注意相关性。例如,由于相关系数为-0.92,因此萼片宽度与PC-2高度相关(成反比)。另一方面,由于corr coef为-0.02,所以花瓣长度和PC-2根本不相关。因此,PC-2随着萼片宽度的减小而增长,而PC-2与花瓣长度的变化无关。也就是说,对于PC-2,萼片宽度很重要,而花瓣长度并不重要。考虑相关系数在区间[-1,1]中,您可以对其他变量进行相同的分析
Rafa

有用的答案!出于我的目的,我希望将数据框旋转以使组件为列。我用过pd.DataFrame(pca.components_.T, index=data_scaled.columns)
劳拉(Laura)

如果要single most important feature name在特定的PC上(或在所有PC上)使用该功能,请在此页末尾看到我的答案。
seralouk

51

编辑:正如其他人所评论,您可能会从.components_属性中获得相同的值。


每个主成分是原始变量的线性组合:

pca-coef

其中X_is是原始变量,Beta_is是相应的权重或所谓的系数。

要获得权重,您可以将身份矩阵简单地传递给该transform方法:

>>> i = np.identity(df.shape[1])  # identity matrix
>>> i
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])

>>> coef = pca.transform(i)
>>> coef
array([[ 0.5224, -0.3723],
       [-0.2634, -0.9256],
       [ 0.5813, -0.0211],
       [ 0.5656, -0.0654]])

coef上面矩阵的每一列都显示了线性组合中的权重,该权重得到相应的主成分:

>>> pd.DataFrame(coef, columns=['PC-1', 'PC-2'], index=df.columns)
                    PC-1   PC-2
sepal length (cm)  0.522 -0.372
sepal width (cm)  -0.263 -0.926
petal length (cm)  0.581 -0.021
petal width (cm)   0.566 -0.065

[4 rows x 2 columns]

例如,上面显示第二个主成分(PC-2)与基本上对齐sepal width,后者的0.926绝对值权重最大;

由于数据已归一化,因此您可以确认主成分具有方差1.0,该方差等于具有norm的每个系数向量1.0

>>> np.linalg.norm(coef,axis=0)
array([ 1.,  1.])

还可以确认可以将主系数计算为上述系数和原始变量的点积:

>>> np.allclose(df_norm.values.dot(coef), pca.fit_transform(df_norm.values))
True

注意numpy.allclose,由于浮点精度错误,我们需要使用而不是正则等式运算符。


3
很棒而详尽的答案,非常感谢!
mazieres 2014年

5
无需该身份矩阵:您的身份coef与相同pca.components_.T。scikit-learn估计器始终将其学习到的参数置于公共属性中。
Fred Foo 2014年

4
为什么不直接使用pca.components_
exAres

2
使用单位矩阵不起作用,因为逆变换函数会增加每个特征的经验平均值。结果为所有原始变量赋予相等的权重(系数)。(请参阅此答案)。通过使用pca.components_,您可以获得正确的答案。
Rahul Murmuria,2016年

32

这个问题的表达方式让我想起了我第一次尝试弄清主成分分析时的误解。我希望在这里仔细研究一下,希望其他人不会花那么多的时间在通向无处可去的路上之前。

“恢复”要素名称的概念表明,PCA可以识别数据集中最重要的要素。严格来说不是这样。

据我所知,PCA可以识别数据集中方差最大的特征,然后可以使用此数据集的质量来创建较小的数据集,而描述性损失最小。较小的数据集的优点在于,它需要较少的处理能力,并且数据中的噪声也应较小。但是,方差最大的特征并不是数据集的“最佳”或“最重要”特征,因为可以说这些概念根本就存在。

要将上述理论带入@Rafa上面的示例代码的实用性:

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
from sklearn import preprocessing
data_scaled = pd.DataFrame(preprocessing.scale(df),columns = df.columns) 

# PCA
pca = PCA(n_components=2)
pca.fit_transform(data_scaled)

考虑以下:

post_pca_array = pca.fit_transform(data_scaled)

print data_scaled.shape
(150, 4)

print post_pca_array.shape
(150, 2)

在这种情况下,post_pca_array具有与150行相同的数据data_scaled,但是data_scaled的四列已从四列减少为两列。

这里的关键点在于,的两列(或术语在术语上保持一致)post_pca_array不是的两个“最佳”列data_scaled。它们是两个新列,由sklearn.decompositionPCA模块背后的算法确定。第二栏,PC-2@Rafa的示例中sepal_width比其他任何列都有更多信息,但是PC-2data_scaled['sepal_width']中的值不相同。

因此,虽然有趣的是找出原始数据中的每一列对PCA后数据集的组成部分的贡献,但是“恢复”列名的概念有点误导,而且肯定会长期误导我。PCA后列和原始列之间唯一匹配的情况是,将主成分的数量设置为与原始列中的列相同。但是,使用相同数量的列将毫无意义,因为数据不会更改。您只会去那儿,然后再回来。


谢谢阿齐兹。我很高兴您能够从中得到一些东西。
amunnelly

谢谢。这从根本上误解了算法的功能,从而节省了我很多时间。
托马斯

8

重要的特征是影响更多组件的特征,因此具有很大的绝对值/系数/组件上的负载。

获取the most important feature name的个人电脑

from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
np.random.seed(0)

# 10 samples with 5 features
train_features = np.random.rand(10,5)

model = PCA(n_components=2).fit(train_features)
X_pc = model.transform(train_features)

# number of components
n_pcs= model.components_.shape[0]

# get the index of the most important feature on EACH component i.e. largest absolute value
# using LIST COMPREHENSION HERE
most_important = [np.abs(model.components_[i]).argmax() for i in range(n_pcs)]

initial_feature_names = ['a','b','c','d','e']

# get the names
most_important_names = [initial_feature_names[most_important[i]] for i in range(n_pcs)]

# using LIST COMPREHENSION HERE AGAIN
dic = {'PC{}'.format(i+1): most_important_names[i] for i in range(n_pcs)}

# build the dataframe
df = pd.DataFrame(sorted(dic.items()))

打印:

     0  1
 0  PC1  e
 1  PC2  d

结论/说明:

因此,在PC1上,命名的功能e最为重要,在PC2上,该功能最为重要d


5

给定拟合的估计量pca,可以在中找到分量,这些分量pca.components_代表数据集中最大方差的方向。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.