SunPinyin-2.0模糊音节切分的实现

模糊切分,即根据上下文,将有歧义的拼音字符串进行自动切分,例如,将fangan切分为fang'an或fan'gan。这是许多现代拼音输入法都具备的功能。SunPinyin的ime-core本身具有搜索多种切分组合的能力,只要在buildLattice时,保证传入的segments是按照起始位置(m_start)排好顺序的即可。

那么首先要解决的问题就是,根据得到的最佳句子,反查到对应的切分序列。例如,最佳句子是“我的方案获得通过”,可以推得“wo'de'fang'an'huo'de'tong'guo”。

我们为TLexiconState加入了m_seg_path的成员,用来记录这个LexiconState对应的切分路径,例如我们有一个lexiconState对应是上例中的fang'an,其切分路径是[4, 8, 10]。然后,为CLatticeState加入了m_pLexiconState成员,用来记录之前transfer时所引用的那个lexiconState。这样,在backTrace最佳句子的时候,就可以得到对应的音节了。由于易混淆音(即z<->zh)的存在,一个seg_path可能对应多个syllable_paths(m_syls);但是最后在存入用户词典时,必须要知道真实的syllables,所以没有采用TLexiconState结构包含一个seg_path、和多个syllable_paths的方案。

接下来,就是该如何产生模糊切分的了。我们为CPinyinData类加入了一些额外的table,这些table都是使用pinyin_data.py脚本生成的。包括fuzzy_finals_map,这是为处理型如xian->xian/xi'an的模糊切分的;以及fuzzy_pre_syllables和fuzzy_pro_syllables,分别代表可能产生切分歧义的前一个音节和后一个音节。经过pinyin_data.py的筛选,发现只有“r/g/n”三个声母,可能作为前一个音节的结尾,或后一个音节的声母。

接下来,我们为CQuanpinSegmentor加入了一个新的helper functor,CGetFuzzySegmentsOp。这个助手类的输入是主切分器(即基于double-array trie的、改良的、最大后向匹配算法)所得到的segments;输出是,其对应的模糊切分segments。这个寻找模糊切分的过程,和切分器的主过程是平行的。但是,我们并不是简单的每次输入都从头到尾扫描一遍。

首先,根据主切分序列的最后一个segment(记为seg),invalidate那些受影响的fuzzy segments。在我们目前的实现中,fuzzy_segs中的模糊切分都是成对出现的,我们从后向前一对一对的进行筛选,只有当某一对的右边界(r),小于或等于seg的起始位置,才能够保留下来。然后,我们仅需要对主切分的最后一个切分(如果是xian的情况),或最近两个切分(如果是fangan的情况),进行处理。然后小心地调整好updatedFrom的值,并返回给CQuanpinSegmentor::_push()。

因此,如果输入xian,会生成xian和xi'an的两种切分,如果继续输入一个a,则会得到xia'na和xian'a,而不会包括xi'an'a这个切分了。主切分器的最后一个segment(即na),会先将xi'an给invalidate掉;然后辅助切分器会将xian'a加入到fuzzy_segs中。从这一点来说,我们和google和sogou输入法的处理仍然有所不同,他们都会保留xi'an'a这个切分。

我个人的感觉,sogou和google输入法每次在追加或删除一个拼音字符时,都是会从头进行一遍扫描处理;其间处理了各种情况,包括易混淆音,自动就错,和模糊音节切分等。而SunPinyin的push/pop操作,尽可能少的对拼音字符串进行扫描和匹配,应该来说效率要高一些。而且,我感觉目前的这种实现方式,也基本满足大家的需要了。:)

返回到_push方法之后,如果设置了易混淆音,就对m_fuzzy_segs的最后两个segments,加入易混淆音。无论之前是否已经加入过易混淆音,CQuanpinSegmentor::_addFuzzySyllables都会先将seg.m_syllables resize为1,即清空了之前的易混淆音。

最后,在getSegments()时,将m_fuzzy_segs和m_segs合并到m_merged_segs中,并按照m_start排好顺序,返回给外层的调用者。我们今后可能会改进这部分,其实m_segs和m_fuzzy_segs都是有序的,只要让CIMIContext::buildLattice可以按照m_start的顺序,同时迭代这两个有序的vector就可以了。

还有其他的一些辅助的修改,例如,CIMIContext::getCandidates的循环退出条件不同了,导致我们现在迭代的次数会明显增多了,需要想一些更好的解决方法。

22 thoughts on “SunPinyin-2.0模糊音节切分的实现

  1. 哎,郁闷啊!刚发现一个很麻烦的问题,就是不能输入中文的空心句号,只能输入这种“·”符号,输入状态明明是中文的,逗号都很正常,可是空心句号出不来,英文状态下能出实心的句号.请问这是什么原因啊?有啥办法解决么?是不是因为笔记本键盘特殊?我的笔记本键盘逗号和句号的按键上面都有三个状态,句号的按键可以输入“.”“>”“·”三种符号,最后一个“·”一般需要fn键配合,但是现在中文标点状态下直接就是“·”而非空心句号,抓狂啊!

  2. @乌斑兔小白,不知道您使用的是那款笔记本?实在不行可以帮我们调试一下,在代码中手工改映射关系试一试 ...

  3. 笔记本是惠普的dv5264ea,需要在代码中手工改映射关系阿?晕,实在是不知道怎么修改。奇怪的是用其他的输入法都可以正常输入空心句号,唉,当然目前更加郁闷的是重新安装了系统,不知道是不是因为最近新发布补丁的原因,sunpinyin无论如何也不能被ibus加载,pkg-config sunpinyin-2.0 --modversion也能看到返回值2.0.1。一切操作都是按照说明进行的,不论有没有指定 --prefix=/usr都不管用。下面是我编译用的指令:
    sudo scons --prefix=/usr
    sudo scons install --prefix=/usr
    pkg-config sunpinyin-2.0 --modversion来查看是否安装成功
    cd wrapper/ibus
    sudo scons --prefix=/usr
    sudo scons install --prefix=/usr
    上次就是这样顺利启动了sunpinyin,但是这次不行了,真是欲哭无泪阿!还请高手救命阿!补充一下,这次安装有点曲折,刚开始忘记了把ibus升级到1.3.7,直接用的是ubuntu安装盘里的老版本,发现sunpinyin无法启动才赶紧升级ibus,然后用sudo scons -c install卸载,重新解压编译,折腾了三四次,反复重启ibus还是不行....55555

  4. 安装文件是从官网上下载的,补丁也是。不过,上次顺利安装是一个修改版,ylmf os 3.0,:-)
    不满意ylmf,所以换装官网的,没想到sunpinyin出了问题5555

  5. 刚才安装了一次,还是失败!真是郁闷,不知道安装输入法前端的时候,下面返回信息有没有用,烦请大侠给看看,谢谢!
    scons --prefix=/usr

    scons: Reading SConscript files ...
    Checking for pkg-config... yes
    Checking for ibus-1.0... no

    sudo scons install --prefix=/usr

    scons: Reading SConscript files ...
    Checking for pkg-config... yes
    Checking for ibus-1.0... no

  6. @乌斑兔小白,貌似你没有安装ibus-devel这个包,导致sunpinyin没有编译通过啊 ...

  7. 个人揣测,sunpinyin没能用起来应该是前端没能编译成功,看错无信息说是没能找到ibus-1.0,奇怪阿!我这次安装乌斑兔接连装了两次(都是官网的10.04,不是ylmf),第一次安装因为更新flash异常缓慢,无法安装其他重要更新,一怒之下就直接覆盖重装,先装了重要更新,然后是flash,这次就比较顺利。但是,sunpinyin出了问题,真不知道如何解决,还请大侠多多指教!如何顺利通过前端的编译,谢谢!另外,sunpinyin的句号问题也想问问如何修改。

  8. 哦,多谢大侠,ibus-devel没安装?不会吧,我现在就用的ibus拼音阿,都是从官网上升级安装的,我去查查看。

  9. 刚才去查了一下,的确是按照ibus的说明安装的,指令如下,看来是没有您说的ibus-devel,真是郁闷!
    sudo add-apt-repository ppa:shawn-p-huang/ppa
    sudo apt-get update
    sudo apt-get install ibus-gtk ibus-qt4 ibus-pinyin ibus-pinyin-db-open-phrase

  10. 冒昧问一句ibus-devel如何安装啊?谢谢,我尝试了下面命令,但是没找到包,又去软件中心翻了翻,只找到一个最接近的包libibus-qt-dev,是这个么?
    sudo apt-get install ibus-devel
    正在读取软件包列表... 完成
    正在分析软件包的依赖关系树
    正在读取状态信息... 完成
    E: 无法找到软件包 ibus-devel

  11. 呵呵,终于搞定了!就是依赖关系没解决,后来还添加了gettext,才顺利安装完毕,谢谢大侠的指点!另外,这次安装上了还有个意外收获,就是空心句号问题也不存在了,一切正常,哈哈哈!不过,对于音节切分功能,很好用,赞一个!

  12. 有个小小疑问,不知道sunpinyin如何输入一些常用的聊天表情呢?比如这几个
    :-) ^_^ ,还有当前时间、日期的快速输入,比如:13时53分03 秒星期三
    还有如何删除错误的自定义词组呢?打拼音总是难免选错字,如果不能快速删除,就很容易一错再错。
    刚才看了网页上的说明,似乎现在还没有这些功能,很遗憾的说!谢谢您们的无私奉献,衷心祝愿sunpinyin成长为最棒的拼音输入法!

  13. (xsunpinyin:1870): Gtk-CRITICAL **: gtk_widget_set_colormap: assertion `!gtk_widget_get_realized (widget)' failed

    (xsunpinyin-preferences:1978): Gtk-CRITICAL **: gtk_radio_button_set_group: assertion `!g_slist_find (group, radio_button)' failed

  14. 饥饿的拼音无法实现模糊切分,只能输入ji‘e。直接输入jie,sunpinyin不会给出“饥饿”的备选项,只有“接、几、及、即”等等,似乎有模糊切分,但是准确性太差。

  15. 快崩溃了,
    安装ibus-devel,提示:
    libibus.so.1 is needed by ibus-devel-1.2.0.20091204-2.el6.i686

    按照提示,安装缺失的libibus.so.1,提示已经安装:
    ibus-libs-1.3.4-3.el6.i686 is already installed

    为什么已经libibus.so.1已经安装,还说缺少呢?

  16. 看过sun拼音输入法的代码解读后很受启发,遇到不懂的地方可能还要向你请教下。谢谢了,呵呵。

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

To submit your comment, click the image below where it asks you to...
Clickcha - The One-Click Captcha