網上LDA源碼很多,但是想要跑起來,確實是需要些語言功底的。於是本文從不熟練者角度介紹了讓LDA源碼跑起來的步驟,LDA源碼使用的是Zhou Li的,其針對LDA寫的學習文章和代碼均可以在http://code.google.com/p/lsa-lda/downloads/list下載得到。我使用的是2009年10月的最新版本ldaviagibbs.zip,但代碼中還是有些bug的地方需要更正。
一、前提
下載源碼ldaviagibbs.zip和測試數據model.zip,解壓。
二、測試
1、新建空的控制台應用程序LDAtest,將源碼內document.h document.cc file_access.h file_access.cc lda.h lda.cc拷貝到工程文件夾下,將model.zip內的ap.dat拷貝到工程文件夾下。
PS:如果不希望程序等會運行半天才停下來,請打開ap.dat,只保留前50行左右,其他的測試數據都刪掉。
2、在工程中引入頭文件和源碼文件
3、添加調試參數:在項目屬性的“調試”屬性中,設置“命令參數”為“2 50 ap.dat ap”,分別表示“ topic_num sample_num data model_name”。
4、修正代碼。
打開file_access.cc,在15行之后加入cps->docs = NULL;即
13 ifstream infile(corpus_name); 14 string line; 15 corpus* cps = (corpus*)malloc(sizeof(struct corpus)); 16 cps->docs = NULL; //如果不加后面realloc的時候會bug
打開lda.cc,將11行改為
11 #include <time.h>
將158行改為
158 double temp = ((double)rand() / RAND_MAX) * p[topic_num - 1]; 159 double rand = temp;//貌似是變量名的問題,不這么轉一下它不給過
在167行后面加上
168 if(sample_topic == topic_num) sample_topic--; //如果相等就數組訪問越界了
將291行改為
srand(time(0));
因為VS2010里面的srandom名字改了
將299行改為
299 param->z[d][word_index] = (int)(((double)rand() / RAND_MAX) * (topic_num - 0.00000001)); //確保上界不為topic_num,否則后面的數組調用會越界
5、按下F5調試運行工程,應該能看到效果了。結果文件保存在工程目錄下,可以用記事本打開(建議裝個UltraEdit,程序員必備)
三、在C++工程中應用LDA
1、參照在VS2010中應用SIFT(C)源碼一文中該部分,新建文件夾lda,並拷貝源碼文件到lda文件夾中。在VS2010工程中新建lda“篩選器”並引入lda源文件:
2、在需要使用lda方法的地方添加對應頭文件:
#include "..\lda\lda.h" #include "..\lda\document.h" #include "..\lda\file_access.h"
3、取消.cc文件的預編譯。
4、修改代碼:打開lda.h,在19行后面添加init_param的聲明即改為
19 void average_param(struct est_param *param, struct corpus* cps,int topic_num,double alpha,double beta, int sample_num); 20 void init_param(struct corpus *cps, struct est_param* param,int topic_num); 21 #endif
5、綜上,你應該可以直接使用lda相關函數了,參照lda.cc中main函數的寫法。