Python 用sklearn恢复主成分分析中解释方差比的特征名称
我正在尝试从使用scikit learn完成的PCA中恢复,选择相关功能 IRIS数据集的经典示例Python 用sklearn恢复主成分分析中解释方差比的特征名称,python,machine-learning,scikit-learn,pca,Python,Machine Learning,Scikit Learn,Pca,我正在尝试从使用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_
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\u名称中获得该特征的索引
In [47]: print iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
提前感谢您的帮助。编辑:正如其他人所评论的,您可能会从属性中获得相同的值
每个主成分是原始变量的线性组合:
>>> np.allclose(df_norm.values.dot(coef), pca.fit_transform(df_norm.values))
True
其中,X_i
s是原始变量,Beta_i
s是相应的权重或所谓的系数
要获得权重,只需将单位矩阵传递给变换
方法:
>>> 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
)主要与萼片宽度
对齐,其绝对值的最大权重为0.926
由于数据已标准化,您可以确认主成分具有方差1.0
,这相当于每个系数向量具有范数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
请注意,由于浮点精度错误,我们需要使用常规等式运算符,而不是常规等式运算符。给定拟合的估计器
pca
,可以在pca.components\uuu
中找到分量,表示数据集中最高方差的方向。此信息包含在pca
属性中:组件中。如中所述,pca.components\uu
输出一个[n\u components,n\u 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维度。关于这一点的直觉,请考虑三维空间中的向量及其负数——它们本质上都表示空间中的同一方向。
查看更多参考资料。这个问题的措辞方式让我想起了我第一次试图弄清楚主成分分析时对它的误解。我想在这里讨论一下,希望其他人不会像我在最后一分钱掉下来之前那样,花那么多时间在一条无路可走的路上
“恢复”特征名称的概念表明PCA识别数据集中最重要的特征。严格说来,这不是真的
据我所知,主成分分析识别数据集中方差最大的特征,然后可以使用数据集的这种质量来创建一个较小的数据集,而描述能力的损失最小。较小数据集的优点是,它需要较少的处理能力,并且数据中的噪声应该较少。但差异最大的特征并不是数据集的“最佳”或“最重要”特征,因为这些概念可以说是存在的
要将该理论应用于上述@Rafa示例代码的实践中:
考虑以下几点:
在这种情况下,post\u pca\u数组
具有与data\u scaled
相同的150行数据,但是data\u scaled
的四列已从四列减少到两列
这里的关键点是post\u pca\u array
的两列(或术语上一致的组件)不是data\u scaled
的两个“最佳”列。它们是两个新列,由sklearn.decomposition
的PCA
模块背后的算法确定。在@Rafa的例子中,第二列,PC-2
比任何其他列更多地由sepal\u width
通知,但是PC-2
和data\u scaled['sepal\u width']
中的值不同
因此,虽然发现原始数据中的每一列对后PCA数据集的组成部分贡献了多少很有意思,但“恢复”列名的概念有点误导,并且肯定误导了我很长一段时间。PCA后列与原始列之间存在匹配的唯一情况是,主成分的数量与原始列中的列数相同。但是,使用相同数量的列没有任何意义,因为数据不会更改。你去那里只是为了再次回来,事实上。重要的特征是那些影响更多组件的特征,因此,组件上有一个很大的绝对值/系数/负载。
获取电脑上最重要的功能名称
:
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
的回答非常棒,非常感谢!无需使用该身份矩阵:您的coef
与pca.components\uuu.T
相同。scikit学习估计器总是将其学习的参数放在公共属性中。为什么不直接使用pca。组件
?使用
0 1
0 PC1 e
1 PC2 d