@scomper

「鼠须管」词库的同步和备份

2017.10.22

鼠须管的词库是由两个部分组成的,一个是的固态词库(.table.bin),另一个是记录用户输入的动态词库( .userdb),也称之为用户词库。固态词库中的内容不会随着用户的输入发生变化,但是可以通过在配置中添加相应的词典文件(.dict.yaml)来扩充(需要重新部署才能生效),用户词库的会随着用户的每次输入发生变化,对应不同的输入方案,这些会记录在对应的 .userdb 文件夹之中, .userdb 文件夹中的用户词库内容同步到 Dropbox 后会以单个 .userdb.txt 的形式存在。

感觉好绕的一段词库说明,换个说法,个人的输入习惯记录在 .userdb.txt(同步到 dropbox 才能看到),平时所说的加载一个搜狗大词库对应的是一个 .dict.yaml 文件,或者还有英语词典一类的 .dict.yaml 文件,鼠须管调用.dict.yaml 词条的方式是将它们和内置词库一起先编译成 .table.bin 文件(所以每次修改完 dict.yaml 需要重新部署)。

配置同步

修改配置文件中的 installation.yaml 可以启用鼠须管的「同步用户数据」功能,从而备份 .dict.yaml 文件和 .userdb.txt 文件到 Dropbox 文件夹。全新安装鼠须管输入法时,只需要安装后将备份的文件复制到配置文件夹「重新部署」,你的词库和习惯配置就都回来了。或许有的人会有一个疑问,为什么不能先配置好 installation.yaml,然后直接「同步用户数据」呢?因为「同步用户数据」同步的是用户词库( .userdb),.dict.yaml 文件只单向备份到 Dropbox。

通常 installation.yaml 文件中增加一行 Dropbox 用来备份的文件夹路径即可,例如:/Users/scomper/Dropbox/应用/RimeSync 指向的是我的 Dropbox 的目录,你需要参照修改成你自己的(技巧:在 Dropbox 中创建目录后拖拽到「终端」窗口可迅速获得路径地址)。

distribution_code_name: Squirrel
distribution_name: "鼠鬚管"
distribution_version: 0.9.27
install_time: "Sat Jun 10 21:21:04 2017"
installation_id: "scomper-MacBook-Pro"
rime_version: 1.2.9
sync_dir: "/Users/scomper/Dropbox/应用/RimeSync"

installation_id 默认是随机生成的一长串 UUID,不是很直观,范例中被我改成了 scomper-MacBook-Pro 这样的命名(使用英文不留空格)。为了区分和管理方便,多台电脑里的里鼠须管installation_id最好不要重复,如下图所示,installation_id 分别对应两台笔记本,配置好 installation.yaml 之后,「同步用户数据」Dropbox 就多了两个对应设备的文件夹。

由菜单栏执行「同步用户数据」时,「鼠须管」会搜索 RimeSync 下所包含的所有子目录,合并其中同名的 .userdb.txt 文件并同步到本地配置文件夹(双向合并),同时,「鼠须管」会备份配置文件夹中的 .dict.yaml 文件到 Dropbox(单向备份)。

这么设计的目的可以合并来自多个设备的用户词库,可以理解为 MacBook Air 上的用户词库 [abc] 和 MacBook Pro 上的用户词库 [bcd],在同步后都变成了[abcd]。那么如何删除用户词库中的错误词汇呢?

候选状态栏上发现错误或不想要的词汇高亮选中后按 fn+Shift+delete 的组合键就可以。如果你发现删不掉,那么这个词汇就是固态词库(dict.yaml 生成的 .table.bin)之中的词汇(*完善的 dict.yaml 词典文件很少会出现错误词汇问题*),只能去一堆 dict.yaml 词典文件里找到并删除,最好重新部署。

不同设备的 Dropbox 同步文件夹最好不同,如果想同步小狼毫和鼠须管的用户词典,推荐用 Hazel 一类的软件定期自动同步指定的 .userdb.txt 文件。

修改用户词库

只要配置好 Dropbox 同步文件夹,同步一次后 .userdb 在保存到 Dropbox 时自动就合并成了 .userdb.txt。 .userdb 文件夹中的内容是给程序看的,如果需要编辑用户词库可以打开 .userdb.txt。


头一次打开自己的 .userdb.txt 文件时很是吃惊,里面有好多奇怪的词条和莫名奇妙的长句子,回想起来很多估计是为了测试随便输入的一串拼音字符,它也都如实的记录了下来。都说输入法是一个人心灵的窗户,这下好了,你有机会回顾一下自己的心路历程。再看看 easy_en.userdb.txt 就是一份自己输入和查询过的所有单词表 ;)。

为了验证,用系统拼音往 .userdb.txt 增加了一个新的「壹页单章」词条(只要输入前面的拼音和词汇就行,后面的参数随意复制一个),没用添加前输入 y y d z第一候选是摇曳多姿,添加后执行「同步用户数据」,词条后面的参数会自动变化,同时输入首字母缩写候选出现「壹页单章」。

c = 词频、 d = 权值 t = 时刻
用户词典的词条在每次输入的时候会更新, t 记录的是他最近一次更新的输入法时间。至于词频 c,一年前输入的一次和刚刚输入过的一次其表现出来的效果肯定不一样,所以会综合时间参数 t 折算成一个权值 d,d 值并不是当前的权重,而是 t 时刻该词的权重。随着时间流逝,d 值会衰减的。

不要被用户词库里自己的创造吓到,如果有心维护一下,不会正则表达式还是算了,毕竟条目太多了,而且大多数时候不影响你的使用。不过前几天网友的案例倒是一个提醒,他反馈的问题现象是输入某些特定字母时输入法卡顿,找了一圈原因,最后发现是用户词库里有一堆不恰当的首字母分词导致的,因为当我们输入字母时,输入法会基于词库进行检索和匹配响应,原本应该是shu ru fa,结果词库里有s hu那么判断关联到的就是不同的词汇,这种非元音的不合理切分也会导致拼音组合混乱,检索量级上来了就表现出卡顿现象。

.userdb 是增量合并的,那么如果你修改了 .userdb.txt,该如何部署到输入法里呢?

  • 如果你有多台电脑的同步配置, .userdb.txt 文件修改好以后先覆盖另一个同步文件夹里的同名 .userdb.txt 文件;
  • 删除「用户设定」也就是本地配置文件夹下的 同名 .userdb 文件夹;
  • 菜单栏执行「同步用户数据」,输入法会基于 .userdb.txt 生成新的 .userdb 文件夹从而实现用户词库的修改。

修改词典文件

网上下载的词典文件(.dict.yaml)部署后就会生成输入法工作时需要的固态词库(.table.bin),.dict.yaml 文件是平时我们扩展本地词库的主要方式,可以用文本编辑器进行编辑。为了说明方便,后面我们就称 .dict.yaml (UTF-8 编码)为词典文件。

  • 词典中每一行代表一个词汇的定义;
  • 形式是 词汇<tab>ci hui<tab>100,从左到右依次是词汇、拼音编码、词频, 表示制表符;
  • 拼音编码之间以半角空格为间隔;
  • 拼音编码和词频可以省略。

编辑器的文本设置中需要将「Auto-expand tabs」关闭,这样输入的才是 tab 而不是空格。启用「Show invisibles」能让我们看到 tab 和空格。

「鼠须管」的调教笔记 中介绍过如何加载多个词典 ,重点其实就两条,一个是自己创建的词典文件需要在最开始的语句中定义词典的名称(随便打开一个 词典文件查看顶部的写法),另一个就是在 luna_pinyin.extended.dict.yaml 中指定以便能实现调用,extended.dict.yaml 是比较特殊的词典文件,它自己可以包含词汇同时能关联其他词典文件,其他词典文件只需要代码的前 4 行就可以。

---
name: luna_pinyin.extended
version: "2016.06.26"
sort: by_weight
use_preset_vocabulary: true 

import_tables:
  - luna_pinyin
  - luna_pinyin.sgmain
  - luna_pinyin.hanyu
  - luna_pinyin.poetry
  - luna_pinyin.cn_en
  - luna_pinyin.emoji
  - luna_pinyin.kaomoji
...
  • name: 词典名称,被 luna_pinyin.extended.dict.yaml 调用时需要列在import_tables:后面;配套输入方案的 yaml 建议和这里的命名标识一致;
  • version: 管理词典的版本;
  • sort: 词条初始排序方式,by_weight(按词频高低排序)或 original(保持原码表中的顺序);如果选择 sort: original 选项按词条在词典中出现的顺序排列,忽略词频。
  • use_preset_vocabulary: 填 truefalse,选择是否导入系统词汇词频。

添加到词典中的词汇最好转成繁体的,这样切换成繁体输入方案时依旧能使用。用系统自带的 ⌃⇧⌘C 即可实现。

词汇的词频

部署输入法时,引入的词典(如.dict.yaml)、用户词库以及与输入法自带的系统词库,共同形成编码集合。含多音字的词,系统词库一般都有,如果没有才要考虑在 .dict.yaml 中增加这个词并注上音。系统词库中已经包含了完整的单字注音和罕用读音降频处理,所以通常我们新增 .dict.yaml时只需要输入词汇部分即可。

dict.yaml 文件中的词汇一般是不需要添加词频的(词频添加模式可参照 easy_en.dict.yaml),而dict.yaml 生成的 table.bin 固态词库和用户词库的词频基准也不同,用户词库的词频优先级更高,也就是说输入时我们选择过的词会排的更靠前。

如果要干涉 dict.yaml 中词汇的词频,决定它的默认候选位置,可以在词条后添加一个比较大的数值(数值是相对的,究竟多大取决于已存在的词频数值,部署时所有词汇的词频权重数值在计算后会形成统一,例如百分比方式)。

easy_en.dict.yaml 中的词频来自于词典源的基础数据,dict.yaml 里面的词频是从语料统计来,其作用是决定候选字的初始顺序,让那些用户从来没打过的词之间也有较好的排序,同时对重码字、词的排序起作用。固态词典中的词频不影响自动调频,只有用户的输入影响自动调频,通常说的调整词频是对用户词库的动态调节。

鼠须管在设计上分设「固态词库」和「用户词库」,不仅仅是为了做优化,两者所记录的词频意义不同,其数值是不可比的。即使固态词典里的词有很高的词频,但那并不能代表用户的输入习惯,因为用户并没有真的输入过那么多次。


为了写这篇稿子又翻了一遍 Rime GitHub 的帖子,很多是很早以前的讨论,不排除后面策略上存在新的变化,不过本着学习和明理的原则,了解这些多少是有益处的,就像学过 DOS 的人面对 Windows 一样,起码在分析问题时能丰富自己的思路,有时候一个知识点上的储备会带来不同的分析问题的角度。

参考文章:
Rime 碼表與詞典
固定词、其他词和自造词调频问题
用移動硬盤同步RIME用戶詞典的樣例

--「壹页单章」会员计划 --

Comments
Write a Comment