利用libpca进行主成分分析

4

libpca 是一个基于Armadillo的C++主成分分析库。

然而,我遇到了一个问题。我正在将其输出与Lindsay Smith在他关于PCA的优秀教程中给出的示例进行比较。当我检索第一个主成分时,我得到的值与Smith在他的教程中相同,但符号相反。对于第二个主成分,符号和值是正确的。

有人知道为什么吗?

代码:

#include "pca.h"
#include <iostream>

using namespace std;

int main(int argc, char** argv) {
    stats::pca pca(2);

    double* elements = new double[20]{2.5, 2.4, 0.5, 0.7, 2.2, 2.9, 1.9, 2.2, 3.1, 3.0, 2.3, 2.7, 2, 1.6, 1, 1.1, 1.5, 1.6, 1.1, 0.9};
    for (int i = 0; i < 20; i++) {
        vector<double> record;
        record.push_back(elements[i++]);
        record.push_back(elements[i]);
        pca.add_record(record);
    }

    pca.solve();             

    const vector<double> principal_1 = pca.get_principal(0);
    for (int i = 0; i < principal_1.size(); i++)
        cout << principal_1[i] << " ";
    cout << endl;

    const vector<double> principal_2 = pca.get_principal(1);
    for (int i = 0; i < principal_2.size(); i++)
        cout << principal_2[i] << " ";
    cout << endl;

    delete elements;
    return 0;
}

输出:

0.82797 -1.77758 0.992197 0.27421 1.6758 0.912949 -0.0991094 -1.14457 -0.438046 -1.22382 
-0.175115 0.142857 0.384375 0.130417 -0.209498 0.175282 -0.349825 0.0464173 0.0177646 -0.162675 

在大多数情况下,只有主成分的大小(magnitude)是重要的。 - mtall
有没有任何提示如何使用libpca? - Ben
@Ben,我的问题没有给出完整的工作示例吗? - kunterbunt
1个回答

5

@mtall已经给出了核心原因:主要组件形成了一个子空间的正常基础。无论您如何创建基础,将任何基向量乘以-1都会形成同一子空间的另一个基础。

这相当容易理解:将向量v乘以任意常数不会改变其方向。如果v垂直于w,则2*v垂直于3*w。将向量乘以-1会反转它的方向。如果v和w之间有一个角度alpha,则-v和w之间有一个角度(pi-alpha)。但是,如果alpha为pi/2,那么v和w是正交的,(pi-pi/2)仍然为pi/2,因此-v和w也是正交的。


谢谢你澄清了这个问题。 后续问题:如果我想让所有向量只有正值,那么我如何转换它们以保持它们之间的关系,比如说距离度量保持它们的距离? - kunterbunt
2
@randomdude:这根本没有意义。你可以将向量乘以-1,但这会使所有分量都乘以-1。例如,您的PCA可能会返回[2,2]和[-1,1]两个正交向量。您可以将后者乘以得到[1,-1],但是您无法合理地将后者转换为[1,1]。那将与[2,2]共线,而不是正交的。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接