如何在python中使用PCA绘制3D平面?

如何在python中使用PCA绘制3D平面?,python,matplotlib,pca,plane,Python,Matplotlib,Pca,Plane,因此-0.375978766054x+0.10612154283y-0.920531469111z+15.1366572005=0 事实上,我不确定这是否正确 我想在这种情况下使用matplotlib库绘制一个平面 如何编写代码?第一个主分量不定义平面,它定义了三维向量。以下是如何在3D中可视化:代码从您的代码开始,然后有绘图步骤: X = np.array([[24,13,38],[8,3,17],[21,6,40],[1,14,-9],[9,3,21],[7,1,14],[8,7,11],[

因此-0.375978766054x+0.10612154283y-0.920531469111z+15.1366572005=0

事实上,我不确定这是否正确

我想在这种情况下使用matplotlib库绘制一个平面


如何编写代码?

第一个主分量不定义平面,它定义了三维向量。以下是如何在3D中可视化:代码从您的代码开始,然后有绘图步骤:

X = np.array([[24,13,38],[8,3,17],[21,6,40],[1,14,-9],[9,3,21],[7,1,14],[8,7,11],[10,16,3],[1,3,2],
    [15,2,30],[4,6,1],[12,10,18],[1,9,-4],[7,3,19],[5,1,13],[1,12,-6],[21,9,34],[8,8,7],
  [1,18,-18],[15,8,25],[16,10,29],[7,0,17],[14,2,31],[3,7,0],[5,6,7]])
pca = PCA(n_components=1)

pca.fit(X)
a = pca.components_[0][0] # a
b = pca.components_[0][1] # b
c = pca.components_[0][2] # c

def average(values):
    if(values) ==0:
        return None
    return sum(values, 0.0) / len(values)

x_mean = average(x) # For an approximation
y_mean = average(y)
z_mean = average(z)
d = -(a * x_mean + b * y_mean + c * z_mean)
(注意上面的代码是自动格式化的,我强烈推荐。)结果图:


第一个主分量不定义平面,它定义了三维的向量。以下是如何在3D中可视化:代码从您的代码开始,然后有绘图步骤:

X = np.array([[24,13,38],[8,3,17],[21,6,40],[1,14,-9],[9,3,21],[7,1,14],[8,7,11],[10,16,3],[1,3,2],
    [15,2,30],[4,6,1],[12,10,18],[1,9,-4],[7,3,19],[5,1,13],[1,12,-6],[21,9,34],[8,8,7],
  [1,18,-18],[15,8,25],[16,10,29],[7,0,17],[14,2,31],[3,7,0],[5,6,7]])
pca = PCA(n_components=1)

pca.fit(X)
a = pca.components_[0][0] # a
b = pca.components_[0][1] # b
c = pca.components_[0][2] # c

def average(values):
    if(values) ==0:
        return None
    return sum(values, 0.0) / len(values)

x_mean = average(x) # For an approximation
y_mean = average(y)
z_mean = average(z)
d = -(a * x_mean + b * y_mean + c * z_mean)
(注意上面的代码是自动格式化的,我强烈推荐。)结果图:


每个主分量在特征空间中定义一个向量。PCA根据每个方向上数据的方差对这些向量进行排序。因此,第一个向量表示数据的最大方差,最后一个向量表示最小方差。假设数据分布在一个平面上,则第三个向量应垂直于该平面。代码如下:

import numpy as np
from sklearn.decomposition import PCA

X = np.array([[24, 13, 38], [8, 3, 17], [21, 6, 40], [1, 14, -9], [9, 3, 21], [7, 1, 14],
              [8, 7, 11], [10, 16, 3], [1, 3, 2], [15, 2, 30], [4, 6, 1], [12, 10, 18], [1, 9, -4],
              [7, 3, 19], [5, 1, 13], [1, 12, -6], [21, 9, 34], [8, 8, 7], [1, 18, -18],
              [15, 8, 25], [16, 10, 29], [7, 0, 17], [14, 2, 31], [3, 7, 0], [5, 6, 7]])

pca = PCA(n_components=1)
pca.fit(X)

## New code below
p = pca.components_
centroid = np.mean(X, 0)
segments = np.arange(-40, 40)[:, np.newaxis] * p

import matplotlib
matplotlib.use('TkAgg') # might not be necessary for you
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
scatterplot = ax.scatter(*(X.T))
lineplot = ax.plot(*(centroid + segments).T, color="red")
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('result.png', dpi=150)

每个主分量在特征空间中定义一个向量。PCA根据每个方向上数据的方差对这些向量进行排序。因此,第一个向量表示数据的最大方差,最后一个向量表示最小方差。假设数据分布在一个平面上,则第三个向量应垂直于该平面。代码如下:

import numpy as np
from sklearn.decomposition import PCA

X = np.array([[24, 13, 38], [8, 3, 17], [21, 6, 40], [1, 14, -9], [9, 3, 21], [7, 1, 14],
              [8, 7, 11], [10, 16, 3], [1, 3, 2], [15, 2, 30], [4, 6, 1], [12, 10, 18], [1, 9, -4],
              [7, 3, 19], [5, 1, 13], [1, 12, -6], [21, 9, 34], [8, 8, 7], [1, 18, -18],
              [15, 8, 25], [16, 10, 29], [7, 0, 17], [14, 2, 31], [3, 7, 0], [5, 6, 7]])

pca = PCA(n_components=1)
pca.fit(X)

## New code below
p = pca.components_
centroid = np.mean(X, 0)
segments = np.arange(-40, 40)[:, np.newaxis] * p

import matplotlib
matplotlib.use('TkAgg') # might not be necessary for you
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
scatterplot = ax.scatter(*(X.T))
lineplot = ax.plot(*(centroid + segments).T, color="red")
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('result.png', dpi=150)

侧边注释:
np.mean
?侧边注释:
np.mean
?您的代码不运行。第29行由于某种原因返回语法错误。z=(-normal[0]*xx-normal[1]*yy-d)*1./正常[2]。也在外部编译器上尝试过,相同result@KantushovHerman谢谢你的评论,我刚刚意识到我忘记关闭第28行的括号(在复制和粘贴我的jupyter笔记本时丢失了它)。无论如何,我编辑了我的答案,它应该马上运行。你的代码没有运行。第29行由于某种原因返回语法错误。z=(-normal[0]*xx-normal[1]*yy-d)*1./正常[2]。也在外部编译器上尝试过,相同result@KantushovHerman谢谢你的评论,我刚刚意识到我忘记关闭第28行的括号(在复制和粘贴我的jupyter笔记本时丢失了它)。不管怎样,我编辑了我的答案,它应该马上运行。