Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

删除自造词使用负的 commit 来 mark 期望的效果是怎样的 #1500

Closed
sci-42ver opened this issue Mar 16, 2024 · 1 comment
Closed

Comments

@sci-42ver
Copy link

sci-42ver commented Mar 16, 2024

以下的序号是想问的几个相关联的问题的序号。


当前环境为weasel-0.15.0,自造词我参考的这个comment

translator:
  dictionary: rime_ice          # 挂载词库 rime_ice.dict.yaml
  prism: double_pinyin_flypy    # 多方案共用一个词库时,为避免冲突,需要用 prism 指定一个名字。
  ...
  enable_encoder: true
  encode_commit_history: true
  max_phrase_length: 5

基于上述配置,可以产生以下两个自造词并通过 yaml 里的 Control+k发送 Shift+Delete 删除 (不过代码里面用的 {XK_Delete, kControlMask},不太清楚具体机制) 并产生 负的 commits:

$ grep -r --include \*.txt --include \*.yaml -E "foo|bar" /d/Rime/
grep/d/Rime/Data/sync/81795296-59cd-4bec-9abc-336b72c8b08d/rime_ice.userdb.txt:foo bar       foo  c=-2 d=1.99501 t=900
:/d/Rime/Data/sync/81795296-59cd-4bec-9abc-336b72c8b08d/rime_ice.userdb.txt:foo bar foo bar        bar  c=-1 d=1 t=915
$ grep -r --include \*.txt --include \*.yaml "foo bar foo bar" /d/Rime/ | wc -l
1
$ grep -r --include \*.txt --include \*.yaml "foo bar" /d/Rime/ | wc -l
69

不过上述过程中,只有 "foo" 会从候选框移除并且不再出现,但是 "bar" 并不会移除总是作为第一候选项。这印证了代码里的注释 // CAVEAT: this doesn't mean anything is deleted for sure

  1. 用戶輸入習慣只反映在重碼候選詞的排序上。

    这个是可以理解为 userdb 只用于重碼候選詞么?所以,上面的“bar”由于已经输入“foo bar foo bar” (故非 "completion")但是由于没有别的候选词(无重碼),故效果上看似并没有删掉这个词语。

  2. 可以问下 {XK_Delete, kControlMask}Shift+Delete 如何联系的吗?


以下是我基于网上一些文档、代码、评论的理解,希望懂相关 删除自造词 机制的人可以帮忙看下。

DeleteCandidate 如何更改 userdb

DeleteCandidate 会调用 delete_notifier_, 其会调用 Memory::OnDeleteEntry 来删词.

Translator 导入 userdb

看了一下weight 相关的代码,首先取负数 commits,然后根据当前timestamp,调用 formula_d 更新 dee(由于此处原本要放置commits 的参数 d=0 设置为0,相当于只更新timestamp/ticks 和 减小dee 了)。

此处 dee 初始为0,然后根据 commits 逐渐增加commits 时间差 逐渐变小(避免了 LRU 问题)。

然后调用 formula_p来更新 weight,其中 s=0kM是一个较大的数字(约为 200.5)。这里由于u变为负数,m 变得更小了。不过由于 pow((1 - exp(-t / 10000)), 10) (图像在 t>0 的情况下类似于 sigmoid,但是 u 很可能随着 t 变小,故 m 随着时间可能维持在某个小范围内) 始终小于1,而 u 随着时间推移大概率接近0 (因为commits远小于present_tick),故 m 也会趋近0。随着时间推移,(d / kM) 成为主导项。同时 d 越大,pow(4, (d / kM))以 4 为底数,也将远大于 m (故 weight 可近似看作关于 d 成正比)。

  • 但是,d/dee 是关于 commits (正比)和时间(反比)的函数,故 weight 亦是。依旧满足 “两者解决了下述问题”。

最后,上面计算的 weight被指数放大,配合 initial_quality


  1. 综上,是不是可以认为删除自造词,其实并没有真的删除它,只是对它的commits取负,而这个负数具体大小 在 algo::formula_d(0.0, (double)tick_, v.dee, (double)v.tick) 里 并不对 dee 产生影响 (有些类似于恢复了默认值)。所以,如果commits始终为负数,时间推移下 dee 将仅受 timestamp 影响变小。由于 dee 大概率主导 weight 的大小,从而导致 weight 变小。所以,可能由于dee的影响会产生当前词好像没有删掉的效果。不知道我们可不可以这样理解?

    候选词排序还受 speller/algebrasyllabifier 影响。后者简单看了下代码 syllabifier.ccsyllabifier_test.cc,其把 SyllableId看成 vertex(实际结构是个map ),然后把音节切分段看成 edge。不过,由于我双拼日常使用官方默认配置足够了(speller/algebra 没有 abbrev/fuzz,同时结合双拼,不太可能会有 kAmbiguousSpelling 的情形),同时 userdb 相关的 table_translator(主翻译器)使用 enable_completion: false,所以,我的双拼里与主翻译器有关的候选项应该基本上都是 kNormalSpelling。故其并不会对 commits 等产生的 weight 产生候选项排序上的影响。

    有什么好的方法可以真正删除掉自造词么(请问 目前有没有可用的接口,可以直接用或稍作修改)?

以上问题希望有人可以指教一下,谢谢。

@sci-42ver sci-42ver changed the title 删除自造词期望的效果是怎样的 删除自造词使用负的 commit 来 mark 期望的效果是怎样的 Mar 17, 2024
@sci-42ver
Copy link
Author

最近有空又看了一下。之前给弄错了,foo bar foo bar 是对应的 sentence (感谢 librime-lua,提供的接口文档和一些范例帮助进一步了解了 rime 大致框架)。虽然 enable_sentence: false,但是在缺少准确候选项时,会造句

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant