Python中PCA图中的项目变量

时间:2017-07-17 15:50:08

标签: python r pca

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

class pdftabelModelForm(forms.ModelForm):
    class Meta:
        model = pdftabel_tool_
        fields = ['apn', 'owner_name']
    apn = forms.ModelChoiceField(queryset= Field.objects.values_list('name', flat=True), empty_label="(Choose field)")
    owner_name = forms.ModelChoiceField(queryset= Field.objects.values_list('name', flat=True), empty_label="(Choose field)")

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

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

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

2 个答案:

答案 0 :(得分:5)

我不知道这种情节的任何预先实现,但可以使用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 = 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()

enter image description here

不确定

我对箭头的缩放有点挣扎。请确保它们正确反映了您的数据的加载量。快速检查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()

enter image description here

答案 1 :(得分: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()              

希望这对某人有帮助!