Skip to content

詞庫開發說明

zonble edited this page Sep 25, 2024 · 8 revisions

這份文件說明如何自行調整小麥注音輸入法所提供的詞庫。

小麥注音輸入法提供加入自訂詞庫,以及反向關閉某個內建詞彙的功能。不過,當您選擇 clone 程式碼自行編譯時,也可以選擇修改小麥注音所提供的詞庫。當您每次編譯程式時,其實其中一個步驟,就是將多種不同來源的資料,透過一些 Python script,合併成一份最終所使用的資料格式,這些檔案都位在專案的 Source/Data 目錄下。

小麥注音提供傳統的手動選字輸入以及自動選字兩種模式,所以我們也提供了兩種詞庫格式。兩者的差異在於:

  • 手動選字模式:這種模式的詞庫中,只使用了最基本的注音以及標點符號表格,不需要詞頻等資料。由於傳統注音輸入法的用戶,相當仰賴記憶固定的選字順序,因此我們鮮少修改這份表格,或是新增可以輸入的詞彙或符號。這個模式的詞庫用到了 BPMFBase.txt 以及 BPMFPunctuations.txt 兩個檔案。
  • 自動選字模式:除了前者用到的基本注音與標點表格之外,還用到了以下檔案
    • BPMFMappings.txt:不同於 BPMFBase.txt 只包含每個中文字的注音,這個檔案包含的是兩個字以上的詞彙的注音
    • phrase.occ:每個詞彙在語料中出現的次數,讓選字引擎做為自動選字的依據
    • Symbols.txt:自動選字模式下額外可以使用的符號與 Emoji
    • Macros.txt:日期巨集的讀音對應表
    • heterophony1.list、heterophony2.list、heterophony3.list:用來標注破音字的相關檔案

修正讀音

如果您發現某個字的讀音錯誤,或是某個讀音下,沒有您所預期的字,那麼,就需要修改 BPMFBase.txt。這個檔案的內容大概如下

兒 ㄦ er - big5
爾 ㄦˇ er3 -3 big5
耳 ㄦˇ er3 -3 big5

每個欄位解釋如下:

  • 中文字
  • 注音
  • 拼音
  • 注音在鍵盤上的位置
  • 是否是 Big5 編碼包含的字元,如果不是,就會標示為 UTF-8

請注意,在這個表格當中每個字的順序,就是最後會用在輸入法當中的順序。

新增詞彙

要增加自動選字輸入模式下的詞彙,我們需要輸入兩種資料:

  • 新詞的讀音,放到 BPMFMappings.txt 裡面
  • 新詞的詞頻,放到 phrase.occ 裡面

舉例來說,「一望無際」可能唸作「ㄧ ˊ ㄨㄤ ˋ ㄨ ˊ ㄐㄧ ˋ」,也可能唸作「ㄧ ㄨㄤ ˋ ㄨ ˊ ㄐㄧ ˋ」,我們就需要將這兩筆資料,輸入到 BPMFMappings.txt 裡面。

…
一望無際 ㄧ ㄨㄤˋ ㄨˊ ㄐㄧˋ
一望無際 ㄧˊ ㄨㄤˋ ㄨˊ ㄐㄧˋ
…

而 phrase.occ 的格式則是

…
一望無際 22
…

occ 副檔名是 occurrence 的縮寫,這代表,「一望無際」在我們的語料庫中,出現了 22 次,這麼數字會影響選字引擎是否會優先選用這個詞彙,因為,當一個詞彙曾經在語料中出現的次數愈多,代表用戶輸入某個讀音的時候,預期是這個詞彙的機率也愈大。小麥注音的開發者自己維護了一套語料庫,不定期會根據所蒐集的語料庫,更新這個檔案的內容,如果您有自己的語料庫,也可以自行更新這個檔案,但只是簡單的增加詞彙,可以先設定為 0。

我們在編譯階段,會把 phrase.occ 編譯成 PhraseFreq.txt,也就是,把 phrase.occ 當中所出現的次數,轉換成實際上的詞頻(這個詞彙在所有出現的詞彙中的佔比)。例如,一望無際會變成:

一望無際 -5.63664129

後面的數字代表 10 的 -5.63664129 次方,大概是 0.000002308653257377265。因為每個詞彙的詞頻,往往小的數字,不利於電腦計算,所以,我們會轉換成這個數字的 log 值

請確保 BPMFMappings.txt 以及 phrase.occ 兩個檔案的詞條排序!

為了方便 code review,我們要求 BPMFMappings.txt 以及 phrase.occ 這兩個檔案,使用位元組順序 (byte order) 的條目排列。請在修改這兩個檔案後,執行以下指令:

LC_ALL=c sort -o phrase.occ phrase.occ
LC_ALL=c sort -o BPMFMappings.txt BPMFMappings.txt

請務必在執行 sort 前增加 LC_ALL=c 的環境變數。

維持位元組順序,一方面方便開發者 code review,二來也可以輕易發現重複的條目。

新增標點

BPMFPunctuations.txt 的內容如下:

a _letter_A 0.0
, _ctrl_punctuation_, 0.0
[ _half_punctuation_[ 0.0
, _half_punctuation_Standard_< 0.0
「 _punctuation_[ 0.0
, _punctuation_Standard_< 0.0
, _punctuation_list 0.0

第一欄是預期要輸入的標點,第二欄則是這個標點的按鍵定義。

當中。義了幾種不同的標點:

  • 讓用戶透過 "`" 按鈕出現的符號表,會定義成 _punctuation_list
  • 讓用戶透過指定按鈕輸入的符號,比方說,按下 [ 會出現 ,我們就定義成 _punctuation_[
  • 某些按鈕在特定鍵盤排列下,會定義成不同的符號。比方說,逗號在標準排列與倚天排列下,定義在 < 按鈕上,所以會定義在 _punctuation_Standard_<_punctuation_ETen_< 上,但是其他鍵盤排列下,定義在 , 上,所以可以看到逗號定義在 _punctuation_ETen26_,_punctuation_Hsu_, 這些位置上。
  • _half_punctuation_ 代表的是半形標點,當用戶選擇使用半形標點時,會改成輸入這系列的標點。
  • _ctrl_punctuation_ 代表的是按下 Ctrl 鍵後,再按下的標點。我們定義了少數標點,符合微軟新注音輸入法用戶的習慣。
  • _letter_ 開頭的則是用戶按下 shift 再加上字母按鍵時可以輸入的字母。

新增符號

在 Symbols.txt 當中,我們則定義一些可以使用注音快速打出的符號,例如

🔥 ㄏㄨㄛˇ -8

我們通常會將這些符號的詞頻定義成 10 的 -8 次方,代表這些詞通常會排列在某個讀音可以輸入的文字的候選字列表的最後方,而且即使曾經輸入過這個符號,也不會被選字引擎記住。

日期巨集

在 Macros.txt 當中,我們定義了一些日期的巨集,例如

MACRO@DATE_TODAY_SHORT ㄐㄧㄣ-ㄊㄧㄢ -8
MACRO@DATE_TODAY_MEDIUM ㄐㄧㄣ-ㄊㄧㄢ -8
MACRO@DATE_TODAY_MEDIUM_ROC ㄐㄧㄣ-ㄊㄧㄢ -8

這代表,當用戶輸入「今天」的讀音時候,同時也會出現「2024/2/13」、「2024 年 2 月 13 日」、「民國 113 年 2 月 13 日」等選項。原理是,選字引擎在挑出 MACRO@DATE_TODAY_MEDIUM 這樣的候選字之後,再動態替代這個候選字的內容。您可以在 InputMacro.swift 裡頭看到有哪些可用的巨集,而如果您新增了新的巨集,也要在 InputMacro.swift 裡頭新增對應的程式碼。

破音字詞頻調整

很多時候,同一個字會有很多讀音,而且在不同讀音下,這個字的出現頻率不一樣,像是「化」同時可以念作「ㄏㄨㄚ ˋ」與「ㄏㄨㄚ」,但是其實很少念成「ㄏㄨㄚ」。中同時可以念成「ㄓㄨㄥ」與「ㄓㄨㄥ ˋ」,但是念作「ㄓㄨㄥ ˋ」的時候,並不會比「重」更常用。但是,我們用來計算詞頻的根據,是這個字在語料庫中出現的次數,這個次數並沒有區分讀音。在小麥注音的詞庫編譯過程中,就有一小段流程,降低破音字的詞頻。作法並不盡科學,但是可以一定程度上解決問題。

在詞庫目錄中,有三個檔案:heterophony1.list、heterophony2.list 還有 heterophony3.list。如果想要降低詞頻,就放到 heterophony2.list 還有 heterophony3.list 中。

  • heterophony1.list:使用原始詞頻
  • heterophony2.list:原始詞頻的 log 值再減去一個 magic number
  • heterophony3.list:原始詞頻的 log 值再減去兩個 magic number

這幾個檔案的內容如以下格式

一 ㄧ
丁 ㄉㄧㄥ
上 ㄕㄤˋ
中 ㄓㄨㄥ
乘 ㄔㄥˊ
乜 ㄇㄧㄝ
乾 ㄍㄢ
予 ㄩˇ
…

magic number 為 0.69314718055994,所以,如果原本詞頻是 10 的 -5 次方的話,如果把這個破音字放在 heterophony2.list 的話,就會調整成 10 的 -5.69314718055994 次方。

相關流程可以參考 cook.py 的實作。

附錄:含「不」的多字詞讀音修正

關於「不」字之音調:請參考下列規則與 PR#464 之討論。

  • 若「不」後面接一二三聲,該「不」應為四聲,僅加入四聲於詞庫
  • 若「不」後面接四聲,該「不」應為二聲 (變調),但四聲「不」 (原調) 也應一併加入詞庫
  • 若「不」於結尾,二四聲皆應加入詞庫

以下舉例說明。

僅加入四聲:

不丹 ㄅㄨˋ  ㄉㄢ
神智不清 ㄕㄣˊ ㄓˋ ㄅㄨˋ ㄑㄧㄥ
不行 ㄅㄨˋ ㄒㄧㄥˊ
不調 ㄅㄨˋ ㄊㄧㄠˊ
離不了 ㄌㄧˊ ㄅㄨˋ ㄌㄧㄠˇ
為時不遠 ㄨㄟˊ ㄕˊ ㄅㄨˋ ㄩㄢˇ

二四聲皆加入 (變調 + 原調):

戰無不勝 ㄓㄢˋ ㄨˊ ㄅㄨˊ ㄕㄥˋ
戰無不勝 ㄓㄢˋ ㄨˊ ㄅㄨˋ ㄕㄥˋ

二四聲皆加入:

也不 ㄧㄝˇ ㄅㄨˋ
也不 ㄧㄝˇ ㄅㄨˊ