拼音重碼率的研究(一)
- 字形輸入法往往能做到極低的重碼率,那拼音輸入法的重碼率如何?
- 拼音輸入法的「模糊音」對輸入效率有多大的影響?
- 如果給拼音引入現時普通話不存在的特徵,能增加多少辨識度?
本文對這些問題做了一个小研究。
重碼率的定義
讓我們設想一種簡易的拼音輸入法,用戶只能輸入一个固定的詞表中的字詞。顯然,同音的字詞中頻率最高的那个應當是第一選擇。所有非第一選項的字詞就構成了第一選項的重碼,因爲它們的編碼(即拼音)重複了。
例如,編碼爲「shi shi」的詞中,「實施」在語料中頻率最高,所以它是默認選項。那同編碼的「事實」、「試試」、「實時」等就處於重碼的地位,需要靠數字鍵來選擇。在輸入中,重碼出現的相對頻率就可稱爲重碼率。
以上所說的實際上是 top-1 error rate。推而廣之,還可以有 top-k error rate,表示想輸入的字詞沒能出現在前 k 个選項中的相對頻率。倘若輸入法每頁提供 5 个選項,則 top-5 error rate 就是用戶需要翻頁的概率了。
現在的輸入法越來越智能,使得編碼方案本身的重碼率已經不像以前那樣是唯一的決定因素了。輸入法可以通過神經网絡等方法實現準確的整句輸入,因爲上下文起到了消歧義的作用。當然,重碼率越低,實現一个好用的輸入法所需的「智能」就越少。
漢語拼音的重碼率
要研究拼音的重碼率,我們需要兩樣東西:一是頻率詞典(語言模型),二是拼音詞典。在這个實驗裏,我是從 Rime 輸入法中提取的這兩樣東西。
- 它有一个
essay.txt
,裏面每行是一个詞,然後附上了它在語料中的頻率。其實有些「詞」實際上是好幾个詞連在一起,比如「我想要」、「我想說」等等;只是因爲沒有分詞,不容易看出來這是一个 n 爲多少的 n-gram model。 - 給定漢字查詢拼音的詞典文件是因輸入方案而異的,這裏我用「朙月拼音」的
luna_pinyin.dict.yaml
。
有一个問題是拼音詞典裏不一定有 essay.txt
裏面的整个的「詞」的拼音,而只有對更短的單位注音(大部分是單字),更別說像上面所說的短語乃至短句了。爲了給這些長「詞」注音,我用最大正向匹配來把長詞分割成一組在拼音詞典中有的詞。例如,把「長江三角洲經濟區」分割成「長江」、「三角洲」、「經濟區」,從而知道此處「長」的拼音是「chang」不是「zhang」,「角」的拼音是「jiao」不是「jue」。
對於這樣處理後仍然存在多音字的,則生成所有可能的拼音,並按照拼音詞典裏各个讀音的概率來分攤頻率。例如,拼音詞典說「長」有 60.26% 可能讀「chang」,有 39.74% 可能讀「zhang」。而 essay.txt
說單字「長」的頻率是 24093,則 14518 屬於「chang」,9575 屬於「zhang」。
有了這些之後,我們就知道對於每一个編碼,存在哪些候選字詞以及它們的頻率。計算 top-k error rate,就是把前 k 个選項以外的頻率加起來,除以 essay.txt
中所有頻率之和(少量無法標音的含生僻字條目除外)。由此計算出漢語拼音方案(無聲調)的重碼率是 17.0%。同時,我還讓系統打出對重碼率貢獻最高的那些編碼。可見,重碼率最高的單音節是「shi」,它貢獻了 0.260% 的重碼率;雙音節則是「shi shi」,它貢獻了 0.032% 的重碼率。
嘗試改造拼音方案
好,有了這套系統之後,我們就可以測測不同的拼音方案對重碼率的影響了。首先,是我們耳熟能詳的「模糊音」,這裏測兩種常見的模糊方案:
- 模糊平翹舌音,即把「zh/ch/sh」與「z/c/s」分別合併,但保留獨立的「r」聲母。
- 模糊前後鼻音,即把幾乎只有韻尾差異的「eng/en」、「ing/in」各自合併,但不動主元音差異較大的「ang/an」或「ong/un」,脣音的「beng/peng/meng/feng」以及「weng」也除外。
顯然,模糊後原本不同音的字也變得同音,會令重碼率上升。爲了降低重碼率,我們得引入在方音、古音當中存在,而在現代標準漢語中已不存在的差異。一个名氣很大的選擇是所謂的「尖團音」:現在聲母是「j/q/x」的字有兩个來源,一部分是讀「g/k/h」聲母的(稱爲團音字,因爲它們先演變成了「j/q/x」),後來又有讀「z/c/s」聲母的字(稱爲尖音字)併入。在不少方言裏,還保留着這樣的對立。甚至有人架設了一个网站來宣傳在普通話中恢復尖團音的主張。
那麼,恢復尖團對立究竟對於重碼率有多大幫助呢?我從 Rime 的中古漢語拼音方案(可利用 /plum/ 安裝)中提取了漢字的中古音,依據這个來對所有聲母是「j/q/x」的漢字進行分類。例如,「需」的拼音變成了「sü」,因爲它的中古音是「syo」;而「虛」的拼音仍是「xu」,因爲它來自「hio」。
實驗結果如下圖所示:
可以看出,模糊平翹舌音比模糊前後鼻音造成的損失更大。這其實是符合直覺的,因爲平翹舌音的牽涉面大於前後鼻音,而且有些音節由於語音演變的規律不可能存在前後鼻音的對立(如「den」、「ten」等音節理論上就不可能存在於普通話)。
區分尖團確實能減少約 1% 的重碼率,其影響介於平翹舌音和前後鼻音之間。如果一定要在區分平翹舌音和區分尖團之間選擇其一的話(見黃色和綠色的柱子),還是區分平翹舌音的重碼率更低。這不禁讓人遐想,究竟是因爲平翹舌音更有區分力,所以語音在演變中才選擇了不犠牲平翹舌音而犠牲尖團;還是因爲先有了尖團混淆的局面,才導致語言本身傾向於避免使用僅靠尖團區別意思的詞彙?
以上研究是基於不帶聲調的拼音。Rime 還有一个帶聲調的詞典,即 terra_pinyin.dict.yaml
,它的重碼率只有 7.2%(區分尖團後 6.8%),相較於剛纔的 17.0%,真是腰斬都不止。可見聲調的區分度是遠遠大於只能用於部分字的彫虫小技的。不過,因爲對多音字的處理方式,不同的詞典並不適合直接比較。我嘗試將這本詞典脫去聲調,其重碼率是 17.3%,這个微小的差異應該就是由於這本詞典收錄的多音字信息比較粗糙導致的。如果直接把中古音拼音丟進去,重碼率更低至 3.5%,可以說已經近乎極限。對重碼貢獻大的仍有「他/她/它/牠」、語氣詞、姓氏等。對於極其常用又同音的字,可以考慮爲它們安排特殊的編碼,不拘泥於讀音。
本文中對拼音的改造只是拋磚引玉;古音和方音還爲我們提供了很多「魔改」漢語拼音的機會,譬如入聲韻、全濁聲母、知照對立等等。即便是不改音系,我們也可以調整這些字音的劃分,比如改換一種平翹舌音的劃分方式(直覺上講,現行的方式翹舌音太多,爲信息量計,最好是平翹各半)。關於這些探索的方向,我有機會會再次發文來詳述。