PCA,LDA的C++實現(內附程式碼~)
原始碼獲取通道:C++實現LDA, 實現PCA
pca_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原理可以參考:
使用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;
}