快轉到主要內容

Immich 繁體中文地理資料技術解析(四):用 Wikidata 翻地名,以及它如何安靜地出錯

··2626 字·6 分鐘
目錄
immich-geodata-zh-tw - 本文屬於一個選集。
§ 5: 本文

上一篇:五個地區,五種方案談到,泰國、印尼這類非漢字系統的地名只能走翻譯路線,而專案選擇的翻譯來源是 Wikidata。

這篇要談的不是「怎麼查」,SPARQL 查詢本身沒什麼難度。難的是:Wikidata 翻錯的時候,通常不會有任何跡象。流程不會中斷,日誌不會報錯,輸出是一個合法的中文字串,只是指向錯的地方。

為什麼是 Wikidata
#

地名這種資料有幾個特性讓通用翻譯很難處理:

  1. 同名地名到處都是:南韓有首爾中區、釜山中區、大邱中區;泰國、印尼也都有大量重複的行政區名。翻譯 API 看不到上下文,無法區分。
  2. 地名不是語意翻譯,是查表:「Ngawi」該翻成什麼,取決於既有的中文慣用譯名,而不是字面意思。
  3. 需要驗證管道:翻出來的結果必須有辦法確認「這確實是那個行政區」,而不只是「這串字讀起來像」。

Wikidata 剛好補上這一塊。它是結構化的知識圖譜,每個地理實體都有:

有了 P131,就能用「上級行政區」來裁決同名問題:查「中區」時,額外要求它的 P131 鏈必須包含首爾(Q86),釜山的中區自然就被排除了。

SELECT ?item ?itemLabel WHERE {
  # 直接綁定韓文原名,不要用 FILTER 掃全圖的 label(那樣幾乎必然逾時)
  ?item rdfs:label "중구"@ko.

  # 關鍵:驗證它確實位於首爾的行政區鏈上
  ?item wdt:P131+ wd:Q86.

  SERVICE wikibase:label { bd:serviceParam wikibase:language "zh-tw,zh-hant,zh,en". }
}

到這裡為止,一切看起來都很美好。

失敗是無聲的
#

實際跑下來會發現,這套流程的失敗有兩種,而且兩種長得完全不一樣

第一種:查不到實體,或所有候選都通不過隸屬驗證。 結果是回退為來源原文,該地名維持未翻譯。這種其實是好結果,它會出現在未翻譯清單裡,一眼就能看到。

第二種:選到了錯誤的實體,而那個實體通過了 P131 驗證。 譯名會直接取自那個錯誤實體。這種最難察覺,因為輸出是一個合法的中文字串,不會出現在任何異常清單裡。

第二種的實例:首爾的 관악구(冠嶽區)曾經被輸出成「新林洞」。冠嶽區裡確實有個新林洞,新林洞的 P131 鏈也確實包含首爾,驗證完全通過。從資料上看不出任何問題,除非有人真的去比對每一個區名。

Wikidata 地名翻譯的三種結果:驗證通過得到正確譯名、查不到則回退原文並出現在未翻譯清單、選到錯誤實體卻通過驗證則產出看不見的錯誤譯名
三條路徑中,只有回退原文是看得見的失敗

六種已知的出錯方式
#

以下是專案實際遇過並記錄下來的形態:

形態案例怎麼判別
搜尋選到錯誤實體관악구 選到區內的 신림동송파구 選到地鐵站 잠실역候選的原文 label 與查詢名稱不相等
上游 label 停在舊制여주시 的中文 label 曾是升格前的「驪州郡」行政層級後綴對不上(시→市、군→郡、구→區)
宣稱是繁體,字形卻有誤함평군zh-tw 把「咸」轉成「鹹」;印尼 Papua 的 zh-hant 直接殘留簡體「巴布亚」人工抽查,或用簡體字白名單掃描
缺少 P131 敘述영종구 設區後一段時間內完全沒有隸屬驗證失敗且查無敘述
P131 被標為 deprecated印尼 Kabupaten Ngawi 隸屬東爪哇省的敘述曾被標 deprecatedSPARQL 的 wdt: 前綴只走 best-rank statement,deprecated 等同不存在
我方的過濾規則誤殺正確候選見下一節正確實體根本不在候選結果裡

第五種特別值得注意,因為它完全違反直覺:Kabupaten Ngawi 的資料明明還在 Wikidata 上,只是被標記成 deprecated,而 wdt: 前綴只會走 best-rank 的敘述。對查詢來說,那條敘述等於不存在。

最諷刺的一種:防護機制自己製造錯誤
#

第六種形態是我們自己造成的。

為了避免搜尋選到機關單位(區公所、教育廳之類),原本的做法是關鍵字黑名單:逐一檢查候選實體取回的每個 label,含有「廳」、「所」這類字就剔除。

然後正確的 관악구 被剔除了,因為它的 zh-hant label 被機器人從中文維基的 infobox 匯入成「冠嶽區」,那是區公所的名稱,不是行政區的名稱。黑名單認得「廳」字,於是把唯一正確的候選踢掉,剩下的候選裡最接近的就是那個新林洞。

黑名單式的排除規則永遠列不完,而且會因為某個無關語言的 label 誤傷正確候選。南韓 handler 後來改成白名單式判定:候選的原文 label 必須與查詢名稱完全相符。機關、職位、選區、車站的名稱不會與行政區名完全相同,自然就落選了,而且不需要維護任何關鍵字清單。

Warning

印尼的處理路徑目前仍保有類似的關鍵字比對機制,涵蓋範圍包含中文系 label 與維基條目標題,也就是當初誤殺 관악구 的同一個範圍。印尼目前沒有觀察到誤殺案例,但這是已知風險。

驗證方法論:不能只看總數
#

這些形態導出一條操作原則:驗證資料時必須比對未翻譯名稱的完整清單,不能只看數量

實際案例:印尼從舊版圖資換到新版時,未翻譯的二級行政區數量維持 51 個,看起來毫無變化。逐筆比對才發現 Kabupaten Ngawi 掉出來了,同時另一個地名首次翻譯成功,剛好抵銷。

同樣地,未翻譯數量上升時也不能直接當成「上游新增了行政區」。上游新增行政區與譯名失效,在數字上的表現一模一樣。

快取:多層,而且會短路
#

SPARQL 查詢慢,快取是必須的。快取檔放在專案的 geoname_data/{國碼}_wikidata_cache.json(例如 KR_wikidata_cache.json),內部分成好幾層:

  • cache.search:搜尋結果
  • cache.labels:實體的多語言 label
  • cache.instance_of:P31 類別
  • cache.p131:隸屬關係驗證結果
  • translations:最終的譯名決策

這裡有個實務上會踩到的坑。translations 命中時要同時滿足兩個條件:本次算出的上層 QID 與快取記錄相同,且該筆結果為翻譯失敗或已通過隸屬驗證。兩者都成立時,流程會直接採用快取結果,完全不查 cache.p131

也就是說,修正了上游的 P131 敘述之後,只清 cache.p131 重跑,會發現什麼都沒改變,因為那一層根本沒被讀到。要重驗單一實體,cache.p131translations 兩處都得清;改動的是候選篩選邏輯的話,直接用空快取重跑比較省事。

優先修正上游
#

最後是一個方向性的原則:某個譯名錯誤如果源自 Wikidata 本身,優先去修 Wikidata,而不是在專案裡加一條對照表。

修正上游對所有使用者都有效;對照表只對這個專案有效,而且要長期維護。南韓的例子在上一篇提過:原本為了修上游錯誤而規劃的七條人工對照表,在改用韓文維基的漢字表記作為名稱來源之後,降到了零條。

翻譯這條路線的核心體悟大概就是這個:能不翻譯的就不要翻譯,必須翻譯的就要有辦法驗證,驗證不過就老實回退到原文。 一個看得出來沒翻譯的地名,遠比一個看起來很合理的錯誤譯名有價值。

參考資源
#


下一篇:用官方圖資重建臺灣的行政區回到臺灣,看看有官方圖資可用時,處理流程可以簡單到什麼程度。

immich-geodata-zh-tw - 本文屬於一個選集。
§ 5: 本文

相關文章

Immich 繁體中文地理資料技術解析(三):五個地區,五種方案

··2686 字·6 分鐘
前兩篇把機制與流程講完了:Immich 從 cities500.txt 讀地名,而那份檔案由各國圖資經過 extract 與 release 產生。技術上「怎麼換」已經沒有懸念,真正難的是另一件事:外國地名要顯示成什麼樣子,臺灣使用者讀起來才自然。 immich-geodata-zh-tw 目前處理五個地區,給出了五種不同的答案。這篇談的是那些答案背後的判斷標準。

Immich 繁體中文地理資料技術解析(二):資料處理流程

··4554 字·10 分鐘
系列上一篇:反向地理編碼是怎麼運作的拆解了 Immich 怎麼讀地理資料:啟動時把幾個純文字檔匯入 PostgreSQL,照片上傳時用最近鄰查詢找出地名。既然換掉檔案就能換掉顯示結果,剩下的問題就落在那份「更好的檔案」本身。 這篇拆解 immich-geodata-zh-tw 的資料處理流程:從各國官方圖資,到使用者下載的那包 release.tar.gz。

Immich 繁體中文地理資料技術解析(一):反向地理編碼是怎麼運作的

··3450 字·7 分鐘
每當你上傳一張照片到 Immich,系統就會自動標註拍攝地點,例如「臺北市信義區」、「東京都澀谷區」。這背後並非雲端 API 的功勞,而是一套完全離線運行的反向地理編碼(Reverse Geocoding)系統。 也因為它是離線的,immich-geodata-zh-tw 這個專案才有存在的空間(實際安裝步驟見系列首篇的圖文安裝教學):Immich 從幾個純文字檔讀取地名,那麼換掉那幾個檔案,顯示出來的地名就會跟著換。 這篇是系列的技術篇第一篇,先把地基講清楚:Immich 查到一個地名時到底發生了什麼事、它讀的是哪幾個檔案,以及這個機制留下了哪些可以動手腳的空間。後續幾篇談的各國處理策略、翻譯與驗證,全部建立在這篇的基礎上。