正交向量未正交绘制(Python 中的 PCA)
Orthogonal Vectors Not Plotting Orthogonally (PCA in Python)
我正在尝试在 Python 中实现 PCA,但是当我用主轴注释我的图形时,我的向量似乎不是正交的。
import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as LA
N = 1000
xTrue = np.linspace(0, 1000, N)
yTrue = 4 * xTrue
xData = xTrue + np.random.normal(0, 100, N)
yData = yTrue + np.random.normal(0, 100, N)
xData = np.reshape(xData, (N, 1))
yData = np.reshape(yData, (N, 1))
Data = np.hstack((xData, yData))
C = np.cov(Data, rowvar = False)
e_vals, e_vecs = LA.eig(C)
e_vals = np.real(e_vals)
e_vecs = -e_vecs
avg = (1/Data.shape[0] )*sum(Data, 0)
arrowprops = dict(arrowstyle = '->', linewidth = 3, shrinkA = 0, shrinkB = 0, color = 'r')
plt.scatter(Data[:,0], Data[:,1])
plt.title("Principal Component Analysis Example: Linear Data")
for i in [0,1]:
ax = plt.gca()
ax.annotate('', avg + np.sqrt(e_vals[i])*e_vecs[:,i], avg, arrowprops = arrowprops)
我可以通过显示 np.matmul(e_vecs, e_vecs.T)
大致是一个单位矩阵来验证我的特征向量是正交的。但是我得到的图像如下:
很明显,图像中的向量不是正交的,但它们为什么不正交是没有意义的,因为通过向量 avg
翻译它们不应该消除这个 属性。任何人都知道这是怎么回事?这是缩放问题还是我遗漏了一些重要参数?
The vectors are mutually orthogonal, but when you plot them they do not appear orthogonal due to the scale of the plot (the x-axis range is much smaller than the y-axis range). This becomes clear if the aspect of the plot is set to 'eqaul'
via matplotlib.axes.Axes.set_aspect
:
for i in [0,1]:
ax = plt.gca()
ax.set_aspect('equal')
ax.annotate('', avg + np.sqrt(e_vals[i])*e_vecs[:,i], avg, arrowprops = arrowprops)
You can of course reverse the scaling for the vectors to force them to be visually orthogonal on a set of axis for which the aspect is non-equal, but that ultimately would not be representative of the actual data. I would recommend either setting the aspect to 'equal'
using set_aspect('equal')
as above or simply noting that the vectors are orthogonal but don't plot orthogonally due to the aspect of the plot.
我正在尝试在 Python 中实现 PCA,但是当我用主轴注释我的图形时,我的向量似乎不是正交的。
import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as LA
N = 1000
xTrue = np.linspace(0, 1000, N)
yTrue = 4 * xTrue
xData = xTrue + np.random.normal(0, 100, N)
yData = yTrue + np.random.normal(0, 100, N)
xData = np.reshape(xData, (N, 1))
yData = np.reshape(yData, (N, 1))
Data = np.hstack((xData, yData))
C = np.cov(Data, rowvar = False)
e_vals, e_vecs = LA.eig(C)
e_vals = np.real(e_vals)
e_vecs = -e_vecs
avg = (1/Data.shape[0] )*sum(Data, 0)
arrowprops = dict(arrowstyle = '->', linewidth = 3, shrinkA = 0, shrinkB = 0, color = 'r')
plt.scatter(Data[:,0], Data[:,1])
plt.title("Principal Component Analysis Example: Linear Data")
for i in [0,1]:
ax = plt.gca()
ax.annotate('', avg + np.sqrt(e_vals[i])*e_vecs[:,i], avg, arrowprops = arrowprops)
我可以通过显示 np.matmul(e_vecs, e_vecs.T)
大致是一个单位矩阵来验证我的特征向量是正交的。但是我得到的图像如下:
很明显,图像中的向量不是正交的,但它们为什么不正交是没有意义的,因为通过向量 avg
翻译它们不应该消除这个 属性。任何人都知道这是怎么回事?这是缩放问题还是我遗漏了一些重要参数?
The vectors are mutually orthogonal, but when you plot them they do not appear orthogonal due to the scale of the plot (the x-axis range is much smaller than the y-axis range). This becomes clear if the aspect of the plot is set to 'eqaul'
via matplotlib.axes.Axes.set_aspect
:
for i in [0,1]:
ax = plt.gca()
ax.set_aspect('equal')
ax.annotate('', avg + np.sqrt(e_vals[i])*e_vecs[:,i], avg, arrowprops = arrowprops)
You can of course reverse the scaling for the vectors to force them to be visually orthogonal on a set of axis for which the aspect is non-equal, but that ultimately would not be representative of the actual data. I would recommend either setting the aspect to 'equal'
using set_aspect('equal')
as above or simply noting that the vectors are orthogonal but don't plot orthogonally due to the aspect of the plot.