辞書マッチング機能
会社名・製品名・禁止ワードなど、正規表現では表現しにくい固有名詞を辞書ベースで検出する機能です。
概要
辞書マッチングでは、あらかじめ登録したワードリストに基づいてテキスト内の固有名詞を検出します。 10万語でも1〜5msの高速検出を実現しています。
⚡
高速検出
10万語でも1〜5msの検出速度
🔍
ファジーマッチング
タイプミスや表記ゆれも類似度ベースで検出
📄
メタデータ対応
各エントリにメタデータを付与可能
カスタム認識器との違い
| 項目 | カスタム認識器 | 辞書マッチング |
|---|---|---|
| 定義方法 | 正規表現パターン | 単語リスト |
| 用途 | 形式が決まったID・番号 | 固有名詞、禁止ワード |
| 例 | EMP-\d{6} |
トヨタ自動車、ProjectX |
| スケール | パターン数個 | 数万〜数十万語 |
Creating a Dictionary
POST
/api/policy/dictionaries
⚠ 楽観的ロック(ETag/If-Match)が必要です
ポリシー変更APIには楽観的ロックが必要です。
まずアクティブポリシーのETagを取得し、If-Matchヘッダーに設定してリクエストしてください。
# 1. ETagを取得
ETAG=$(curl -s -I https://api.pii-fi.com/api/policy/active \
-H "Authorization: Bearer YOUR_API_KEY" | grep -i etag | awk '{print $2}' | tr -d '\r')
# 2. If-Matchヘッダー付きでリクエスト
curl -X POST ... -H "If-Match: $ETAG" ...
Request Parameters
| Parameter | Required | Description |
|---|---|---|
id |
Required | 辞書ID(例: dict.companies) |
name |
Required | 辞書名 |
entity_type |
Required | エンティティタイプ |
entries |
Required | エントリのリスト |
priority |
Optional | 優先度(default: 80) |
normalize |
Optional | 正規化を有効にするか(default: true) |
fuzzy |
Optional | ファジーマッチング(default: false) |
fuzzy_threshold |
Optional | ファジーマッチングの類似度閾値(0.0〜1.0、default: 0.8) |
case_sensitive |
Optional | 大文字小文字を区別するか(default: false) |
Entry Format
json
{
"value": "検出対象のワード",
"metadata": {
"key": "value" // 任意のメタデータ
}
}
Priority Settings
同じテキスト位置で辞書マッチと組み込み検出器の両方がエンティティを検出した場合、優先度の高い方が採用されます。
| 用途 | 推奨優先度 | 説明 |
|---|---|---|
| 禁止ワード(最優先) | 100 | 組み込み検出器(95)より優先 |
| 会社名・製品名 | 90 | 組み込み検出器と競合する可能性がある場合 |
| 一般的な辞書 | 80(デフォルト) | 他の検出器との競合が少ない場合 |
Examples
1. Company Names Dictionary
bash
# ETagを取得
ETAG=$(curl -s -I https://api.pii-fi.com/api/policy/active \
-H "Authorization: Bearer YOUR_API_KEY" | grep -i etag | awk '{print $2}' | tr -d '\r')
# If-Matchヘッダー付きで辞書を作成
curl -X POST https://api.pii-fi.com/api/policy/dictionaries \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG" \
-d '{
"id": "dict.companies",
"name": "会社名辞書",
"entity_type": "JPII_COMPANY_NAME",
"priority": 90,
"entries": [
{"value": "トヨタ自動車", "metadata": {"industry": "自動車"}},
{"value": "ソニー", "metadata": {"industry": "電機"}},
{"value": "任天堂", "metadata": {"industry": "ゲーム"}}
]
}'
2. Prohibited Words Dictionary
bash
# ETag取得後に実行
curl -X POST https://api.pii-fi.com/api/policy/dictionaries \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG" \
-d '{
"id": "dict.prohibited",
"name": "禁止ワード辞書",
"entity_type": "JPII_PROHIBITED_WORD",
"priority": 100,
"normalize": false,
"entries": [
{"value": "ProjectX"},
{"value": "極秘プロジェクト"},
{"value": "CodeName-Alpha"}
]
}'
Fuzzy Matching
ファジーマッチングは、辞書エントリと完全一致しないが類似している文字列を検出する機能です。 タイプミス、表記ゆれ、文字の入れ替わりなど、わずかな違いがある文字列も辞書エントリとして認識できます。
設定方法
bash
# ETag取得後に実行
curl -X POST https://api.pii-fi.com/api/policy/dictionaries \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG" \
-d '{
"id": "dict.products",
"name": "製品名辞書",
"entity_type": "JPII_PRODUCT_NAME",
"priority": 90,
"entries": [
{"value": "Bestllam", "metadata": {"type": "LLM"}},
{"value": "ChatStream", "metadata": {"type": "Chat"}},
{"value": "MotionVox", "metadata": {"type": "Voice"}}
],
"fuzzy": true,
"fuzzy_threshold": 0.8,
"normalize": true
}'
fuzzy_threshold(類似度閾値)
fuzzy_threshold は、入力テキスト中の文字列と辞書エントリの類似度スコアの下限を指定します。
| 閾値 | 特徴 | 適したケース |
|---|---|---|
0.9 |
非常に厳密 | 長い単語(10文字以上)の1文字ミス |
0.8(推奨) |
バランスが良い | 一般的な用途。5文字以上で1文字のタイプミス |
0.7 |
やや緩め | 表記ゆれが多い固有名詞 |
0.6 |
緩め | 誤検出が増えるため注意が必要 |
ファジーマッチの検出結果
ファジーマッチで検出されたエンティティには、通常の辞書マッチとは異なるフィールドが含まれます。
json
// ファジーマッチの場合
{
"entity_type": "JPII_PRODUCT_NAME",
"original_text": "Bestlam",
"confidence_score": 0.88,
"detection_method": "dictionary_fuzzy",
"masking_details": {
"replacement_text": "<製品名>",
"original_entry": "Bestllam",
"matched_text": "Bestlam"
}
}
| フィールド | 説明 |
|---|---|
detection_method |
dictionary_exact(完全一致)、dictionary_normalized(正規化)、dictionary_fuzzy(ファジー) |
confidence_score |
類似度スコア(完全一致は1.0、ファジーマッチは1.0未満) |
original_entry |
ファジーマッチ時のみ。マッチした辞書エントリの元の値 |
Dictionary Management
List Dictionaries
GET
/api/policy/dictionaries
bash
curl https://api.pii-fi.com/api/policy/dictionaries \
-H "Authorization: Bearer YOUR_API_KEY"
Add Entries
POST
/api/policy/dictionaries/{dictionary_id}/entries
bash
# ETag取得後に実行
curl -X POST https://api.pii-fi.com/api/policy/dictionaries/dict.companies/entries \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG" \
-d '{
"entries": [
{"value": "パナソニック", "metadata": {"industry": "電機"}},
{"value": "日立製作所", "metadata": {"industry": "電機"}}
]
}'
Delete Entries
DELETE
/api/policy/dictionaries/{dictionary_id}/entries
bash
# ETag取得後に実行
curl -X DELETE https://api.pii-fi.com/api/policy/dictionaries/dict.companies/entries \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG" \
-d '{
"values": ["パナソニック"]
}'
Delete Dictionary
DELETE
/api/policy/dictionaries/{dictionary_id}
bash
# ETag取得後に実行
curl -X DELETE https://api.pii-fi.com/api/policy/dictionaries/dict.companies \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-Match: $ETAG"
Python Client Example
python
import requests
class DictionaryManager:
# base_url: デモ環境(本番環境では専用エンドポイントを提供)
def __init__(self, api_key, base_url="https://api.pii-fi.com/api"):
self.api_key = api_key
self.base_url = base_url
self.headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
def _get_etag(self):
"""アクティブポリシーのETagを取得"""
response = requests.get(
f"{self.base_url}/policy/active",
headers=self.headers
)
return response.headers.get("ETag")
def list_dictionaries(self):
"""辞書一覧を取得"""
response = requests.get(
f"{self.base_url}/policy/dictionaries",
headers=self.headers
)
response.raise_for_status()
return response.json()
def create_dictionary(self, config):
"""辞書を作成"""
etag = self._get_etag()
response = requests.post(
f"{self.base_url}/policy/dictionaries",
headers={**self.headers, "If-Match": etag},
json=config
)
response.raise_for_status()
return response.json()
def add_entries(self, dictionary_id, entries):
"""エントリを追加"""
etag = self._get_etag()
response = requests.post(
f"{self.base_url}/policy/dictionaries/{dictionary_id}/entries",
headers={**self.headers, "If-Match": etag},
json={"entries": entries}
)
response.raise_for_status()
return response.json()
def delete_entries(self, dictionary_id, values):
"""エントリを削除"""
etag = self._get_etag()
response = requests.delete(
f"{self.base_url}/policy/dictionaries/{dictionary_id}/entries",
headers={**self.headers, "If-Match": etag},
json={"values": values}
)
response.raise_for_status()
return response.json()
# 使用例
manager = DictionaryManager("YOUR_API_KEY")
# ファジーマッチング有効の製品名辞書を作成
manager.create_dictionary({
"id": "dict.products",
"name": "製品名辞書",
"entity_type": "JPII_PRODUCT_NAME",
"priority": 90,
"entries": [
{"value": "Bestllam", "metadata": {"type": "LLM"}},
{"value": "ChatStream", "metadata": {"type": "Chat"}}
],
"fuzzy": True,
"fuzzy_threshold": 0.8
})
# タイプミスを含むテキストで検出テスト
detect_response = requests.post(
f"{manager.base_url}/detect",
headers=manager.headers,
json={
"text": "弊社のBestlamとChatSteamをご紹介します",
"deidentification_type": "replace"
}
)
result = detect_response.json()
print(result["deidentified_text"])
# → "弊社の<製品名>と<製品名>をご紹介します"
Use Cases
| Use Case | Entity Type | 推奨設定 |
|---|---|---|
| 禁止ワード検出 | JPII_PROHIBITED_WORD |
priority: 100, fuzzy: true, threshold: 0.7 |
| 会社名検出 | JPII_COMPANY_NAME |
priority: 90, fuzzy: true, threshold: 0.8 |
| 製品名検出 | JPII_PRODUCT_NAME |
priority: 90, fuzzy: true, threshold: 0.8 |
| 短いコード検出 | JPII_CODE |
priority: 80, fuzzy: false, case_sensitive: true |
Performance
⚡ High Performance
辞書サイズに関わらず高速な検出を実現しています。
- 10,000語: < 1ms
- 100,000語: 1〜5ms
- 1,000,000語: 5〜10ms
💡 ファジーマッチングのパフォーマンス
ファジーマッチングは完全一致マッチングと比較して処理コストが高くなります。
タイプミスが想定される辞書のみ fuzzy: true に設定することを推奨します。