2013年5月28日星期二

cdec添加一个模块

往cdec中添加一个模块, 以svmlight, maxent等classifiers为例.

1) 新建文件夹classifier, 在classifier/中实现svmlight.h/cpp, maxent.h/cpp, classifier.h/cpp

2) 在classifier/中新建Makefile.am, 内容可参照:

noinst_LIBRARIES = libclassifiers.a

libclassifiers_a_SOURCES = \
  svmlight.cpp \
  maxent.cpp \
  classifier.cpp
 
AM_CPPFLAGS = -W -Wall

这样libclassifiers.a可以在其他地方调用

3) 在主文件夹, 修改Makefile.am
在SUBDIRS项中添加classifier文件夹

4) 在主文件夹, 修改configure.ac
在末尾添加
AC_CONFIG_FILES([classifier/Makefile])

5) 重新开始编译(autoconf, configure, make等)


注意: 得看情况决定是否要修改decoder/ mira-vlad/下的Makefile.am文件, 即添加../classifier/libclassifiers.a和-I../classifier项

2013年4月3日星期三

往cdec中添加一个新feature

可按下面步骤:
1) 在decoder/目录下新建ff_feature_name.h和ff_feature_name.cc文件.
    在ff_feature_name.h中定义继承于FeatureFunction的类, 如何有需要, 定义继承于FactoryBase的factory类. 可参考ff_klm.h, ff_basic.h等.

2) 注册新定义的feature
    在decoder/cdec_ff.cc中注册新feature
    #include "ff_feature_name.h"
    在void register_feature_functions()中添加:
    ff_registry.Register("NewFeatureName", new NewFeatureFactory()); //如果定义了factory类
    或者
    ff_registry.Register("NewFeatureName", new FFFactory); //如果没有定义factory类

3) 在decoder/Makefile.am 中添加新定义的类(文件) ff_feature_name.cc, 可参考ff_klm类的写法.

4) 重新编译..


添加一个新的feature, contextual free, 但是需要用state来保留些信息, 用于快速计算该feature值.
这个时候需要注意, apply_models.cc/IncorporateIntoPlusLMForest(...), 里面(*s2n)[item->state_]会根据state值,决定是否产生一个新的node,或者丢弃. 因此在这之前需要将state里面的内容关于新feature的部分给erase掉. 按以下:
1) 在ff_set.h/ModelSet类里添加
public: 
FFState GetRealFFState(const FFState& state) const;
在该方法的实现中根据原state状态, 返回一个新的real_state, real_state里将新feature部分的state给删除掉了
2) 在apply_models.cc/IncorporateInputPlusLMForest(...)里:
Candidate*& o_item = (*s2n)[item->state_];
修改为

FFState real_state = models.GetRealFFState(item->state_);
Candidate*& o_item = (*s2n)[real_state];


assert(o_item->state_ == item->state_);    // sanity check!
修改为

assert(models.GetRealFFState(o_item->state_) == models.GetRealFFState(item->state_));  //sanity check!

附: GetRealFFState()实现
void ModelSet::GetRealFFState(const FFState& state, FFState& real_state) const {
real_state.resize(state.size());
for (int i = 0; i < state.size(); i++) {
real_state[i] = state[i];
}

if (state.size() == 0)
return;
assert(state.size() == state_size_);

//erase the states for SRLReorderFeature
for (int i = 0; i < models_.size(); i++) {
if (models_[i]->name_ == string( "NewFeatureName" )) {
int start_pos = model_state_pos_[i];
int end_pos;
if (i == models_.size() - 1)
end_pos = state_size_;
else
end_pos = model_state_pos_[i + 1];
for (int j = start_pos; j < end_pos; j++)
real_state[j] = 0;
}
}
}

FFState ModelSet::GetRealFFState(const FFState& state) const {
FFState real_state;
GetRealFFState(state, real_state);
return real_state;
}




2013年3月29日星期五

cdec一些細節

1) 讀取cdec.ini文件
line484: decoder.cc
DecoderImpl::DecoderImpl() at decoder.cc:484
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

2) 讀取weight.init文件
line15:weights.cc
Weights::InitFromFile() at weights.cc
DecoderImpl::DecoderImpl() at decoder.cc:571

Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

3) 讀取language model文件
line91: ff_factory.h:92
FactoryRegistry::Create() at ff_factory.h:92
make_ff() at decoder.cc:131
DecoderImpl::DecoderImpl() at decoder.cc:604
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

4) 添加glue grammar
line51: scfg_translator.cc
GlueGrammar::GlueGrammar() at scfg_translator.cc:51
SCFGTranslatorImpl::SCFGTranslatorImpl() at scfg_translator.cc:134
SCFGTranslator::SCFGTranslator() at scfg_translator.cc:345
DecoderImpl::DecoderImpl() at decoder.cc:667
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14


5) 讀取grammar文件
line303: rule_lexer.ll
RuleLexer::ReadRules() at rule_lexer.ll:303
TextGrammar::ReadFromStream() at grammar.cc:123
TextGrammar::ReadFromFile() at grammar.cc:119
TextGrammar::TextGrammar() at grammar.cc:80
SCFGTranslator::ProcessMarkupHintsImpl() at scfg_translator.cc:363
Translator::ProcessMarkupHints() at translator.cc:21
DecoderImpl::Decoder() at decoder.cc:791
Decoder::Decoder() at decoder.cc:746
main() at cdec.cc:30

6) input sentence轉換為lattice structure
line58: lattice.cc
LatticeTools::ConvertTextOrPLF() at lattice.cc:58
SCFGTranslatorImpl::Translate() at scfg_translator.cc:186
SCFGTranslator::TranslateImpl() at scfg_translator.cc:354
Translator::Translate() at translator.cc:33
DecoderImpl::Decode() at decoder.cc:794
Decoder::Decode() at decoder.cc:746
main() at cdec.cc:30

7) 添加pass through grammar
line65: scfg_translator.cc
PassThroughGrammar::PassThroughGrammar() at scfg_translator.cc:65
SCFGTranslatorImpl::Translate() at scfg_translator.cc:190
SCFGTranslator::TranslateImpl() at scfg_translator.cc:354
Translator::Translate() at translator.cc:33
DecoderImpl::Decode() at decoder.cc:794
Decoder::Decode() at decoder.cc:746
main() at cdec.cc:30



取消cdec中phrase長度限制

cdec中有三個參數來表示phrase span的單詞最大個數.

1) 抽取規則時, phrase在training sentences中的最大長度. 該變量的定義在sa-extract/sa-compile.pl中, my $max_size = 15; 可以通過sa-extract/sa-compile.pl -p max-size=10來修改;

2) 還是抽取規則時, phrase在test sentences中的最大長度. 既對於test sentences中的某個phrase, 如果長度超過該值, 那麼不去從training sentences中找匹配規則. 該變量的值在sa-extract/extract.ini文件中設置 (作為rulefactory.HieroCachingRuleFactory()的一個參數):
max_initial_size=15,             # maximum span of a grammar rule in TEST DATA

可以修改為max_initial_size=max_size, 既1)提到的phrase在training sentences中的最大長度. 雖然在sa-extract/extract.ini中也設置了max_size的值, 但該值會被sa-extract/sa-compile.pl中的值覆蓋掉.

3) Decoding的時候, scfg的長度, 在配置文件cdec.ini中設置. 如scfg_max_span_limit=12

往cdec取消phrase span單詞數的限制, 那麼需要修改以上三個參數, 比如:

1) 調用sa-compile.pl時, 設置-p, sa-extract/sa-compile.pl -p max-size=100000
2) 修改sa-extract/extract.ini, 將max_initial_size=15改為max_initial_size=max_size
    或者
    在調用sa-compile.pl生成的extract.ini文件中, 將max_initial_size=15改為max_initial_size=max_size
    (注: sa-extract/extract.ini是一個extract.ini的模板文件, sa-compile.pl輸出的extract.ini文件是以該文件為模板)
3)修改cdec.ini文件, 將scfg_max_span_limit=12改為scfg_max_span_limit=100000

2013年3月4日星期一

使用zpar的分词功能

1) 下载zpar http://faculty.sutd.edu.sg/~yue_zhang/doc/index.html
2) 阅读Chinese word segmentation文档http://faculty.sutd.edu.sg/~yue_zhang/doc/doc/segmenter.html 写得很清楚, zan
3) 编译make segmentor (将生成dict/segmentor/***)
4) 训练
     ./dist/segmentor/train <train-file> <model-file> <number of iterations>
     ./dist/segmentor/train ctb6.0/ctb6.0.train.segmented.txt ctb6.0/ctb6.0.seg.model 1
    (最后一个参数是迭代次数, 可以使用test.sh多次迭代然后选择最优值, 见Chinese word segmentation文档6 How to tune the performance of a system)
    (下载evaluate.py http://faculty.sutd.edu.sg/~yue_zhang/doc/doc/seg_files/evaluate.py)
    (需要修改test.sh里的一些文件名称路径等, 每次迭代会在原先迭代的基础上完成, 即为什么test.sh中总是执行$segmentor/train train.txt model 1)

#####test.sh#####
segmentor=dist/segmentor

rm model

for i in `seq 1 30`;
do
echo "iteration $i"
$segmentor/train ctb6.0/ctb6.0.train.segmented.txt model 1
$segmentor/segmentor model ctb6.0/ctb6.0.deve.unseg.txt ctb6.0.deve.autoseg.txt
python evaluate.py ctb6.0.deve.autoseg.txt ctb6.0/ctb6.0.deve.segmented.txt
cp model ctb6.0/ctb6.0.seg.model.$i
done
迭代18次的log:

239 iteration 18
240
241 Training started ...
242 Loading model ... done (8.39196s).
243 Computing averaged feature scores ... done
244 Saving model ... done.
245 Done.
246 Training has finished successfully. Total time taken is: 49.2729
247 Segmenting started
248 Loading model ... done (8.06785s).
249 Segmenting has finished successfully. Total time taken is: 11.2431
250 Word precision: 0.955604476243
251 Word recall: 0.955700108415
252 Word F-measure: 0.955652289936




5) 测试
    ./dist/segmentor/segmentor ctb6.0/ctb6.0.seg.model.18 ctb6.0/ctb6.0.test.unseg.txt ctb6.0.test.autoseg.txt

python evaluate.py ctb6.0.test.autoseg.txt ctb6.0/ctb6.0.test.segmented.txt

Word precision: 0.951947892344
Word recall: 0.949520704111
Word F-measure: 0.950732749098



   
 

使用stanford segmenter

1) 下载 http://nlp.stanford.edu/software/segmenter.shtml 当前最新版本为
1.6.72012-11-11. 大小为200M+, 其中的中文训练数据ctb.gz和pku.gz占了大概200M. 
将jar -xf stanford-segmenter-1.6.7-sources.jar 解压的文件夹放入src文件夹中.
用ant编译, 得到classes/文件夹

(jar xf stanford-segmenter-1.6.7-sources.jar
 mkdir src
 mv edu src/edu
 ant
 jar cvf seg.jar -C classes/ .)
这样生成新的seg.jar文件


2) 训练
  从ctb6.0中抽取了数据(train/test/deve按xue cl 08划分, train/test/deve:23420/2796/2079句)
  ctb_v6/data/utf8/bracketed/chtb_3095.fid的第89行((WHNP-4改为(CP (WHNP-4, 同时将第91行最前面的CP去除, 该句子为((IP (NP (CP (CP (IP (NP (NN 地方)(NN 当局))(VP (ADVP (AD 正在))(VP (VV 组织))))(DEC 的)))(ADJP (JJ 紧急))(NP (NN 求援)))(PU ,)(ADVP (AD 但是))(PP (P 据)(NP (NN 报道)))(PU ,)(NP (CP (CP (IP (VP (QP (CD 1多))(VP (VA 深))))(DEC 的)))(NP (NN 大雪)))(VP (PP (P 给)(NP (NN 求援)(NN 工作)))(VP (VV 造成)(AS 了)(NP (CP (CP (IP (VP (ADVP (AD 极))(VP (VA 大))))(DEC 的)))(NP (NN 困难)))))(PU 。)))

下载http://nlp.stanford.edu/software/trainSegmenter-20080521.tar.gz
大小为100M, 其中包括了中文ctb6.0的数据.
1) 准备 ctb6.train, ctb6.dev, and ctb6.test (需要按照ctb6.0的格式来准备, 会用到postagged信息)
2) 修改Makefile里面的
CTB6=/path/to/ctb6.0/
SEGMENTER=/path/to/stanford-chinese-segmenter-2012-11-11/
修改time java6 --> time java
3) make all
如果在第三步出错 可查看logs/ctb6.err
在8g内存机器上, 大概需要1个小时.

在Makefile里发现在训练的时候需要用到-serDictionary $(SEGMENTER)/data/dict-chris6.ser.gz
不知道dict-chris6.ser.gz内容是什么, 但应该不是从我提供的训练集中得到的...
(如果忽略这个东西, 把训练生成的mode/ctb6.ser.gz移到stanford-segmenter-2012-11-11/data/下, 去 替换ctb6.gz(还未试过))

2013年2月17日星期日

citibank网上银行往国内转账


1) citibank支持网上转账, 手续费是30$每笔(网上转要比到柜台转便宜些)

2) 选择网上转账及相关验证后, 需要填写/选择的项包括:
    a. Foreign Currency or US Dollars, 选择US Dollars, 即以美元的行式转到国内账号, 这可能要求国内账号有存储外币功能(听同事说到中国银行申请外币存储时需要预存大概100刀的样子). 不知道是不是选择US Dollars再到国内转成人民币要比直接选择Foreign Currency要划算一点?
    b. Select destination country: 选China
    c. enter bank's swift/bic: 这个可以问国内银行提供, 中国银行的也可以参考http://www.bankba.net/swiftcode/bc.htm, 这里我选择的是苏州分行(SUZHOU BRANCH) BKCHCNBJ95B

3) 下一个页面
      Beneficiary Name: 接收人姓名, 拼音就好, 但要确定名字拼音之间是否有空格 (比如: LI XIAO MING, LI XIAOMING). 这个应该看卡上都有
      Amount: 转出金额
     When: 可以选择单次转,还是按周期转(比如每周转一次等)

4) 下一个页面
     两部分信息, 一是关于接收人的信息:
    输入接收人的姓名/电话/地址/账号 (地址栏我空着, 没提供)
    Special instructions: 应该类似于附言, 填写吴江市分行的名称和地址(应该不填也没关系)
    另一信息是银行的信息:
    由于在前面输入了接收银行的swift code, 这个页面会自动填上银行的信息(比如苏州中国银行). 虽然转入的银行是吴江市分行, 但应该没问题, 都是苏州, 不去改动.
    CHIPS/UID#, 不太知道是什么, 但好像是跟银行与地址对应起来的代码, 类似邮政编码的功能?? 没有填写
    Intermediary Bank: 这里没有填写, 因为是直接转到中国银行, 应该不需要再来一个中转行. (是不是说如果转到国内一个小银行或地方性银行, 需要中转行??)

5) 下一个页面
    确定下就好..

6) 补充
    30$手续费是另付, 不是从汇出金额中扣. 大概两天就到国内账号上. 银行不会通知, 即不需要收件人确定. 中国银行会扣除12$作为手续费.