2009年4月15日星期三

ictclas4j bug小结

bug:
1“邓颖超”2深圳的“圳”3发飙的“飚”4發财的“發”5“月份牌”6单独的“年”字

1、邓颖超
分词后漏掉“邓颖”只剩“超”
解决办法:(转http://tinypig.javaeye.com/blog/250926
修改方法是将ictclas4j中PosTagger类的personRecognize方法里面的这段代码

if (sn.getPos() < color="#ff0000">personName += sn.getSrcWord();
也就是将该if判断句的条件部分注释掉,同时将getWord改为getScrWord

深圳的“圳”, 发飙的“飚”
运行异常:说是Dictionary.java中getMaxMatch(String word)函数中的pointernull异常,调试发现是wis=null,
解决方法:将原程序中的语句 for (int j = 0; j < color="#ff0000">for (int j = 0; j 小于 wis.size()&&wis!=null; j++)

对于發财的“發” 解决办法:
将Dictionary.java中的findInOriginalTable方法里的
if (res != null && wts != null )
{ WordTable wt = wts.get(index);
……
}
改为 if (res != null && wts != null && index>=0 && index小于wts.size())
{ WordTable wt = wts.get(index);
……
}

bug5:“月份牌”出现死循环,网友发现
解决办法:
出错位置:org.ictclas4j.segment.GraphGenerate类中源代码90行左右
WordItem wi = null;
for (; j <= atoms.size(); j++) { int totalFreq = 0; wi = dict.getMaxMatch(word); if (wi != null) { // find it if (word.equals(wi.getWord())) { ArrayList wis = dict.getHandle(word); for (WordItem w : wis)totalFreq += w.getFreq();// 1年内,1999年末 if (word.length() == 2 && segGraph.getSize() > 0)
{SegNode g2 = segGraph.getLast();
if(Utility.isAllNum(g2.getWord())
Utility.isAllChinese(g2.getWord())&& (g2.getWord().indexOf("年") == 0 g2.getWord().indexOf("月") == 0))
{if ("末内中底前间初".indexOf(word.substring(1)) != -1)break;}}// 只有一个性词,存贮它
SegNode sg = null;
if (wis.size() == 1)
sg = new SegNode(i, j,wis.get(0).getHandle(),totalFreq , word);
else sg = new SegNode(i, j, 0,totalFreq , word);
segGraph.insert(sg, true);}
if (flag) //此两行不应该放在这,应该放到这个for循环的外面,否则“月份”后面如果有词构成一个词的话会出错如“月份牌”是一个词。
i++; //就会出错,将其放在for循环外
if (j < word2 =" atoms.get(j).getWord();word">

bug6:输入:"年"或“年加一个与年不成词的词” 输出:“始##始年”
问题原因:AdjustSeg.java中对“年”做了特殊判断,而单独的“年”在开头与起始符号“始##始”分在一起了 解决办法: 在文件第80行左右将程序改为: else if ("年".equals(curWord))
{ if (!prevsn.getWord().equals("始##始")&& prevsn != null &&Utility.isYearTime(prevsn.getSrcWord()))
{prevsn.setCol(sn.getCol());
prevsn.setWord(Utility.UNKNOWN_TIME);
prevsn.setSrcWord(prevsn.getSrcWord()+curWord);
prevsn.setPos(-POSTag.TIME); continue; } }
即在if的判断条件里添加语句:!prevsn.getWord().equals("始##始")
new bug? new solution!



续:病有猪流感,bug有新内容
某个不和“發”成词的字 + “發”,比如 :淘發
类比 ,其他生僻字或者繁体字(GB2312外的?)分词结果为“淘”即出现丢字现象。


原因:这类字的pos=4,然后结尾标志“末##末”也是4,然后就被丢弃了

解决:加个判断,别让他们丢……

具体方法:在PosTagger.java的第100行左右
switch (tagType)
{ case TT_NORMAL:
for (SegNode sn : sns)
{ if (sn.getPos() == 0)
{ sn.setPos(getBestTag(sn));
}
}
}

改为

switch (tagType)
{ case TT_NORMAL:
for (SegNode sn : sns)
{ if (sn.getPos() == 0)
{ //sn.setPos(getBestTag(sn));
sn.setPos(getBestTag(sn)==4?3:getBestTag(sn));//修改此行,使pos=4的不被当成结尾,可以在处理繁体字时不丢字
}
}
}

然后就ok了。

没有评论: