Files
detect-policy-conflict-gs/scripts/util/conflict_classifier.py

88 lines
2.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""冲突严重程度分级纯函数。
依据:
- 高(high):相似度 >= HIGH_CONFLICT_THRESHOLD → 制度文件核心条款直接冲突
- 中(medium):相似度 >= MEDIUM_CONFLICT_THRESHOLD → 程序/用词层歧义
- 低(low):其它(如命名相似但实质无关)
"""
from __future__ import annotations
from typing import Tuple
def classify_conflict_severity(
similarity: float,
thresholds: Tuple[float, float] = (0.85, 0.92),
) -> str:
"""根据条款相似度返回冲突等级。
thresholds = (medium_min, high_min),须 0 <= medium_min <= high_min <= 1。
返回:'high' / 'medium' / 'low'。
"""
medium_min, high_min = thresholds
if similarity >= high_min:
return "high"
if similarity >= medium_min:
return "medium"
return "low"
def normalize_policy_text(s: str) -> str:
"""规范化制度文本:去空白 + 中文/英文标点统一。
用于语义比对前的预处理,确保章节编号差异不干扰相似度计算。
转换规则:
- 全角空格 → 半角空格
- 全角 ASCII(数字 0-9 / 字母 A-Z a-z / 常见标点)→ 半角
- 合并连续空白为单空格
"""
if s is None:
return ""
# 全角 ASCII 标点 → 半角(覆盖冒号/逗号/句号/分号/问号/感叹号/括号/方括号/引号)
full_to_half_punct = {
",": ",", "。": ".", ":": ":", ";": ";",
"?": "?", "!": "!", "(": "(", ")": ")",
"【": "[", "】": "]", "『": "'", "』": "'",
"「": "'", "」": "'",
}
out_chars = []
for ch in str(s):
code = ord(ch)
# 全角空格
if ch == " ":
out_chars.append(" ")
continue
# 已映射的标点
if ch in full_to_half_punct:
out_chars.append(full_to_half_punct[ch])
continue
# 全角数字 0xFF10-0xFF19 → 0x30-0x39
if 0xFF10 <= code <= 0xFF19:
out_chars.append(chr(code - 0xFEE0))
continue
# 全角字母 0xFF21-0xFF3A / 0xFF41-0xFF5A → 半角
if 0xFF21 <= code <= 0xFF3A:
out_chars.append(chr(code - 0xFEE0))
continue
if 0xFF41 <= code <= 0xFF5A:
out_chars.append(chr(code - 0xFEE0))
continue
out_chars.append(ch)
text = "".join(out_chars)
# 合并连续空白为单空格
return " ".join(text.split())
def parse_policy_draft_id(s: str) -> str:
"""解析送审稿 ID:去空白 + 校验非空。
占位骨架的轻量校验,业务层后续接入更严格规则。
"""
if s is None:
raise ValueError("policy_draft_id 不能为空")
s = str(s).strip()
if not s:
raise ValueError("policy_draft_id 不能为空")
return s