首页 > 编程知识 正文

java开源项目,编译原理词法分析程序java

时间:2023-05-05 22:14:04 阅读:110471 作者:1800

LTP是哈佛大学开源中文语言处理系统,涵盖基本功能。 分词、词性标注、命名实体识别、依存句法分析、语义角色标注、语义依存分析等。

【开源中文分词工具探析】系列:

1 .前言

与THULAC相同,LTP也基于结构化感知器(Structured Perceptron,SP ),在最大熵标准下对注释序列$Y$输入序列$X$时的score函数进行模型化。

$$s(y,x ) ) sum_s ) alpha_s ) phi_s ) y,x ) $$

其中$phi_s(y,x ) $是本地特征函数。 中文分词问题等价于给定$X$数组,求解与score函数最大值相对应的$Y$数组:

$$mathop{argmax}_ys(y,x ) $$

2 .分解

以下源代码分析基于3.4.0版。

分词流程

分词的流程和其他分词器一样。 首先提取文字特征,计算特征的权重值,然后对Viterbi进行解码。 有关代码的详细信息,请参阅_ _ LTP _ dll _ segmentor _ wrapper 33603360 segment (

intsegment(constchar*str,STD :3360 vector : string words ) )

LTP :框架: viterbifeaturecontextctx;

LTP :框架: viterbiscorematrixscm;

LTP :框架:虚拟编码解码器;

LTP : segmentor :实例inst;

intret=preprocessor.preprocess (str,inst.raw_forms,inst.forms,

inst.chartypes;

if(-1==ret||0==ret ) {

words.clear (;

返回0;

}

LTP : segmentor : segmentationconstraincon;

con.regist((Inst.chartypes ) );

build _ lexicon _ match _ state (lexicons,inst );

extract_features(Inst,model,ctx,false );

calculate_scores(Inst,(*model ),ctx,true,scm );

//allocateanewdecodersothatthesegmentorsupportmultithreaded

//decoding.thismodificationwascommittedbyniuox

decoder.decode(SCM,con,inst.predict_tagsidx );

build_Words(Inst.raw_forms,inst.predict_tagsidx,words );

return words.size (;

}

训练模式

模型文件cws.model包含类别、特征、权重、内部词典(internal lexicon )等。 用Java重写了模型分析。 代码如下。

datainputstreamis=new data inputstream (new file inputstream (path );

char[]octws=readchararray(is,128 );

//1 .读标签

smartmaplabel=readsmartmap(is;

int[]Entries=readintarray(is,label.numEntries );

//2 .读功能空间

char[]space=readchararray(is,16 );

intoffset=readint(is;

intSZ=readint(is;

smart map [ ] dicts=newsmartmap [ SZ ];

for(intI=0; i sz; I ) {

dicts[I]=readsmartmap(is;

}

//3 .读我

char[]Param=readchararray(is,16 );

intdim=readint(is;

double[]w=readdoublearray(is,dim );

double [ ] wsum=readdoublearray (is,di

m);

int lastTimestamp = readInt(is);

// 4. read internal lexicon

SmartMap internalLexicon = readSmartMap(is);

// read char array

private static char[] readCharArray(DataInputStream is, int length) throws IOException {

char[] chars = new char[length];

for (int i = 0; i < length; i++) {

chars[i] = (char) is.read();

}

return chars;

}

// read int array

private static int[] readIntArray(DataInputStream is, int length) throws IOException {

byte[] bytes = new byte[4 * length];

is.read(bytes);

IntBuffer intBuffer = ByteBuffer.wrap(bytes)

.order(ByteOrder.LITTLE_ENDIAN)

.asIntBuffer();

int[] array = new int[length];

intBuffer.get(array);

return array;

}

LTP共用到了15类特征,故sz为15;特征是采用Map表示,LTP称之为SmartMap,看代码本质上是一个HashMap。分词工具测评结果表明,LTP分词速度较THULAC要慢。究其原因,THULAC采用双数组Trie来表示模型,特征检索速度要优于LTP。

特征

LTP所用到的特征大致可分为以下几类:

unigram字符特征 ch[-2], ch[-1], ch[0], ch[1], ch[2]

bigram字符特征 ch[-2]ch[-1], ch[-1]ch[0],ch[0]ch[1],ch[1]ch[2]

字符类型特征 ct[-1], ct[0], ct[1]

词典属性特征 ch[0]是否为词典开始字符、中间字符、结束字符

源码见extractor.cpp:

Extractor::Extractor() {

// delimit feature templates

templates.push_back(new Template("1={c-2}"));

templates.push_back(new Template("2={c-1}"));

templates.push_back(new Template("3={c-0}"));

templates.push_back(new Template("4={c+1}"));

templates.push_back(new Template("5={c+2}"));

templates.push_back(new Template("6={c-2}-{c-1}"));

templates.push_back(new Template("7={c-1}-{c-0}"));

templates.push_back(new Template("8={c-0}-{c+1}"));

templates.push_back(new Template("9={c+1}-{c+2}"));

templates.push_back(new Template("14={ct-1}"));

templates.push_back(new Template("15={ct-0}"));

templates.push_back(new Template("16={ct+1}"));

templates.push_back(new Template("17={lex1}"));

templates.push_back(new Template("18={lex2}"));

templates.push_back(new Template("19={lex3}"));

}

#define TYPE(x) (strutils::to_str(inst.chartypes[(x)]&0x07))

data.set("c-2", (idx - 2 < 0 ? BOS : inst.forms[idx - 2]));

data.set("c-1", (idx - 1 < 0 ? BOS : inst.forms[idx - 1]));

data.set("c-0", inst.forms[idx]);

data.set("c+1", (idx + 1 >= len ? EOS : inst.forms[idx + 1]));

data.set("c+2", (idx + 2 >= len ? EOS : inst.forms[idx + 2]));

data.set("ct-1", (idx - 1 < 0 ? BOT : TYPE(idx - 1)));

data.set("ct-0", TYPE(idx));

data.set("ct+1", (idx + 1 >= len ? EOT : TYPE(idx + 1)));

data.set("lex1", strutils::to_str(inst.lexicon_match_state[idx] & 0x0f));

data.set("lex2", strutils::to_str((inst.lexicon_match_state[idx] >> 4) & 0x0f));

data.set("lex3", strutils::to_str((inst.lexicon_match_state[idx] >> 8) & 0x0f));

#undef TYPE

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。