我想要生成一个3D图形来显示这两个类的分离。我看过这个解决方案,但不知道如何在px.scatter_3d中实现分离平面
下面是我到目前为止掌握的代码:
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
import pandas as pd
import os
from mpl_toolkits.mplot3d import Axes3D
from sklearn.decomposition import PCA
#df = pd.read_csv('df00_snippet.csv')
#X_train_flat = df.drop(columns=['Label']).values
#ydata = df['Label'].values
#X_train_flat
pca_train = PCA().fit(X_train_flat)
pca_train = PCA(n_components = 4)
x_pca = pca_train.fit_transform(X_train_flat)
y_train_new = ydata.astype(str)
# https://plotly.com/python/3d-scatter-plots/
fig = px.scatter_3d(x_pca,
x= x_pca[:,0], y= x_pca[:,1],z = x_pca[:,2],
labels={'x':'PCA-1', 'y':'PCA-2','z':'PCA-3'},
size_max=13,
#symbol=y_train_new,
opacity=1,
color=y_train_new,
color_discrete_sequence=["blue", "green"],
title='3d Plot of Top 3 PCA components')
fig.show()下面是mydata的一个片段:
feat1 feat2 feat3 feat4 Label
-3.8481877 -0.47685334 0.63422906 1.0396314 1
-2.320888 0.65347993 1.1519914 0.12997247 1
1.5827686 1.4119303 -1.7410104 -4.6962333 1
-0.1337152 0.13315737 -1.6648949 -1.4205348 1
-0.4028037 1.332986 1.3618442 0.3292255 1
-0.015517877 1.346349 1.4083523 0.87017965 1
-0.2669228 0.5478992 -0.06730786 -1.5959451 1
-0.03318152 0.3263167 -2.116833 -5.4616213 1
0.4588691 0.6723614 -1.617398 -4.3511734 1
0.5899199 0.66525555 -1.694493 -3.9452586 1
1.610061 2.4186094 1.8807093 1.3764497 0
1.7985699 2.4387648 1.6306056 1.1184534 0
-9.222036 -9.9776 -9.832 -9.909746 0
0.21364458 -1.0171559 -4.9093766 -6.2154694 0
-0.019955145 -1.1677283 -4.6549516 -5.9503417 0
0.44730473 -0.77167743 -4.7527356 -5.971007 0
-0.16508447 -0.005777468 -1.5020386 -4.49326 0
-0.8654994 -0.54387957 -1.300646 -4.621529 0
-1.7471086 -2.0005553 -1.7533782 -2.6065414 0
-1.5313624 -1.6995796 -1.4394685 -2.600004 0你能帮我生成分离平面吗?谢谢!
发布于 2022-07-10 06:56:28
花了好几个小时,但这是我的尝试。
有两件事需要做:
为了在平面上生成点,我们使用PCA中的三维平面 post的一部分代码(使用"ax+by+cz=d"),使用拟合点的'x_pca‘变量和来自'pca_train’变量的特征向量(见答案末尾的注释)。法线'a,b,和c‘是由'eig_vec’变量生成的。生成x和y坐标,计算‘质心’和'd‘值,并传递给"ax+by+cz=d“,给出平面的x、y和z坐标。
至于把飞机放在散点图上,那是最简单的部分。使用将平面添加到三维散射中后,我们可以使用点xx,yy和z来生成平面。飞机的颜色可以通过得到一个新的RGB值和改变两个‘#FFDB58 58’十六进制值来改变。
守则:
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
import pandas as pd
import plotly.graph_objects as go
import os
from mpl_toolkits.mplot3d import Axes3D
from sklearn.decomposition import PCA
df = pd.read_csv('df00_snippet.csv')
X_train_flat = df.drop(columns=['Label']).values
ydata = df['Label'].values
pca_train = PCA(n_components = 4).fit(X_train_flat)
x_pca = pca_train.fit_transform(X_train_flat)
y_train_new = ydata.astype(str)
# https://plotly.com/python/3d-scatter-plots/
fig = px.scatter_3d(x_pca,
x= x_pca[:,0], y= x_pca[:,1],z = x_pca[:,2],
labels={'x':'PCA-1', 'y':'PCA-2','z':'PCA-3'},
size_max=13,
#symbol=y_train_new,
opacity=1,
color=y_train_new,
color_discrete_sequence=["blue", "green"],
title='3d Plot of Top 3 PCA components')
# -- Start calculating the plane --
# https://stackoverflow.com/questions/49957601/how-can-i-draw-3d-plane-using-pca-in-python
eig_vec = pca_train.components_
# This is the normal vector of minimum variance
normal = eig_vec[2, :] # (a, b, c)
centroid = np.mean(x_pca, axis=0)
# Every point (x, y, z) on the plane should satisfy a*x+b*y+c*z = d
# Taking centroid as a point on the plane
d = -centroid.dot(normal)
# Calculate the plane's x, y and z coordinates
xx, yy = np.meshgrid((np.min(x_pca[:, 0]), np.max(x_pca[:, 0])), (np.min(x_pca[:, 1]), np.max(x_pca[:, 1])))
# Generated from the a*x+b*y+c*z = d formula
z = (-normal[0] * xx - normal[1] * yy - d) * 1. / normal[2]
# Add a plane to the figure
# https://stats.stackexchange.com/questions/163356/fitting-a-plane-to-a-set-of-points-in-3d-using-pca
fig.add_trace(go.Surface(x=xx, y=yy, z=z, colorscale=[[0, '#00FFFF'], [1, '#00FFFF']], showscale=False))
fig.show()注意:运行这个之后,'x‘和'y’轴似乎是正常的,但是'z‘轴似乎是关闭的。我认为这与这句话有关:
eig_vec = pca_train.components_https://stackoverflow.com/questions/72777649
复制相似问题