Numpy 计算并可视化SVM决策边界的正交向量,在嵌入空间内导航

Numpy 计算并可视化SVM决策边界的正交向量,在嵌入空间内导航,numpy,matplotlib,scikit-learn,embedding,ipywidgets,Numpy,Matplotlib,Scikit Learn,Embedding,Ipywidgets,我用CNN计算了2048个维度的嵌入物,这些嵌入物来自时尚商品的图像。我现在的目标是在这个多维嵌入空间中以交互方式导航。为了实现这一点,我首先应用PCA将空间的维数降低到2D或3D,这样我就可以将其可视化,并验证我的方法是否首先在低维空间中工作。2D和3D的结果分别如下所示: 我已经根据我的目标功能给它上色了季节。正如您所看到的,这个特性并不能很好地对嵌入进行集群。我的假设是,多维空间中存在一个超平面,它将这两个值很好地分开 现在,为了在2D/3D空间中导航,我现在使用了一个支持向量机,20

我用CNN计算了2048个维度的嵌入物,这些嵌入物来自时尚商品的图像。我现在的目标是在这个多维嵌入空间中以交互方式导航。为了实现这一点,我首先应用PCA将空间的维数降低到2D或3D,这样我就可以将其可视化,并验证我的方法是否首先在低维空间中工作。2D和3D的结果分别如下所示:

我已经根据我的目标功能给它上色了
季节
。正如您所看到的,这个特性并不能很好地对嵌入进行集群。我的假设是,多维空间中存在一个超平面,它将这两个值很好地分开

现在,为了在2D/3D空间中导航,我现在使用了一个支持向量机,2048维嵌入为
X
,一个功能为
season
,该功能表明一件衣服是在夏天穿还是在冬天穿,为
Y
。由于生成的决策边界以最大的裕度将两个类分开,因此我应该能够通过绘制与决策边界正交的另一个向量,从一个季节导航到另一个季节。因此,在2D中,我计算并绘制决策边界,并将其旋转90°,以获得正交轴,如下所示:

如您所见,除了两个轴之外,我还设置了一个用户标记,它根据
ipywidgets
FloatSlider的值进行更新。此外,我将返回ID、季节和最近嵌入到用户位置的预览图像(atm仅在2D中)。看起来,旋转轴并不是真的与决策边界正交。我做错什么了吗

目前,3D绘图看起来是这样的,没有导航的可能性,因为我还没有找到如何计算和可视化决策边界的法向量

如何计算3D和/或R^n中的正交向量?我的一个想法是利用scikit learn
LinearSVC
返回的
w
向量(属性
coef\uu
),因为这实际上是决策边界的垂直向量。这是一种有效的方法吗?你对我如何解决这个问题还有什么想法吗

以下是相关的代码片段:

2D绘图

从ipywidgets导入AppLayout,FloatSlider
从matplotlib.offsetbox导入(注释BBOX、OffsetImage、TextArea)
plt.ioff()
图,ax=plt.子批次(图尺寸=(15,7))
图canvas.header_visible=False
图canvas.layout.min_高度='400px'
#创建按季节特征着色的过滤数据集散点图
sns.散点图(x=“x”,y=“y”,
hue=“季节”,
数据=已过滤的df_,
legend=“full”,
α=0.8)
#计算训练分类器的决策边界
db_xx,db_yy=计算支持向量机决策边界(支持向量机clf,-35,35)
#旋转90度
负的=负的(分贝)
#绘制轴
plt.绘图(db_xx,db_yy,“k-”,线宽=2)
plt.绘图(负Y,分贝xx,“k-”,线宽=2)
#选择一个随机的起始位置
rand_idx=random.choice(范围(len(db_xx)))
x=neg_yy[rand_idx]
y=db_xx[rand_idx]
用户标记,用户位置=创建用户标记(x,y)
最近邻,最近邻=获取最近邻(用户位置,df过滤)
注释最近邻(最近邻、最近邻位置、ax、df)
plt.title('最近嵌入:{},季节:{}'。格式(最近邻,df_filtered.loc[df_filtered['id']==最近邻)。季节值[0]))
#创建与绘图交互的滑块
滑块=浮动滑块(
方向=“水平”,
description=“职位:”,
值=用户位置[0],
最小值=最小值(负),
最大值=最大值(负)
)
slider.layout.margin='0px 30%0px 30%'
slider.layout.width='40%'
滑块。观察(更新用户位置,名称='value')
申请(
中心=图画布,
页脚=滑块,
窗格高度=[0,6,1]
)
3D绘图

%matplotlib小部件
从matplotlib.colors导入ListedColormap
从ipywidgets导入AppLayout,浮动滑块
sns.set_风格(“白色”)
xx,yy=np.meshgrid(np.linspace(-150150200),np.linspace(-150150200))
z1=(-svm_-clf.intercept_0]-svm_-clf.coef_0[0]*xx-svm_-clf.coef[0][1]*yy)/svm_-clf.coef[0][2]
θ=(svm_-clf.coef[0][0]*xx-svm_-clf.coef[0][1]*yy)/svm_-clf.coef[0][2]
图=plt.图(图尺寸=(12,8))
ax=图添加_子图(111,投影='3d')
对于df_中的s,过滤的.seasure.unique():
散度(df_filtered.x[df_filtered.seasure==s],df_filtered.y[df_filtered.seasure==s],df_filtered.z[df_filtered.seasure==s],label=s)
ax.图例()
ax.图_面(xx,yy,z1,color='seashell')
#ax.plot(θ,yy,color='green')
plt.title(“三维嵌入空间”)
#创建与绘图交互的滑块
滑块=浮动滑块(
方向=“水平”,
description=“职位:”,
值=0,
最小值=-150,
最大值=150
)
slider.layout.margin='0px 20%0px 20%'
slider.layout.width='40%'
滑块。观察(更新用户位置,名称='value')
显示(滑块)
计算决策边界

def calc_svm_decision_边界(svm_clf,xmin,xmax):
“”“计算决策边界并重试”“”
w=支持向量机系数[0]
b=svm\u clf.截距[0]
xx=np.linspace(xmin,xmax,200)
yy=-w[0]/w[1]*xx-b/w[1]
返回xx,yy