You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PCA分析中最大特征值特征向量与最大方差轴不匹配问题排查

半圆柱点云PCA分析异常问题排查

问题背景

用Blender生成半圆柱模拟点云数据集,进行PCA分析求解特征向量与特征值:

  • Z轴为圆柱高度方向,方差统计显示Z轴方差最大:
np.var(data, axis=0)
x     0.225168
y     0.057463
z    33.122499
dtype: float64
  • 理论上最大特征值对应的特征向量应沿Z轴,但实际绘图显示最小特征值的特征向量沿圆柱轴;将点云投影到最小特征值对应的两个特征向量构成的平面时,未得到预期圆形,反而呈圆柱状。
  • 已确认特征向量选择逻辑正确,但结果不符合预期,同时对Blender点云导出的轴设置(轴选为Z、正方向选为Y或X)存在困惑。

相关代码

import numpy as np
import pandas as pd
from scipy.spatial.transform import Rotation as R
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

from r_pca import R_pca  # Ensure you have the r_pca library installed
from hyper_fit_with_lts import *
from cfg_fit_cylinder import *

def plot_vectors(data, eigvecs, eigenvals):
    colors = ['r', 'g', 'b']
    # Create a 3D scatter plot of the centered data
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(data[:, 0], data[:, 1], data[:, 2], label='Data', c='g', marker='x', alpha=0.1)

    # Plot eigenvectors as vectors
    for i in range(3): 
        vector = eigvecs[:, i]
        ax.quiver(0, 0, 0, vector[0], vector[1], vector[2], color=colors[i], label=f'Eigenvector {eigvecs[:, i]}, {eigenvals[i]}')

    ax.set_xlabel('X-axis')
    ax.set_ylabel('Y-axis')
    ax.set_zlabel('Z-axis')
    ax.legend()
    plt.show()

data = pd.read_csv(PATH_TO_POINT_CLOUD, header=None)
data.columns = ['x', 'y', 'z']

rpca = R_pca(data.values) # RPCA
L, S = rpca.fit(max_iter=10_000)
column_means = np.mean(L, axis=0)
centered_L = L - column_means
cov_matrix = np.cov(centered_L, rowvar=False)
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

print("Eigenvectors (Principal Components):")
print(eigenvectors)
print("\nEigenvalues")
print(eigenvalues)


centered_data = data - data.mean()
sorted_indices = np.argsort(-eigenvalues)
sorted_eigenvalues = sorted(eigenvalues, reverse=True)
sorted_eigenvectors = eigenvectors[:, sorted_indices]
plot_vectors(data.values, sorted_eigenvectors, sorted_eigenvalues)

smallest_components = sorted_eigenvectors[:, 1:] # Smallest eigenvectors (eigenvalues)

circle_projected_data = centered_data @ smallest_components
cylinder_2d_projection = sorted_eigenvectors[:, :2].T @ centered_data.T
cylinder_1d_projection = sorted_eigenvectors[:, 0].T @ centered_data.T
cylinder_height = np.ptp(cylinder_1d_projection)

circle_projected_data_without_centering = data @ smallest_components

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.scatter(circle_projected_data[0], circle_projected_data[1], color='r', label='Circle 2D in XY')
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')
ax1.set_title('Cycle 2D Projected Data')
ax1.set_aspect('equal')

ax1.legend()
plt.show()

排查方向

1. RPCA与后续数据不匹配

代码中用RPCA分解得到的低秩部分L计算协方差矩阵和特征值,但后续的中心化、绘图、投影操作全部使用原始data而非处理后的L。这会导致PCA计算的是低秩数据的特征,而可视化的是原始数据,两者维度分布不一致,必然出现结果矛盾。

  • 修复:将后续所有用到data或centered_data的地方替换为L或centered_L,保持数据来源统一。

2. Blender轴系映射偏差

Blender默认轴系为Y轴向上,而Matplotlib等工具的3D绘图默认Z轴向上。如果导出点云时轴设置错误,会导致你认知的Z轴(圆柱高度)与实际数据的轴方向不匹配。

  • 验证:打印L或data的数值范围,确认Z轴是否为数值跨度最大的轴;若不是,调整Blender导出时的轴设置,或在代码中手动交换轴(比如将Y和Z轴数据互换)。

3. 投影逻辑维度错误

在绘制投影图时,circle_projected_data是(n,2)的二维数组,但代码中用circle_projected_data[0]和circle_projected_data[1]取数,这只会获取第一行的两个值,而非所有点的X、Y投影坐标,导致绘图异常。

  • 修复:将绘图代码改为ax1.scatter(circle_projected_data[:, 0], circle_projected_data[:, 1], color='r', label='Circle 2D in XY')。

4. 特征值排序验证

虽然使用了np.argsort(-eigenvalues)进行降序排序,但可通过以下方式验证特征向量与轴的对应关系:

  • 计算最大特征值对应向量与[0,0,1]的点积,绝对值接近1则说明该向量沿Z轴;
  • 打印sorted_eigenvalues和sorted_eigenvectors,确认特征值大小与向量方向的对应关系是否符合预期。

内容的提问来源于stack exchange,提问作者Karantai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:25:17