502 Star 2.1K Fork 624

GVP狮子的魂 / jcseg

 / 详情

简体繁体相互检索

已完成
创建于  
2018-08-23 10:19

您好作者,
对于将jcseg作为elasticsearch的分词器,想实现中文简体和繁体的相互检索,可行的方法是什么呢?希望您能给些思路啊,看介绍说jcseg有简体和繁体的转换工具什么的没有找到啊。

评论 (12)

xwz 创建了任务

里面确实有个简繁体的转换程序,不过不太精确,比较久前就关闭该功能了。
你可以设置繁体字为简体字的同义词,然后通过同义词合并来实现这个功能,或者反过来。

@狮子的魂 这样的话我需要把词典的所有词的繁体和简体的同义词关系维护到lex-synonyms.lex文件中,工作量很大啊。jcseg目前可用的只有一套词库吗?还是有三套,简体、繁体、简体繁体混合?

写个程序自动生成下面的格式(运行一下也就一两分钟的事情):

简体词条1,转换后的繁体词条1
简体词条2,转换后的繁体词条2

然后通过jcseg的同义词合并功能,繁体词条在索引过程中变成简体词条,检索的时候简体或者繁体词条都会转成简体来检索。

@xwz 之前有简体,繁体词库,后面因为精度问题,我都去掉了,目前只有简体,繁体词库通过工具转下就OK了。

@狮子的魂 还有个问题,就是拼音检索方面的,之前搜索拼音可以检索到对应的汉字,但是elasticsearch高亮会出现高亮字数增多的情况,所以我自己对追加拼音那块代码做了些修改,将汉字对应的拼音长度设置成和汉字长度相等,这样高亮问题就解决了,不知道这样解决会影响到其他功能吗?

理论上直接设置词条的长度这个方案不不能工作的,这个问题是下个版本的重点。
我不知道你怎么设置的,如果知识通过设置长度工作了,应该是es截取了拼音的长度,会影响检索的结果。

@狮子的魂 ES的源码我没有去研究过,所以怕会有影响啊。我是在追加拼音那块加了下拼音的追加方式,比如词北京,获取它的拼音,会是bei jing,然后我会将其中的空格去掉变成beijing,然后将beijing的拼音长度改成和汉字北京的长度相等,加到wordPool里面,这样再搜索beijing的时候,汉字北京能够正确高亮并且返回。单字北和京同理啊。

我用大批量的数据测试,返回结果打分确实不一样了,但是返回的结果是差不多的。毕竟同音的字还是很多的,势必影响返回结果的。

@xwz 这种方式可以工作,本质上其实拼音的长度写进索引的时候被截取了(BytesRef被截取),也就是可能会小概率的出现不相干的结果,例如beijing其实写进索引只是beijin(g丢掉了,因为北京utf-8编码六个字节),打分不一样是肯定的,文档长度增加了BM25模型打分自然不一样了。
你可以试试使用luke工具看下索引进去的具体的词条。

@狮子的魂 用luke看了下,没有截断啊。比如北京,对应的拼音就是bejing啊,看来ES没有对其进行截取。
输入图片说明

还有,发现jcseg的词库中对da这个单字读音缺失啊,不管是伟大、大人对应的单字大的读音都是dai,是故意要设计成这样的?

不是的,是bug,jcseg的很多词条的都是机器组成的,难免有些错误。
如果索引没问题,那这样能工作挺好的,分享下你的代码?

@狮子的魂 好的,通过读代码,切分后追加拼音是在/jcseg-core/src/main/java/org/lionsoul/jcseg/tokenizer/ASegment.java类下的方法appendWordFeatures中
我在ASegment.java中声明了两个私有变量
private static int pinyinLengthTmp;
private static String pinyinTmp;
然后对appendWordFeatures方法做了改造:`/**
* check and append the pinyin and the synonyms words of the specified word
*
* @chancelai word
/
protected void appendWordFeatures( IWord word )
{
//add the pinyin to the pool
/
if ( config.APPEND_CJK_PINYIN
&& config.LOAD_CJK_PINYIN && word.getPinyin() != null ) {
IWord pinyin = new Word(word.getPinyin(), IWord.T_CJK_PINYIN);
pinyin.setPosition(word.getPosition());
pinyin.setEntity(word.getEntity());
wordPool.add(pinyin);
}*/
if ( config.APPEND_CJK_PINYIN
&& config.LOAD_CJK_PINYIN && word.getPinyin() != null ) {
pinyinLengthTmp = word.getLength();
pinyinTmp = word.getPinyin();
if (pinyinTmp.contains(" ")) {
IWord pinyin = new Word(pinyinTmp.replace(" ", ""), IWord.T_CJK_PINYIN);
pinyin.setLength(pinyinLengthTmp);
pinyin.setPosition(word.getPosition());
pinyin.setEntity(word.getEntity());
wordPool.add(pinyin);
} else {
IWord pinyin = new Word(pinyinTmp, IWord.T_CJK_PINYIN);
pinyin.setLength(pinyinLengthTmp);
pinyin.setPosition(word.getPosition());
pinyin.setEntity(word.getEntity());
wordPool.add(pinyin);
}
}

    //add the synonyms words to the pool
    if ( config.APPEND_CJK_SYN 
            && config.LOAD_CJK_SYN && word.getSyn() != null ) {
        SegKit.appendSynonyms(wordPool, word);
    }
}`

提交评论后代码格式乱了,截图如下:
输入图片说明
输入图片说明

原词和同义词的字数不同高亮问题也可以解决了,我才修改代码测试了下,好使。
输入图片说明
输入图片说明

狮子的魂 负责人设置为狮子的魂
狮子的魂 添加了
 
同义词
标签
狮子的魂 添加了
 
高亮异常
标签
狮子的魂 添加了
 
解决方案
标签
狮子的魂 任务状态待办的 修改为进行中
狮子的魂 任务状态进行中 修改为已完成

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(2)
5187 lionsoul 1578914315
Java
1
https://gitee.com/lionsoul/jcseg.git
git@gitee.com:lionsoul/jcseg.git
lionsoul
jcseg
jcseg

搜索帮助