将向量 w 投影到向量 v 并绘制垂直线 – PCA 的准备工作

我想进行向量投影作为 PCA 的准备工作,我遵循了这个教程来计算向量投影。enter image description herew 是指向数据点的向量,v 是跨越 w 应该投影到的线的向量。

代码如下:

import numpy as npimport matplotlib.pyplot as pltfrom matplotlib import stylestyle.use('fivethirtyeight')from sklearn.preprocessing import StandardScaler# Normalize the input dataA = np.array([[10,8],[1,2],[7,5],[3,5],[7,6],[8,7],[9,9],[4,5],[6,5],[6,8],             [1,9],[10,2],[6,3],[2,5],[1,14],[8,8],[9,5],[4,4],[5,6],[8,8],             [11,9],[10,12],[6,4],[5,2],[10,2],[8,3],[6,9],[0,4],[13,6],[9,6]])A = StandardScaler(with_std=False,copy=False).fit_transform(A)fig = plt.figure(figsize=(15,10))ax0 = fig.add_subplot(111)ax0.set_ylim(bottom=min(A[:,1])-3,top=max(A[:,1])+3)ax0.scatter(A[:,0],A[:,1])# Initialize a first vector av = np.array([1,0.5])# Plot the vector v#ax0.arrow(0,0,a[0],a[1],length_includes_head=True,width=0.03,color='green')# Plot the line y=alpha*v defined by the vector a and passing the originax0.plot(np.linspace(min(A[:,0])-3,max(A[:,0])+3),np.linspace(min(A[:,0])-3,max(A[:,0])+3)*(v[1]/v[0]),         'k--',linewidth=1.5,zorder=0)# Run through all datapointscoordinates_on_ba_run = [] # Store the coordinates of the projected points on a for i in range(len(A[:,0])):    # Plot the vector v    #ax0.arrow(0,0,v[0],v[1],length_includes_head=True,width=0.03,color='green')    # Point on one of the datapoints and denote this vector with w    w = np.array([A[i][0],A[i][1]])    #ax0.arrow(0,0,w[0],w[1],length_includes_head=True,width=0.03,color='blue')    # Caclculate c and the projection vector cv. Additionally, test if the dot product of v and (w-cv) is zero    c = np.dot(w,v.reshape(2,1))/np.dot(v,v.reshape(2,1))    print(np.dot((w-c*v),v)) #This must be zero for each projection!    cv = c*v     # Draw a line from the datappoint in A to the tip of the vector cv.     ax0.plot([w[0],cv[0]],[w[1],cv[1]],linewidth=1,color='red',linestyle='--',zorder=0)    plt.show()

这会得到以下结果:

2.22044604925e-16-2.22044604925e-160.00.02.77555756156e-17-5.55111512313e-171.11022302463e-162.22044604925e-160.00.00.00.00.0-2.22044604925e-160.0-2.22044604925e-160.01.11022302463e-160.0-2.22044604925e-160.0-4.4408920985e-160.00.00.00.00.0-2.22044604925e-16-4.4408920985e-16-2.22044604925e-16

enter image description here

因此,代码是有效的,并且“控制”计算(np.dot((w-c*v),v))在每次变换中都必须为零,结果也是零…所以结果应该是正确的…但是,正如你用肉眼看到的,虚线并不是垂直于由向量 v 跨越的线。所以这只是一个可视化问题还是代码中有错误?感谢任何帮助


回答:

已经找到了错误…如果你查看坐标轴的比例,你会发现它们是不相等的,即 x 轴的范围是 (-10,10),而 y 轴的范围是 (-6,10)…因此这会扭曲视图,用肉眼看,红色虚线与由 v 跨越的线之间的角度不是 90 度,而是取决于比例的其他角度。这也解释了为什么计算 np.dot((w-c*v),v) 返回零,这表明结果是正确的。

这是有效的代码:

import numpy as npimport matplotlib.pyplot as pltfrom matplotlib import stylestyle.use('fivethirtyeight')from sklearn.preprocessing import StandardScaler# Normalize the input dataA = np.array([[10,8],[1,2],[7,5],[3,5],[7,6],[8,7],[9,9],[4,5],[6,5],[6,8],             [1,9],[10,2],[6,3],[2,5],[1,14],[8,8],[9,5],[4,4],[5,6],[8,8],             [11,9],[10,12],[6,4],[5,2],[10,2],[8,3],[6,9],[0,4],[13,6],[9,6]])A = StandardScaler(with_std=False,copy=False).fit_transform(A)fig = plt.figure(figsize=(10,10))ax0 = fig.add_subplot(111)ax0.set_aspect('equal')ax0.set_xlim((-10,10))ax0.set_ylim((-10,10))ax0.scatter(A[:,0],A[:,1])# Run through all the datafor i in range(len(A[:,0])):    # v    v = np.array([3,2])    ax0.plot(np.linspace(-10,10),np.linspace(-10,10)*(v[1]/v[0]),color='black',linestyle='--',linewidth=1.5)       # w    w = np.array([A[i][0],A[i][1]])    #ax0.arrow(0,0,w[0],w[1],length_includes_head=True,width=0.01,color='green')    # cv    cv = (np.dot(w,v))/np.dot(v,np.transpose(v))*v    #ax0.arrow(0,0,cv[0],cv[1],length_includes_head=True,width=0.005,color='black')    print(cv)    # line between w and cv    ax0.plot([w[0],cv[0]],[w[1],cv[1]],'r--',linewidth=1.5)    # Check the result    print(np.dot((w-cv),cv))plt.show()

enter image description here

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注