使用sklearn在PCA中恢复explain_variance_ratio_的功能名称

maz*_*res 61 python machine-learning pca scikit-learn

我正在尝试从使用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_
Run Code Online (Sandbox Code Playgroud)

这回来了

In [42]: pca.explained_variance_ratio_
Out[42]: array([ 0.72770452,  0.23030523])
Run Code Online (Sandbox Code Playgroud)

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

In [47]: print iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助.

Raf*_*afa 67

此信息包含在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
Run Code Online (Sandbox Code Playgroud)

重要提示:作为附注,请注意PCA符号不会影响其解释,因为符号不会影响每个组件中包含的差异.只有形成PCA尺寸的特征的相对符号才是重要的.事实上,如果再次运行PCA代码,您可能会获得反转符号的PCA尺寸.对于这种直觉,考虑一个向量及其在三维空间中的负面 - 两者基本上代表了空间中的相同方向.查看此帖子以获取进一步参考.

  • 要了解哪些功能很重要,您需要注意相关性.例如,萼片宽度和PC-2强烈相关(反向),因为相关系数是-0.92.另一方面,花瓣长度和PC-2完全不相关,因为corr coef是-0.02.因此,PC-2随着萼片宽度的减小而增长,而PC-2则与花瓣长度的变化无关.也就是说,对于PC-2,萼片宽度很重要而花瓣长度则不重要.考虑到相关系数在区间[-1,1]中,您可以对其他变量进行相同的分析 (7认同)
  • 所以说你想知道哪个原始特征是最重要的,你应该只取绝对值并求它们吗?我的意思是,从答案的最后一行开始:pd.DataFrame(pca.components_,columns = data_scaled.columns,index = ['PC-1','PC-2']).abs().sum (轴= 0),其结果为:0.894690 1.188911 0.602349 0.631027.我们可以说萼片宽度最重要,其次是萼片长度吗? (2认同)

beh*_*uri 45

编辑:正如其他人评论的那样,您可以从.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]])
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

例如,上面显示第二主成分(PC-2)主要与其对齐sepal width,其具有0.926绝对值的最高权重;

由于数据是标准化的,因此可以确认主成分的方差1.0等于具有范数的每个系数向量1.0:

>>> np.linalg.norm(coef,axis=0)
array([ 1.,  1.])
Run Code Online (Sandbox Code Playgroud)

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

>>> np.allclose(df_norm.values.dot(coef), pca.fit_transform(df_norm.values))
True
Run Code Online (Sandbox Code Playgroud)

注意numpy.allclose,由于浮点精度错误,我们需要使用而不是常规的相等运算符.

  • 不需要那个单位矩阵:你的`coef`和`pca.components_.T`是一样的.scikit-learn估算器总是将他们学到的参数放在公共属性中. (4认同)
  • 像我这样的人尝试学习PCA的有见地的答案 (3认同)
  • 为什么不直接使用`pca.components_`? (3认同)
  • 非常棒的答案,非常感谢! (2认同)
  • 使用单位矩阵不起作用,因为逆变换函数添加每个特征的经验均值.结果给出了所有原始变量的相等权重(系数).(见[回答](http://stackoverflow.com/a/22141821/3919475)).通过使用`pca.components_`,您可以得到正确的答案. (2认同)

amu*_*lly 23

这个问题的措辞方式让我想起了当我第一次想出来时对主成分分析的误解.我想在这里通过它,希望其他人不会像我在便士最终放弃之前那样花费太多时间在通往无处的路上.

"恢复"功能名称的概念表明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)
Run Code Online (Sandbox Code Playgroud)

考虑以下:

post_pca_array = pca.fit_transform(data_scaled)

print data_scaled.shape
(150, 4)

print post_pca_array.shape
(150, 2)
Run Code Online (Sandbox Code Playgroud)

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

这里的关键点是,两个列 - 或组件,在术语上是一致的 - post_pca_array不是两个"最佳"列data_scaled.他们是两个新列,由背后的算法确定sklearn.decompositionPCA模块.PC-2在@ Rafa的例子中,第二列sepal_width比任何其他列更多地通知,但是值PC-2和不同的值data_scaled['sepal_width'].

因此,虽然有趣的是找出原始数据中每列有多少贡献给后PCA数据集的组件,但"恢复"列名称的概念有点误导,并且肯定误导了我很长一段时间.如果主要组件的数量设置为与原始列中的列相同的数量,那么后PCA和原始列之间将匹配的唯一情况.但是,使用相同数量的列是没有意义的,因为数据不会改变.你只会去那里再回来,就像它一样.


mak*_*kis 13

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

获取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()))
Run Code Online (Sandbox Code Playgroud)

这打印:

     0  1
 0  PC1  e
 1  PC2  d
Run Code Online (Sandbox Code Playgroud)

结论/解释:

因此,在 PC1 上,命名的功能e是最重要的,而在 PC2 上,d.


eic*_*erg 6

给定您的拟合估计量pca,组件将在 中找到pca.components_,代表数据集中方差最大的方向。