Recovering features names of explained_variance_ratio_ in PCA with sklearn
我正在尝试从使用scikit-learn完成的PCA中恢复,这些功能被选择为相关。
IRIS数据集的经典示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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_ |
这返回
1 2 | In [42]: pca.explained_variance_ratio_ Out[42]: array([ 0.72770452, 0.23030523]) |
如何恢复数据集中哪两个特征允许这两个已解释的方差?
换句话说,我如何在iris.feature_names中获取此功能的索引?
1 2 | In [47]: print iris.feature_names ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] |
在此先感谢您的帮助。
此信息包含在
注意:每个系数代表特定的一对零件和特征之间的相关性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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空间中的负数-两者本质上都表示空间中的相同方向。
检查此帖子以获取更多参考。
编辑:正如其他人所评论,您可能会从
每个主成分是原始变量的线性组合:
其中
要获得权重,您可以将身份矩阵简单地传递给
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> 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]]) |
上面
1 2 3 4 5 6 7 8 | >>> 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] |
例如,上面显示第二主成分(
由于数据已归一化,因此可以确认主成分的方差
1 2 | >>> np.linalg.norm(coef,axis=0) array([ 1., 1.]) |
还可以确认可以将主系数计算为上述系数与原始变量的点积:
1 2 | >>> np.allclose(df_norm.values.dot(coef), pca.fit_transform(df_norm.values)) True |
请注意,由于浮点精度错误,我们需要使用
这个问题的表达方式让我想起了我第一次试图弄清主成分分析时的误解。我希望在这里仔细阅读一下,希望其他人不会花那么多的时间在通向无处可去的道路上,而那笔钱要花在我的钱最终下降之前。
"恢复"要素名称的概念表明,PCA可以识别数据集中最重要的要素。并非完全正确。
据我所知,PCA可以识别数据集中方差最大的特征,然后可以使用此数据集的质量来创建较小的数据集,而描述性损失最小。较小的数据集的优点在于,它需要较少的处理能力,并且数据中的噪声也应较小。但是,方差最大的特征并不是数据集的"最佳"或"最重要"特征,因为可以说这些概念根本就存在。
要将上述理论应用于上述@Rafa示例代码的实用性,请执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 | # 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) |
考虑以下:
1 2 3 4 5 6 7 | post_pca_array = pca.fit_transform(data_scaled) print data_scaled.shape (150, 4) print post_pca_array.shape (150, 2) |
在这种情况下,
这里的关键点是,
因此,虽然很有趣的是找出原始数据中的每一列对后PCA数据集的贡献有多大,但是"恢复"列名的概念有点误导,而且肯定会长期误导我。在PCA后和原始列之间存在匹配的唯一情况是,如果将主成分的数量设置为与原始列中的列相同。但是,使用相同数量的列将毫无意义,因为数据不会更改。您只会去那儿,然后再回来。
重要的特征是影响更多组件的特征,因此具有很大的绝对值/系数/组件上的负载。
在PC上获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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())) |
打印:
1 2 3 | 0 1 0 PC1 e 1 PC2 d |
结论/说明:
因此,在PC1上,名为
给定拟合的估计量