DEV Community

JH5
JH5

Posted on

PII 偵測實測 : Regex vs BERT-NER vs Ensemble

PII 偵測三路對比:Regex vs BERT-NER vs Ensemble 在 9 個醫療與商業場景的實測

要替 LLM pipeline 加 PII 偵測,最常見的問題是:規則式(Regex)夠不夠用?BERT-NER 能補什麼?這次我們拿 9 個測試案例(商業合約、HR 記錄、程式碼審查、EMR 出院摘要、VCF 基因報告、放射科報告,加上 3 種混淆格式的 PII)做了三路比較。結果是:Ensemble 拿到最高平均 F1 = 0.662,BERT-NER 單獨跑反而只有 0.167——在醫療文本上幾乎全滅。

這份報告記錄了 2026 年 4 月底的實測數據,適合正在為醫療 AI pipeline 選 PII 偵測方案的工程師。

三個方法的設計邏輯

M1 Regex(純規則):手刻台灣電話格式(09XX-XXX-XXX)、電子郵件、身分證(A123456789)、日期(YYYY-MM-DD)、健保碼、MRN 格式。設計上只抓格式特徵,不需要語意理解。延遲幾乎是零(<0.3ms/筆)。

M2 BERT-NER(dslim/bert-base-NER:只辨識 PER / ORG / LOC / MISC 四類實體。強項是抓中英文姓名和機構名,但對台灣特有的格式(健保碼 AB12345678、MRN 代碼)完全沒有訓練過。延遲約 40ms 到 5900ms(視文本長度,第一次 load 最慢)。

M3 Ensemble:M1 OR M2,任一方抓到就算命中。理論上可以互補,但也會把兩邊的 FP 疊加。

9 個測試案例的結果

案例 領域 Regex F1 BERT-NER F1 Ensemble F1
T1-01 商業合約 0.750 0.571 1.000
T1-02 HR 記錄 0.571 0.333 0.750
T1-03 程式碼審查 0.800 0.000 0.800
T2-01 EMR 出院摘要 0.800 0.000 0.800
T2-02 VCF 基因報告 0.833 0.600 0.941
T2-03 放射科報告 0.750 0.000 0.667
T3-01 混淆:分拆格式 1.000 0.000 1.000
T3-02 混淆:同音編碼 0.000 0.000 0.000
T3-03 混淆:語境偽裝 0.000 0.000 0.000
平均 - 0.612 0.167 0.662

幾個有意思的發現

BERT-NER 在醫療文本上近乎廢掉。T2-01(EMR)和 T2-03(放射科報告)的 F1 都是 0.000,原因很直接:BERT-NER 只認識四類命名實體,對「0912-345-678」這種電話、「MRN: 0987654」這種病歷號碼、「19820712」這種生日格式完全不認識。Regex 在這幾題反而表現穩定,把大部分有格式特徵的 PII 都抓到了。

程式碼審查(T1-03)裡 BERT-NER 也全滅。API key sk-abc123XYZ 和 email 在程式碼 context 裡,BERT-NER 認不出來。Regex 靠 sk- prefix 和 email pattern 抓到了 2/3。

混淆格式是三個方法共同的死穴。T3-02 和 T3-03 全部歸零。T3-02 是同音編碼(「零九一二三四五六七八」、「john DOT smith AT example DOT com」),T3-03 是語境偽裝(聊天裡藏的 PII,沒有明確結構)。Regex 和 BERT-NER 都不是設計來處理這類問題的——這是 LLM-based 方案才有機會做到的事。

Ensemble 在大多數標準格式 PII 場景勝出,但在混淆場景同樣無效。T2-03(放射科報告)的 Ensemble 反而比 Regex 低(0.667 vs 0.750),是因為 BERT-NER 把「Taipei Veterans General Hospital」這個機構名抓進來,造成 FP 增加而拉低分數。這說明 OR 邏輯的代價:當 NER 誤判時,Ensemble 沒有辦法自動降權。

跟 Piiranha 的對比

我們之前測過 Piiranha GPU(RTX 3090 FP16 batch-16),整體 F1 = 0.9866,是目前在我們測試集上跑出最高分的方案。相比起來,這次的 Ensemble 最高只到 0.662。

差距在哪?Piiranha 是為 PII 偵測特別訓練的模型,覆蓋的類別更多、格式更廣;BERT-NER 只是通用命名實體辨識,根本不是為 PII 設計的。純 Regex 則天生受限於你手刻了多少 pattern。

如果你的部署環境有 GPU(任何 RTX 卡),Piiranha 是目前 ROI 最高的選擇。如果是 CPU-only 環境,Regex 對格式清楚的商業文件已經夠用,配上 BERT-NER 做姓名補漏是合理的 fallback。

混淆格式和醫療特有 PII 目前沒有現成的完美解法——要麼接 LLM 做語意偵測(latency 換準確率),要麼接 openai/privacy-filter 這種 128k context 的大模型,讓它一次掃整份文件。

給工程師的建議

幾個在設計 PII pipeline 前要想清楚的問題:

  1. 你的 PII 是否有格式特徵?台灣身分證、健保號、電話、MRN,格式清楚 → Regex 夠用,速度最快(<1ms/筆)。
  2. 你需要抓姓名和機構名嗎?這是 BERT-NER 的強項,但要接受它在醫療文本的失效率。
  3. 文件是否有混淆或刻意繞過的可能?這種情境目前只有 LLM 方案有機會應對。
  4. CPU only 還是有 GPU?有 GPU 直上 Piiranha,沒 GPU 用 Regex + BERT-NER Ensemble 先撐著。

  • 測試腳本:experiments/a_safety_guardrails/batch_o2_privacy_filter.py
  • 主要結果:batch_o2_privacy_results_20260430_115710.json
  • 混淆格式補測:batch_o2_r2_20260430_115938.json
  • 對比基準:Piiranha GPU F1=0.9866(experiments/pii/piiranha_pii_results.json

Top comments (0)