我有一个包含 50 个 x、y、z 坐标样本的数组。这些样本表示手臂的线性运动。我想做以下事情:
到目前为止,我尝试使用PCA来计算最佳拟合线,但我对它的理解有些困难。我必须亲手做。 首先,我生成了一个包含 50 个样本的数组。
import random
import numpy as np
x, y, z = np.mgrid[-30:-10:50j], np.mgrid[-50:-30:50j], np.mgrid[0:-10:50j]
points = np.concatenate((x[:, np.newaxis],
y[:, np.newaxis],
z[:, np.newaxis]),
axis=1)
points += np.random.normal(size=points.shape) * 0.8
print(np.shape(points))
之后我必须计算 PCA 的 cov 矩阵和特征向量/特征值。
# Mean of every column.
x, y, z = points[:,0], points[:,1], points[:,2]
mean = np.array((sum(x)/len(x), sum(y)/len(y), sum(z)/len(z)))
# Cov-Matrix
N, M = np.shape(points)
cov = np.zeros((M,M))
for i in range(M):
for j in range(M):
summe = 0
for k in range(N):
summe += (points[k][i] - mean[i]) * (points[k][j] - mean[j]) / (N-1)
cov[i, j] = summe
# eigenvectors and eigenvalues. Safe first principle component to variable "eig"
eigval, eigvec = np.linalg.eig(cov)
eig = eigvec[:,np.argmax(eigval)]
最高特征值对应的特征向量是我们的第一个分量。 为了比较结果,我使用sklearn来测试我的价值观是否正确。
与 PCA 相比,我的矢量方向值是相同的:
eig: [-0.67634469 -0.66399367 0.31885775]
sklearn: [ 0.67634469 0.66399367 -0.31885775]
现在我不知道如何使用这个方向向量来计算到新点的距离。 此外,如果我尝试绘制它,点和云会由于偏移而关闭。
# Plot points in 3D
def plot_line(arr, line):
fig = plt.figure()
ax = plt.axes(projection='3d')
x, y, z = arr[:,0], arr[:,1], arr[:,2]
ax.scatter3D(x, y, z)
segments = np.arange(-20, 20)[:, np.newaxis] * line
lineplot = ax.plot(*(segments).T, color="red")
lineplot = ax.plot(*(line).T, 'ro')
当我有斜率时,如何得到线穿过的点? 是否有更好/更快的替代方法来获得线路,或者 PCA 是最好的方式吗?
感谢您的帮助!