- 論壇徽章:
- 0
|
本帖最后由 huihui_2012 于 2012-06-16 13:19 編輯
WRSeg分詞器的java工程模塊
本文所實(shí)現(xiàn)的WRSeg分詞器以java語言開發(fā)。主要步驟在ChineseSegment這個(gè)工程中實(shí)現(xiàn)。這個(gè)工程引用了Tools工程中的一些工具類。因此,在使用時(shí),要將Tools導(dǎo)入到ChineseSegment中。源代碼見附件。源代碼內(nèi)有已經(jīng)訓(xùn)練好的分詞器,用戶可以直接使用。因?yàn)槭芨郊笮〉南拗疲嫉挠?xùn)練語料沒有在源代碼包中(訓(xùn)練語料用的是北大標(biāo)注的1998年1月的語料)。
源代碼僅供學(xué)術(shù)參考使用,若用于商業(yè)用途,請聯(lián)系我:zhonghui830506@163.com
ChineseSegment項(xiàng)目的目錄結(jié)構(gòu)如下:
QQ截圖20120616115024.png (72.81 KB, 下載次數(shù): 36)
下載附件
2012-06-16 11:50 上傳
其中Count類是用來統(tǒng)計(jì)詞頻,進(jìn)而計(jì)算成詞概率的類;CountBiGram繼承Count,專門對二元語法概率進(jìn)行計(jì)算。
MergeNameEntity類是用于解決人名、地名、機(jī)構(gòu)名等的詞語粒度問題。在原始語料中,人名中姓和名字被當(dāng)作是兩個(gè)詞語。如“江 澤民”中姓氏“江”和名字“澤民”被當(dāng)作兩個(gè)詞語。但是,這往往不符合實(shí)際需求。在實(shí)際需求中,我們通常不希望將名字分割。在地名、機(jī)構(gòu)名中也會(huì)存在類似的情況。MergeNameEntity類中提供方法將人名、地名、機(jī)構(gòu)名中的各個(gè)組成部分合成一個(gè)單一的詞語。
統(tǒng)計(jì)的成詞概率結(jié)果放在數(shù)據(jù)結(jié)構(gòu)類SegModel類的對象中。
UnigramSeg是利用Unigram語法,利用動(dòng)態(tài)規(guī)劃進(jìn)行分詞的類。BigramSeg是利用二元語法進(jìn)行分詞的類。
199801q.txt是原始訓(xùn)練語料,語料中的人名、地名和機(jī)構(gòu)名都沒有采取MergeNameEntity類中所提供的合并策略。詞典.txt是前面所提到的外部詞典,里面的詞語不是來自于199801q.txt。
biWordRate.out,wordFrequence.out,wordRate.out都是已經(jīng)訓(xùn)練好的分詞模型。這些模型中都已經(jīng)對人名中的姓氏和名字進(jìn)行了合并,但是沒有對地名和機(jī)構(gòu)名進(jìn)行MergeNameEntity類中所提供的合并。wordFrequence.out是基于wordfreq的一元語法,wordRate.out是基于wordrate的一元語法。biWordRate.out是基于二元語法,分詞效果最好。
SplitSentence_seg是基于分詞開發(fā)的一些工具方法,可以忽略。
調(diào)用示例
調(diào)用方法。下面的例子展示了如何調(diào)用本文所述的工程:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.tseg.seg.SegModel;
import org.tseg.seg.BigramSeg;
public class ChineseSegment {
//假如原句是:
// 鄧玉嬌是湖北人,在09年是熱點(diǎn)新聞人物
// 則分詞后的結(jié)果是(返回結(jié)果的詞語之間用空格隔開):
// 鄧玉嬌 是 湖北 人 , 在 09年 是 熱點(diǎn) 新聞 人物
public String seg(String line){
//用單例方法來獲得分詞器,這樣為了避免分詞器的重復(fù)加載
BigramSeg seg = BigramSeg.getSeg();
return seg.segment(line);
}
//假如原句是:
// 鄧玉嬌是湖北人,在09年是熱點(diǎn)新聞人物
// 則分詞后的結(jié)果是(返回結(jié)果放在一個(gè)ArrayList中):
// [鄧玉嬌, 是, 湖北, 人, ,, 在, 09年, 是, 熱點(diǎn), 新聞, 人物]
public ArrayList<String> getSegList(String line){
//用單例方法來獲得分詞器,這樣為了避免分詞器的重復(fù)加載
BigramSeg seg = BigramSeg.getSeg();
return seg.getSegWordList(line);
}
// 給分詞器加入新詞
public BigramSeg seggerWithNewWords(Collection<String> newWords){
//沒有用取得單例的方法來獲得分詞器,這是為了不讓新生成的分詞器影響別的應(yīng)用
BigramSeg seg = new BigramSeg(SegModel.biWordRateType);
for(String word : newWords){
if(!seg.getModel().wordLogProb.containsKey(word)){
seg.getModel().wordLogProb.put(word, 0.0);
}
}
return seg;
}
//將加入了新詞的新的分詞器保存到文件中
public void save(BigramSeg seg, String segPath) throws IOException{
seg.getModel().writeModel(segPath);
}
//從文件中讀取分詞器
public BigramSeg read(String segPath) throws IOException{
return new BigramSeg(segPath);
}
public void segTest() throws IOException{
String line = "鄧玉嬌是湖北人,在09年是熱點(diǎn)新聞人物";
System.out.println(this.seg(line));
System.out.println(this.getSegList(line));
line = "鄧玉嬌刺官案在社會(huì)上反響很大!";
System.out.println(this.getSegList(line));
// 輸出結(jié)果:[鄧玉嬌, 刺, 官案, 在, 社會(huì), 上, 反響, 很, 大, !]
Set<String> newWords = new HashSet<String>();
newWords.add("刺官案");
BigramSeg seg = this.seggerWithNewWords(newWords); //往分詞器里加入新詞,生成一個(gè)新的分詞器
System.out.println(seg.getSegWordList(line));
// 輸出結(jié)果:[鄧玉嬌, 刺官案, 在, 社會(huì), 上, 反響, 很, 大, !]
String segPath = "D:/xing/seg.out";
this.save(seg, segPath); //保存新分詞器
BigramSeg newSeg = this.read(segPath); //讀取剛保存的新分詞器
System.out.println(newSeg.getSegWordList(line));
// 輸出結(jié)果:[鄧玉嬌, 刺官案, 在, 社會(huì), 上, 反響, 很, 大, !]
}
public static void main(String args[]) throws IOException{
ChineseSegment cst = new ChineseSegment();
cst.segTest();
}
}
|
-
-
Tools.rar
2012-06-16 11:52 上傳
點(diǎn)擊文件名下載附件
542.71 KB, 下載次數(shù): 19
-
-
ChineseSegment.rar
2012-06-16 12:04 上傳
點(diǎn)擊文件名下載附件
4.7 MB, 下載次數(shù): 30
|