我使用以下简单的代码对包含10个特征的数据框进行了PCA分析:
pca = PCA()fit = pca.fit(dfPca)
pca.explained_variance_ratio_
的结果显示如下:
array([ 5.01173322e-01, 2.98421951e-01, 1.00968655e-01, 4.28813755e-02, 2.46887288e-02, 1.40976609e-02, 1.24905823e-02, 3.43255532e-03, 1.84516942e-03, 4.50314168e-16])
我认为这意味着第一主成分解释了52%的方差,第二主成分解释了29%,依此类推…
我不理解的是pca.components_
的输出。如果我这样做:
df = pd.DataFrame(pca.components_, columns=list(dfPca.columns))
我会得到下面的数据框,其中每一行是一个主成分。我想了解如何解释这个表格。我知道如果我对每个成分上的所有特征进行平方并求和,结果是1,但是PC1上的-0.56意味着什么?它是否说明了“特征E”,因为它在一个解释了52%方差的成分上具有最高的数值?
谢谢
回答:
术语: 首先,PCA的结果通常用成分得分(有时称为因子得分,即与特定数据点对应的转换变量值)和载荷(每个标准化原始变量应乘以的权重,以获得成分得分)来讨论。
第一部分:我将解释如何检查特征的重要性以及如何绘制双向图。
第二部分:我将解释如何检查特征的重要性以及如何使用特征名称将它们保存到pandas数据框中。
第一部分:
在你的例子中,特征E在PC1上的值-0.56是该特征在PC1上的得分。这个值告诉我们特征对PC(在我们的例子中是PC1)的影响程度。
因此,绝对值越高,对主成分的影响就越大。
进行PCA分析后,人们通常会绘制已知的“双向图”来查看在N维(在我们的例子中是2维)中转换后的特征和原始变量(特征)。
我编写了一个函数来绘制这个图表。
示例 使用鸢尾花数据:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsimport pandas as pdfrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAiris = datasets.load_iris()X = iris.datay = iris.target#一般来说,缩放数据是个好主意scaler = StandardScaler()scaler.fit(X)X=scaler.transform(X)pca = PCA()pca.fit(X,y)x_new = pca.transform(X) def myplot(score,coeff,labels=None): xs = score[:,0] ys = score[:,1] n = coeff.shape[0] plt.scatter(xs ,ys, 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.xlabel("PC{}".format(1))plt.ylabel("PC{}".format(2))plt.grid()#调用函数。 myplot(x_new[:,0:2], pca.components_) plt.show()
结果
第二部分:
重要特征是那些对成分影响较大且在成分上具有较大绝对值的特征。
要获取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
。