我已经对原始数据集进行了PCA分析,并且从通过PCA转换的压缩数据集中选择了我想要保留的主成分数量(它们解释了几乎94%的方差)。现在我正在努力识别在降维后的数据集中哪些原始特征是重要的。我如何找出在降维后的主成分中哪些特征是重要的,哪些不是?这是我的代码:
from sklearn.decomposition import PCApca = PCA(n_components=8)pca.fit(scaledDataset)projection = pca.transform(scaledDataset)
此外,我还尝试在降维后的数据集上执行聚类算法,但令我惊讶的是,分数低于原始数据集。这是怎么可能的?
回答:
首先,我假设您将features
称为变量而不是样本/观察。在这种情况下,您可以创建一个biplot
函数,将所有内容显示在一个图表中,类似于以下操作。在这个例子中,我使用了iris数据集。
在示例之前,请注意使用PCA作为特征选择工具的基本思想是根据其系数(加载)的绝对值大小(从最大到最小)来选择变量。请参阅图表后的最后一段以获取更多细节。
概述:
第一部分:我将解释如何检查特征的重要性以及如何绘制biplot。
第二部分:我将解释如何检查特征的重要性以及如何使用特征名称将它们保存到pandas数据框中。
第一部分:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn.decomposition import PCAimport pandas as pdfrom sklearn.preprocessing import StandardScaleriris = datasets.load_iris()X = iris.datay = iris.target#一般来说,缩放数据是个好主意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()#调用函数。仅使用前两个PC。myplot(x_new[:,0:2],np.transpose(pca.components_[0:2, :]))plt.show()
使用biplot可视化发生了什么
现在,每个特征的重要性通过特征向量中相应值的大小反映出来(数值越大,重要性越高)
首先让我们看看每个PC解释了多少方差。
pca.explained_variance_ratio_[0.72770452, 0.23030523, 0.03683832, 0.00515193]
PC1解释了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]]
在这里,pca.components_
的形状是[n_components, n_features]
。因此,通过查看PC1
(第一主成分),它是第一行:[0.52237162 0.26335492 0.58125401 0.56561105]
,我们可以得出结论,特征1、3和4
(或biplot中的Var 1、3和4)是最重要的。这从biplot中也清晰可见(这就是我们经常使用这种图表以视觉方式总结信息的原因)。
总结一下,查看对应于k个最大特征值的特征向量的绝对值分量。在sklearn
中,组件是按explained_variance_
排序的。这些绝对值越大,特定特征对该主成分的贡献就越大。
第二部分:
重要特征是那些对组件影响更大,因此在组件上具有较大绝对值/分数的特征。
要获取PC上最重要的特征,并使用名称将它们保存到pandas数据框中,使用以下代码:
from sklearn.decomposition import PCAimport pandas as pdimport numpy as npnp.random.seed(0)# 10个样本,5个特征train_features = np.random.rand(10,5)model = PCA(n_components=2).fit(train_features)X_pc = model.transform(train_features)# 组件数量n_pcs= model.components_.shape[0]# 获取每个组件上最重要的特征的索引# 这里使用列表解析most_important = [np.abs(model.components_[i]).argmax() for i in range(n_pcs)]initial_feature_names = ['a','b','c','d','e']# 获取名称most_important_names = [initial_feature_names[most_important[i]] for i in range(n_pcs)]# 再次使用列表解析dic = {'PC{}'.format(i): most_important_names[i] for i in range(n_pcs)}# 构建数据框df = pd.DataFrame(dic.items())
这将打印:
0 1 0 PC0 e 1 PC1 d
因此,在PC1上,名为e
的特征是最重要的,而在PC2上是d
。