PCA分析后的特征/变量重要性

fbm*_*fbm 12 python machine-learning pca feature-selection scikit-learn

我对原始数据集进行了PCA分析,并且从PCA转换的压缩数据集中,我还选择了我想要保留的PC数量(它们几乎解释了94%的方差).现在,我正在努力识别在简化数据集中重要的原始特征.在降维后,如何找出哪些特征是重要的,哪些特征不在剩余的主要组件中?这是我的代码:

from sklearn.decomposition import PCA
pca = PCA(n_components=8)
pca.fit(scaledDataset)
projection = pca.transform(scaledDataset)
Run Code Online (Sandbox Code Playgroud)

此外,我还尝试对简化数据集执行聚类算法,但令我惊讶的是,得分低于原始数据集.这怎么可能?

mak*_*kis 25

首先,我假设你调用features变量和not the samples/observations.在这种情况下,您可以通过创建一个biplot在一个图中显示所有内容的函数来执行以下操作.在这个例子中,我使用的是虹膜数据:

在此示例之前,请注意使用PCA作为特征选择工具时的基本思想是根据系数(负载)的大小(从绝对值的最大值到最小值)选择变量.有关更多详细信息,请参阅情节后的最后一段.


import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
import pandas as pd
from sklearn.preprocessing import StandardScaler

iris = datasets.load_iris()
X = iris.data
y = iris.target
#In general a good idea is to scale the data
scaler = StandardScaler()
scaler.fit(X)
X=scaler.transform(X)    

pca = PCA()
x_new = pca.fit_transform(X)

def myplot(score,coeff,labels=None):
    xs = score[:,0]
    ys = score[:,1]
    n = coeff.shape[0]
    scalex = 1.0/(xs.max() - xs.min())
    scaley = 1.0/(ys.max() - ys.min())
    plt.scatter(xs * scalex,ys * scaley, c = y)
    for i in range(n):
        plt.arrow(0, 0, coeff[i,0], coeff[i,1],color = 'r',alpha = 0.5)
        if labels is None:
            plt.text(coeff[i,0]* 1.15, coeff[i,1] * 1.15, "Var"+str(i+1), color = 'g', ha = 'center', va = 'center')
        else:
            plt.text(coeff[i,0]* 1.15, coeff[i,1] * 1.15, labels[i], color = 'g', ha = 'center', va = 'center')
plt.xlim(-1,1)
plt.ylim(-1,1)
plt.xlabel("PC{}".format(1))
plt.ylabel("PC{}".format(2))
plt.grid()

#Call the function. Use only the 2 PCs.
myplot(x_new[:,0:2],np.transpose(pca.components_[0:2, :]))
plt.show()
Run Code Online (Sandbox Code Playgroud)

使用biplot可视化正在发生的事情

BIPLOT结果


现在,每个特征的重要性反映在特征向量中相应值的大小(更高的幅度 - 更高的重要性)

让我们先看看每台PC解释的差异量.

pca.explained_variance_ratio_
[0.72770452, 0.23030523, 0.03683832, 0.00515193]
Run Code Online (Sandbox Code Playgroud)

PC1 explains 72%PC2 23%.总之,如果我们只保留PC1和PC2,他们会解释95%.

现在,让我们找到最重要的功能.

print(abs( pca.components_ ))

[[0.52237162 0.26335492 0.58125401 0.56561105]
 [0.37231836 0.92555649 0.02109478 0.06541577]
 [0.72101681 0.24203288 0.14089226 0.6338014 ]
 [0.26199559 0.12413481 0.80115427 0.52354627]]
Run Code Online (Sandbox Code Playgroud)

这里pca.components_有形状[n_components, n_features].因此,通过查看PC1作为第一行的(第一主成分):[0.52237162 0.26335492 0.58125401 0.56561105]]我们可以得出结论feature 1, 3 and 4(或者双子图中的变量1,3和4)是最重要的.

总而言之,查看对应于k个最大特征值的特征向量分量的绝对值.在sklearn组件中按排序explained_variance_.这些绝对值越大,特定特征对该主要成分的贡献就越大.

  • 你必须先了解一些重要的东西。每个功能都以不同的方式影响每台 PC。这意味着您只能得出如下结论:`特征 1、3 和 4 是最重要的/对 PC1 的影响最大`和`特征 2 是最重要的/对 PC2 的影响最大`等对于` N` 组件。在我的例子中,我只会对 PC1 和 PC2 进行这样的总结,因为这 2 台 PC 一起解释了 95% 的方差。现在清楚了吗? (3认同)
  • 是的,但我已经知道我必须保留多少台 PC。问题仍然是找到 PCA(n_components = 2) 的重要特征,也许我没有明白你的意思。假设我保留了 3 台 PC,我是否必须查看“pca.componets_”的第 3 个原始数据才能了解每个原始功能与我想要保留的那些 PC 的相关性? (2认同)

erd*_*ant 7

pca 库包含此功能。

pip install pca
Run Code Online (Sandbox Code Playgroud)

提取特征重要性的演示如下:

# Import libraries
import numpy as np
import pandas as pd
from pca import pca

# Lets create a dataset with features that have decreasing variance. 
# We want to extract feature f1 as most important, followed by f2 etc
f1=np.random.randint(0,100,250)
f2=np.random.randint(0,50,250)
f3=np.random.randint(0,25,250)
f4=np.random.randint(0,10,250)
f5=np.random.randint(0,5,250)
f6=np.random.randint(0,4,250)
f7=np.random.randint(0,3,250)
f8=np.random.randint(0,2,250)
f9=np.random.randint(0,1,250)

# Combine into dataframe
X = np.c_[f1,f2,f3,f4,f5,f6,f7,f8,f9]
X = pd.DataFrame(data=X, columns=['f1','f2','f3','f4','f5','f6','f7','f8','f9'])

# Initialize
model = pca()
# Fit transform
out = model.fit_transform(X)

# Print the top features. The results show that f1 is best, followed by f2 etc
print(out['topfeat'])

#     PC      feature
# 0  PC1      f1
# 1  PC2      f2
# 2  PC3      f3
# 3  PC4      f4
# 4  PC5      f5
# 5  PC6      f6
# 6  PC7      f7
# 7  PC8      f8
# 8  PC9      f9
Run Code Online (Sandbox Code Playgroud)

绘制解释方差

model.plot()
Run Code Online (Sandbox Code Playgroud)

解释方差

制作双标图。可以很好地看出,方差最大的第一个特征 (f1) 在图中几乎是水平的,而方差第二大的特征 (f2) 几乎是垂直的。这是意料之中的,因为大部分方差在 f1 中,其次是 f2 等。

ax = model.biplot(n_feat=10, legend=False)
Run Code Online (Sandbox Code Playgroud)

双标

3d 中的双标图。在这里,我们在 z 方向的图中看到了预期 f3 的很好的添加。

ax = model.biplot3d(n_feat=10, legend=False)
Run Code Online (Sandbox Code Playgroud)

双图3d