Skip to content

notoriouslab/trad-zh-search

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trad-zh-search

可單獨搭配主流搜尋引擎,專門給繁體中文使用的繁體中文文本預處理工具 —— CKIP 分詞 + bigram 索引生成,附可選擇的領域字典系統。

需要 Python 3.9+ · 屬於 notoriouslab 開源工具組的一員。

English README


這個工具用了什麼

你的文本 → trad-zh-search → 搜尋引擎(Meilisearch / MiniSearch / Elasticsearch / ...)
元件 是什麼 需要裝嗎
CKIP (ckip-transformers) 中研院開發的繁體中文 NLP 工具,用 Transformer 模型做分詞 選裝(pip install trad-zh-search[ckip]
albert-tiny CKIP 用的分詞模型,只有 ~50MB,CPU 就能跑 隨 CKIP 自動下載
Bigram 把中文字兩兩組合(「聖靈」→「聖靈」「靈充」「充滿」),確保搜尋不漏 內建,不需要額外安裝
領域字典 YAML 格式的專有名詞表,告訴分詞器哪些詞不要拆開 內建基督教繁中字典,也可自己建
PyYAML 讀寫 YAML 自動安裝

最小安裝只需要 PyYAML(幾 KB),就能用 bigram 模式。加裝 CKIP 會多 PyTorch(~700MB)+ 模型(~50MB),但分詞品質大幅提升。


為什麼需要這個工具

主流搜尋引擎(Meilisearch、Elasticsearch、SQLite FTS5)的中文支援大多依賴 jieba(簡體中文訓練),對繁體中文分詞品質差,這問題已經很多年了,但沒有一個很好的解決方案,我最近整理了一些文章,在過程中陸續找出了適合自己的解法,提供出來給大家參考使用。

先看看實際差異:

原文 jieba 分詞 CKIP + 自訂字典
聖靈充滿的經歷 聖靈 / 充滿 / 的 / 經歷 聖靈充滿 / 的 / 經歷
因信稱義的教義 因信 / 稱義的 / 教義 因信稱義 / 的 / 教義
台北靈糧堂的主日崇拜 台北 / 靈糧堂 / 的 / 主日 / 崇拜 台北靈糧堂 / 的 / 主日崇拜
靈糧教牧宣教神學院 靈糧 / 教牧 / 宣教 / 神學院 靈糧教牧宣教神學院

jieba 把「稱義的」黏在一起、「聖靈充滿」拆成兩個詞、機構名全部切碎,CKIP + 自訂字典都能正確處理。

實戰數據

在一個 8,000+ 篇繁體中文文章的搜尋系統上實測(80 組 benchmark query):

  • CKIP 分詞 + bigram:Top-1 搜尋結果有 21% 的查詢獲得改善(17/80 好轉,3/80 變差)
  • albert-tiny 模型 vs bert-base:分詞結果完全一致,但速度快 4 倍、模型小 10 倍
  • 自訂字典(915 詞):機構名、人名不再被拆開,搜「靈糧教牧宣教神學院」直接命中

功能特色

特色 說明
CKIP 分詞 ckip-transformers(albert-tiny),繁體中文專用
Bigram 索引 CJK 字符滑動窗口 bigram,確保子字串都能搜到
可選 CKIP 沒裝 CKIP 時自動退回 bigram-only——tokens 回空 list、used_ckip 為 False,bigram 照常產生
領域字典 YAML 格式,可插拔。首發基督教繁中字典(915 自訂詞)
自動建字典 丟一批文件進去,CKIP NER 自動提取專有名詞
Meilisearch Adapter TokenResult → 多欄位文件格式,一行搞定
MiniSearch Adapter 靜態網站客戶端搜尋,build time 建索引、瀏覽器直接用
Stop-bigrams 內建 102 個繁中虛詞 bigram 過濾表,提升搜尋精準度

快速開始

pip install trad-zh-search

# (選裝)CKIP 分詞支援
pip install trad-zh-search[ckip]

CKIP 安裝須知

trad-zh-search[ckip] 會一併安裝 PyTorch(約 700MB+),這是 ckip-transformers 的底層依賴。 首次呼叫 tokenize() 時會自動從 HuggingFace 下載 albert-tiny 模型(約 50MB),需要對外網路。 離線環境請參考 HuggingFace offline mode

不裝 CKIP 也能用——自動退回 bigram-only 模式,仍比 jieba 更適合繁體中文。

三行程式碼

from trad_zh_search import tokenize

result = tokenize("轉型正義委員會的調查報告")
print(result.bigrams)   # ['轉型', '型正', '正義', '義委', '委員', '員會', '會的', '的調', '調查', '查報', '報告']
print(result.tokens)    # CKIP 分詞結果(有裝 CKIP 時)
print(result.used_ckip) # True / False

搭配領域字典

from trad_zh_search import tokenize, load_dictionary

# 載入內建基督教繁中字典
ck_dict = load_dictionary("christian-zh-hant")
result = tokenize("台北靈糧堂的主日崇拜", dictionary=ck_dict)
# CKIP + 自訂詞合併:「台北靈糧堂」不會被切成「台北/靈糧/堂」

從文件自動建字典

from trad_zh_search import build_dictionary, save_dictionary

# 丟一批文本 → CKIP NER 提取專有名詞 → 產生字典
texts = [open(f).read() for f in my_articles]
my_dict = build_dictionary(texts, min_freq=2)
save_dictionary(my_dict, "my_domain.yaml")  # 存檔可人工微調

Meilisearch 整合

from trad_zh_search import tokenize, load_dictionary
from trad_zh_search.adapters.meilisearch import to_meilisearch, to_meilisearch_synonyms

ck_dict = load_dictionary("christian-zh-hant")

# 文件預處理
doc = to_meilisearch(
    fields={
        "title": tokenize(title, dictionary=ck_dict),
        "content": tokenize(content, dictionary=ck_dict),
    },
    original={"id": doc_id, "title": title, "content": content},
)
# → {"id": ..., "title": ..., "title_ckip": "...", "title_bigram": "...",
#    "content": ..., "content_ckip": "...", "content_bigram": "...", ...}

# 同義詞設定
synonyms = to_meilisearch_synonyms(ck_dict)
# → {"敬拜": ["崇拜", "主日"], "崇拜": ["敬拜", "主日"], ...}

搜尋建議:將以下欄位依序加入 searchableAttributes(順序即權重,越前面越重要):

title_ckip → title_bigram → content_ckip → content_bigram

實戰 benchmark 顯示 CKIP 和 bigram 互補——CKIP 提供精確的詞邊界匹配,bigram 確保不漏掉子字串。

MiniSearch 整合(靜態網站適用)

v0.2 新增 — 適用於所有靜態網站(Astro、Hugo、Next.js SSG、11ty 等)搭配 GitHub Pages / Cloudflare Pages / Vercel 部署。

MiniSearch 是輕量的客戶端搜尋引擎,支援序列化索引。搭配 trad-zh-search 的 build-time 分詞,靜態網站也能有高品質的繁中搜尋。

架構

Build time (Python):  文章內容 → tokenize() → to_minisearch() → JSON
Build time (Node.js): JSON → MiniSearch.addAll() + toJSON() → 序列化索引
Runtime (瀏覽器):     fetch 索引 → MiniSearch.loadJSON() → 即時搜尋

Python 端(build time)

from trad_zh_search import tokenize
from trad_zh_search.adapters.minisearch import to_minisearch

doc = to_minisearch(
    fields={
        "title": tokenize(title),
        "content": tokenize(content),
    },
    original={"id": doc_id, "title": title, "url": url},
)
# → {"id": ..., "title": ..., "title_bigram": "台灣 灣人 人權 ...",
#    "content_bigram": "...", ...}

查詢端過濾虛詞

from trad_zh_search.adapters.minisearch import filter_stop_bigrams

bigrams = ["中文", "文工", "工具", "具可", "可以", "搜尋"]
filtered = filter_stop_bigrams(bigrams)
# ["中文", "文工", "工具", "具可", "搜尋"]  ("可以" 被過濾)

JavaScript 端:MiniSearch 的 tokenize 設為空格分割(因為 bigram 已預處理),查詢端用 CJK bigram 分詞即可。完整範例請參考 jacobmei.com 的搜尋實作


TokenResult

@dataclass
class TokenResult:
    original: str        # 輸入原文(截斷後)
    tokens: list[str]    # CKIP 分詞結果(無 CKIP 時為空 list)
    bigrams: list[str]   # CJK bigrams(永遠產生)
    used_ckip: bool      # 是否使用了 CKIP

字典格式

YAML 格式,三個可選區塊:

# 自訂分詞詞庫(Phase 1 核心)
ckip_custom_words:
  - 轉型正義
  - 國家人權委員會

# 別名映射(目前供參考,未來 entity-resolver 會使用)
aliases:
  人權會: 國家人權委員會

# 同義詞組(adapter 可直接輸出為搜尋引擎 synonyms)
synonyms:
  判決: [裁定, 裁判]

字典人名聲明

內建的 christian-zh-hant 字典包含部分知名牧師、神學家、聖經人物及歷史人物的姓名,均來自各教會公開網站及公開出版物。若當事人希望移除,請開 issue 告知,我們會盡速處理。


API 參考

函式 說明
tokenize(text, dictionary?, max_chars?) 分詞 + bigram,回傳 TokenResult
tokenize_batch(texts, dictionary?, batch_size?) 批次版本
load_dictionary(name) 載入內建字典
load_dictionary_file(path) 載入 YAML 字典檔
merge_dictionaries(*dicts) 合併多個字典
save_dictionary(dictionary, path) 儲存字典為 YAML(原子寫入)
build_dictionary(texts, min_freq?) NER 自動提取字典(需要 CKIP)
to_meilisearch(fields, original?) TokenResult → Meilisearch 文件格式
to_meilisearch_batch(fields_list, originals?) 批次版本
to_meilisearch_synonyms(dictionary) 同義詞 → Meilisearch 雙向格式
to_minisearch(fields, original?) TokenResult → MiniSearch 文件格式(含 Latin 詞自動提取)
to_minisearch_batch(fields_list, originals?) 批次版本
filter_stop_bigrams(bigrams) 過濾查詢中的虛詞 bigram
STOP_BIGRAMS 內建繁中虛詞 bigram 集合(frozenset)

詳細參數說明請參考各函式的 docstring。


Roadmap

以下是規劃中但尚未實作的功能:

更多搜尋引擎 Adapter

Adapter 狀態 說明
Meilisearch v0.1 已完成 多欄位格式 + 同義詞轉換
MiniSearch v0.2 已完成 靜態網站客戶端搜尋 + stop-bigrams
Elasticsearch / OpenSearch 規劃中 _analyze 自訂分析器 + mapping 生成
SQLite FTS5 規劃中 trigram tokenizer + 自訂 tokenize 函式
Typesense 考慮中 另一個熱門的開源搜尋引擎

進階文本處理

功能 狀態 說明
Entity Resolver(別名展開) 規劃中 搜「周牧師」自動展開為「周神助 OR 周巽正」
Synonym Expander 規劃中 搜「宣教」自動展開為「宣教 OR 差傳 OR 宣植」
簡繁正規化 考慮中 輸入簡體自動轉繁體再分詞(opencc s2twp)
停用詞過濾 v0.2 部分完成 內建 stop-bigrams(102 個繁中虛詞),完整停用詞表規劃中

工具 & 整合

功能 狀態 說明
CLI 工具 規劃中 trad-zh-search tokenize "你的文本" 命令列直接用
更多領域字典 歡迎貢獻 法律、醫療、教育...
字典品質報告 考慮中 分析字典覆蓋率、衝突、冗餘

有想法或需求?歡迎開 issue 討論。


貢獻

歡迎貢獻領域字典、回報 bug、或提交 PR。詳見 CONTRIBUTING.md


授權

MIT

About

trad-zh-search 可單獨搭配主流搜尋引擎,專門給繁體中文使用的繁體中文文本預處理工具 —— CKIP 分詞 + bigram 索引生成,附可選擇的領域字典系統

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages