1. 程式人生 > >PCA,LDA的C++實現(內附程式碼~)

PCA,LDA的C++實現(內附程式碼~)

原始碼獲取通道:C++實現LDA實現PCA

pca_z執行結果:
pca
LDA_Z執行結果:
LDA_Z
原理簡單易懂,用於降維。

Visual C++ 無法解析的外部符號問題

在VS環境下用Eigen進行SVD分解
先輸入陣列,二維陣列,然後轉換為MatrixXd型別,然後呼叫SVD,呼叫方法是:ja
期間注意兩點:
第一:Map函式可將陣列對映成矩陣,但是對映規則和MATLAB儲存矩陣的方式類似,是按列進行的投射的。比如[ 1,3,3,4,5,1]投射[2*3]的結果是[1,4;3,5;3,1];
第二:呼叫SVD時,可以使用Full,Thin兩種模式,奇異值分解後得到的前部分是一樣的,所以如果只取前面部分,可以不用太care;
SVD原理可以參考:

http://blog.csdn.net/yueliangku/article/details/41725905

使用Eigen進行線性方程組的求解

STD:

實現矩陣歸一化時,Matlab中的mean,和std原理要反覆推敲,注意行列關係,比如求均值是對列求,得到一個行向量,std公式根號下前面的係數是(N-1)!

y=std(x) 算出x的標準偏差。 x可以是vector或者一個matrix矩陣。

若x是vector,則y是算x的標準偏差。
若x是matrix,則y是個vector,存放的是算每一列/行的標準偏差。 std (x, flag,dim)
fla表示標註公差時是要除以n還是n-1
flag==0………是除以n-1
flag==1………是除以n
dim表示維數
dim==1……….是按照列分
dim==2……….是按照行分 若是三維的矩陣,dim==3就按照第三維來分資料

預設std格式是std(x,0,1);

 >>x=[ 1 2 3 4; 4 5 6 1 ]
 >>std(x)
ans =
    2.1213    2.1213    2.1213    2.1213

>> std(x,1)
ans =
    1.5000    1.5000    1.5000    1.5000

 >> std(x,0,2)
ans =
    1.2910
    2.1602

>> std(x,1,2)
ans =
    1.1180
    1.8708

具體分析:
A=[1,2;3,4];
CC=mean(A,1) %每列求均值

result: 2 3

A=[1,2;3,4];
CC=mean(A,2) % 每行就均值

result: 1.5000
3.5000
A=[1,2;3,4];
CC=mean2(A) % 矩陣均值

result :2.5000

std(x,0,1)與mean(x,1) 其實得到的都是行向量,也即對例進行處理
A=[1,2;3,4];
CC=std(A,0,1) % 矩陣均值
result: 1.4142 1.4142
驗證std(A,0,2),其實結果也一樣的, 0.7071 0.7071。

然而std2與mean2一樣,是對矩陣求均 方差。

A=[1,2;3,4];
CC=std2(A)

測試程式碼執行時間:

在C++中計算執行的時間是呼叫clock函式,使用clock函式獲得程式開始和結束所需的時間,相減就得到程式所花的時間。

clock()是C/C++中的計時函式,而與其相關的資料型別是clock_t。在MSDN中,查得對clock函式定義如下:

clock_t clock(void) ;

簡單而言,就是該程式從啟動到函式呼叫佔用CPU的時間。這個函式返回從“開啟這個程式程序”到“程式中呼叫clock()函式”時之間的CPU時鐘計時單元(clock tick)數,在MSDN中

稱之為掛鐘時間(wal-clock);若掛鐘時間不可取,則返回-1。其中clock_t是用來儲存時間的資料型別。

#include<iostream>  
#include<ctime>  
using namespace std;  

int main()  
{  
    clock_t start,finish;  
    start=clock();  

    cout << "HW .... " << endl;  

    finish=clock();  

    cout << finish-start   << "/" << CLOCKS_PER_SEC  << " (s) "<< endl;  

    return 0;  
}