【问题标题】:Project variables in PCA plot in PythonPython中PCA图中的项目变量
【发布时间】:2017-12-22 05:52:37
【问题描述】:

在 R 中执行 PCA 分析后,我们可以:

ggbiplot(pca, choices=1:2, groups=factor(row.names(df_t)))

这将绘制2个PC空间中的数据,以及向量等空间中变量的方向和权重(具有不同的长度和方向)。

在 Python 中我可以在 2 PC 空间中绘制数据,我可以得到变量的权重,但是我怎么知道方向。

换句话说,如何在 Python 中绘制变量对 PC(权重和方向)的贡献?

【问题讨论】:

  • 这里的重量和方向是什么意思?主成分是原始预测变量的线性组合。权重是指主成分中原始特征的系数吗?这里的方向是什么意思?
  • 方向和重量是指用于绘制箭头的数据,例如:sthda.com/sthda/RDoc/figure/factor-analysis/…
  • 我不确定情节对我有什么意义

标签: python r pca


【解决方案1】:

我不知道这种情节的任何预制实现,但可以使用matplotlib.pyplot.quiver 创建它。这是我快速整理的一个示例。您可以以此为基础创建一个适合您的数据的漂亮图。


示例数据

这会生成一些示例数据。从this answer重复使用。

# User input
n_samples  = 100
n_features =   5

# Prep
data  = np.empty((n_samples,n_features))
np.random.seed(42)

# Generate
for i,mu in enumerate(np.random.choice([0,1,2,3], n_samples, replace=True)):
    data[i,:] = np.random.normal(loc=mu, scale=1.5, size=n_features)

主成分分析

pca = PCA().fit(data)

变量因子图

我们开始吧:

# Get the PCA components (loadings)
PCs = pca.components_

# Use quiver to generate the basic plot
fig = plt.figure(figsize=(5,5))
plt.quiver(np.zeros(PCs.shape[1]), np.zeros(PCs.shape[1]),
           PCs[0,:], PCs[1,:], 
           angles='xy', scale_units='xy', scale=1)

# Add labels based on feature names (here just numbers)
feature_names = np.arange(PCs.shape[1])
for i,j,z in zip(PCs[1,:]+0.02, PCs[0,:]+0.02, feature_names):
    plt.text(j, i, z, ha='center', va='center')

# Add unit circle
circle = plt.Circle((0,0), 1, facecolor='none', edgecolor='b')
plt.gca().add_artist(circle)

# Ensure correct aspect ratio and axis limits
plt.axis('equal')
plt.xlim([-1.0,1.0])
plt.ylim([-1.0,1.0])

# Label axes
plt.xlabel('PC 0')
plt.ylabel('PC 1')

# Done
plt.show()


不确定

我对箭头的缩放有点挣扎。请确保它们正确反映了数据的负载。快速检查一下feature 4 是否真的与PC 1 密切相关(如本例所示)看起来很有希望:

data_pca = pca.transform(data)
plt.scatter(data_pca[:,1], data[:,4])
plt.xlabel('PC 2') and plt.ylabel('feature 4')
plt.show()

【讨论】:

    【解决方案2】:

    感谢 WhoIsJack 的较早回答。

    我将那里的代码改编为下面的函数,该函数接受一个合适的 PCA 对象和它所基于的数据。它产生类似于上面的图,但我用真实的列名代替了列索引,然后将其修剪为只显示一定数量的贡献列。

    def plot_pca_vis(pca, df: pd.DataFrame, pc_x: int = 0, pc_y: int = 1, num_dims: int = 5):
        """
        https://stackoverflow.com/questions/45148539/project-variables-in-pca-plot-in-python
        Adapted into function by Tim Cashion
        """
        # Get the PCA components (loadings)
        PCs = pca.components_
    
        PC_x_index = PCs[pc_x, : ].argsort()[-num_dims:][::-1]
        PC_y_index = PCs[pc_y, : ].argsort()[-num_dims:][::-1]
        combined_index = set(list(PC_x_index) + list(PC_y_index))
        PCs = PCs[:, list(combined_index)]
        # Use quiver to generate the basic plot
        fig = plt.figure(figsize=(5,5))
        plt.quiver(np.zeros(PCs.shape[1]), np.zeros(PCs.shape[1]),
                PCs[pc_x,:], PCs[pc_y,:], 
                angles='xy', scale_units='xy', scale=1)
    
        # Add labels based on feature names (here just numbers)
        feature_names = df.columns
        for i,j,z in zip(PCs[pc_y,:]+0.02, PCs[pc_x,:]+0.02, feature_names):
            plt.text(j, i, z, ha='center', va='center')
    
        # Add unit circle
        circle = plt.Circle((0,0), 1, facecolor='none', edgecolor='b')
        plt.gca().add_artist(circle)
    
        # Ensure correct aspect ratio and axis limits
        plt.axis('equal')
        plt.xlim([-1.0,1.0])
        plt.ylim([-1.0,1.0])
    
        # Label axes
        plt.xlabel('PC ' + str(pc_x))
        plt.ylabel('PC ' + str(pc_y))
        # Done
        plt.show()              
    

    希望这对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-08-04
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 2018-03-30
      相关资源
      最近更新 更多