| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- # PREMPredict.predict_money / correct_money_by_rule 模型后修正规则
- # (角色分类流程优化 Phase B 外置 / Phase C 机器可读化)。
- #
- # 来源:dl/predictors/prem.py
- # - PREMPredict.predict_money(约 403-437 行):按 label 分支的金额修正链
- # - PREMPredict.correct_money_by_rule(约 440-454 行):标题/正文类别修正
- #
- # 机器可读语义(Phase C RoleRuleEngine 消费):
- # - stage:引擎执行阶段。金额链路固定阶段序(对应原代码 if/elif 短路语义):
- # 阈值过滤(label∈[0,1] 且 values[label]<p_model_threshold → label=2,
- # 终止)→ 按 label 进入分支阶段:
- # label=1 → m1;label=0 → m0;label=2 → m_bid
- # (阈值过滤命中的实体不再走任何分支;label 0/1 的 elif 分支必被取走,
- # 故 m_bid 阶段仅有模型原始 label=2 的实体到达,原代码
- # `label != 1 or values[label] < 0.5` 条件由阶段序保证恒真。)
- # doc_title 阶段独立于上述链路,由 correct_money_by_rule 按标题/正文
- # 类别批量修正(entity_filter 过滤实体,不依赖 front/behind 切片)。
- # - model_labels:规则仅对当前 label 命中列表内值时生效。
- # 标签映射:0=招标金额(预算/控制价),1=中标金额(成交价),2=其他金额。
- # - applies_to:pattern 匹配的切片。front=金额实体前文(13 字),
- # behind=金额实体后文(15 字),title=公告标题(doc_title 阶段用)。
- # - window:applies_to 切片的截断(front 取末 size 字 / behind 取前 size 字),
- # 对应原代码 front[-N:]/behind[:N]。
- # - guard / guard_not / or_trigger:结构化条件(AND / OR-排除 / OR-替代触发),
- # 类型见 schema/pattern_schema.json definitions.condition。
- # 条件 on=title_content_head 时求值目标为 标题+正文前 size 字,
- # 对应原代码 title + content[:100]。
- # - entity_filter:doc_title 阶段实体过滤(entity_type / notes_in / label)。
- # - set_label / set_prob:命中后改写的标签与概率。set_prob.index 显式指定
- # values 写入槽位;缺省 = set_label(若有)否则当前 label。原代码中
- # `values[旧label]=x; label=N`(先写概率后改标签)用 index=旧label 表达。
- # - 阈值过滤为程序逻辑(非 YAML 规则),引擎用 probability_ladder 的
- # p_model_threshold 常量执行。
- version: 1
- category: MONEY
- description: >-
- 金额模型预测后的上下文修正规则:按模型预测 label 分支,用金额实体
- 前文(front)/后文(behind)模式纠正错分的招标金额/中标金额/其他金额,
- 以及按公告标题类别的批量修正。
- probability_ladder:
- p_model_threshold: 0.5
- p_rule_override: 0.501
- p_fallback: 0.51
- p_title: 0.55
- patterns:
- # ---- m1:label=1(中标金额)分支 ----
- - id: fix_m1_total_price_boost
- description: '前文:(总金额|总价|单价|合价): 结尾且前文不含 中标|投标|成交|中价 → 保持 label=1,values[1]=0.5'
- stage: m1
- model_labels: [1]
- applies_to: front
- pattern: '[::,。](总金额|总价|单价|合价)((万?元))?:?$'
- guard_not:
- - {type: regex, on: front, pattern: '中标|投标|成交|中价'}
- set_prob: {value: 0.5}
- golden_examples:
- - input: ',总价:'
- should_match: true
- - input: '总价'
- should_match: false
- - id: fix_m1_formula_demote
- description: '前文:+(中标金额 / 如中标金额为 等公式变量 → values[1]=0.49。doc 241561780'
- stage: m1
- model_labels: [1]
- applies_to: front
- pattern: '[\+=]((中标|成交)(金?额|价格?)|[若如]果?(中标|成交)(金?额|价格?)为?'
- set_prob: {value: 0.49}
- golden_examples:
- - input: '如中标金额为'
- should_match: true
- - input: '中标金额'
- should_match: false
- - id: fix_m1_rate_demote
- description: '后文[:20]:按N%收取 / 及以上 / +N% / 服务招标费率 / 招标代理服务收费 → values[1]=0.49。doc 628951835'
- stage: m1
- model_labels: [1]
- applies_to: behind
- window: {size: 20}
- pattern: '^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+|服务招标费率|招标代理服务收费'
- set_prob: {value: 0.49}
- golden_examples:
- - input: '按1.5%收取'
- should_match: true
- - input: '以上'
- should_match: true
- - input: '收取'
- should_match: false
- - id: fix_m1_inclusive_demote
- description: '前文:(含|在|包括|大于|达到)$ 或 N%× 结尾 → values[1]=0.49'
- stage: m1
- model_labels: [1]
- applies_to: front
- pattern: '(含|在|包括|[大小等高低]于|达到)$|[\d.%]+[+×*-]$'
- set_prob: {value: 0.49}
- golden_examples:
- - input: '控制在'
- should_match: true
- - input: '100×'
- should_match: true
- - input: '含税'
- should_match: false
- # ---- m0:label=0(招标金额)分支 ----
- - id: fix_m0_investment_boost
- description: '前文:投资(金额|规模): 结尾,或 entity.notes ∈ {投资,总投资,工程造价} → 保持 label=0,values[0]=0.51。doc 545988699'
- stage: m0
- model_labels: [0]
- applies_to: front
- pattern: '投资(金额|规模):$'
- or_trigger:
- - {type: notes_in, values: ['投资', '总投资', '工程造价']}
- set_prob: {value: 0.51}
- golden_examples:
- - input: '投资金额:'
- should_match: true
- - input: '总金额:'
- should_match: false
- - id: fix_m0_floor_price_demote
- description: '前文:最低限价:/注册资本 或 服务内容:N元- 结尾 → values[0]=0.49 且 label=2'
- stage: m0
- model_labels: [0]
- applies_to: front
- pattern: '最低限价:?$|注册资本|服务内容:([\d,.]+万?亿?元?-?)$'
- set_label: 2
- set_prob: {index: 0, value: 0.49}
- golden_examples:
- - input: '最低限价:'
- should_match: true
- - input: '注册资本'
- should_match: true
- - input: '最高限价:'
- should_match: false
- - id: fix_m0_rate_demote
- description: '后文:按N%收取 / 及以上 / +N% / (含) → values[0]=0.49'
- stage: m0
- model_labels: [0]
- applies_to: behind
- pattern: '^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+|(含)'
- set_prob: {value: 0.49}
- golden_examples:
- - input: '以上'
- should_match: true
- - input: '下'
- should_match: false
- - id: fix_m0_estimate_demote
- description: '前文:预计约?为$ 结尾且前文不含 招标金额|限价|预算|控制价|拦标价 → label=2。doc 565894149'
- stage: m0
- model_labels: [0]
- applies_to: front
- pattern: '预计约?为?$'
- guard_not:
- - {type: regex, on: front, pattern: '招标金额|限价|预算|控制价|拦标价'}
- set_label: 2
- golden_examples:
- - input: '(预计约'
- should_match: true
- - input: '预算约为'
- should_match: false
- - id: fix_m0_hangwang_demote
- description: '前文:挂网价((万?元)): → label=2。doc 634316533'
- stage: m0
- model_labels: [0]
- applies_to: front
- pattern: '挂网价((万?元))?:'
- set_label: 2
- golden_examples:
- - input: '挂网价(元):'
- should_match: true
- - input: '网价:'
- should_match: false
- # ---- m_bid:label=2(其他金额)分支(模型原始 label=2 才到达)----
- - id: fix_m_bid_total_boost
- description: '前文:报价:预估不?含税总价[为:]$ 且(label≠1 或 values[label]<0.5;由阶段序保证恒真)→ label=1,values[1]=0.8'
- stage: m_bid
- model_labels: [2]
- applies_to: front
- pattern: '报价:预估不?含税总价[为:]$'
- set_label: 1
- set_prob: {value: 0.8}
- golden_examples:
- - input: '报价:预估不含税总价:'
- should_match: true
- - input: '报价:'
- should_match: false
- # ---- doc_title:标题/正文类别批量修正(correct_money_by_rule)----
- - id: fix_m_title_tenderee_amount
- description: >-
- 标题恰含一个 监理|施工|设计|勘察 且不含 施工|总承包|EPC,或正文含 服务金额:
- 将 notes=招标或中标金额 且 label=2 的金额实体改为招标金额(values[0]=0.55)。
- 标题+正文前100字不含 中标|成交|中选|中价|中租|结果|入围 时走本规则,
- 否则走 fix_m_title_winner_amount。
- stage: doc_title
- applies_to: title
- pattern: '监理|施工|设计|勘察'
- or_trigger:
- - {type: regex, on: content, pattern: '服务金额'}
- guard:
- - type: any
- of:
- - type: all
- of:
- - {type: count_eq, on: title, pattern: '监理|施工|设计|勘察', equals: 1}
- - {type: regex_not, on: title, pattern: '施工|总承包|epc|EPC'}
- - {type: regex, on: content, pattern: '服务金额'}
- guard_not:
- - {type: regex, on: title_content_head, size: 100, pattern: '中标|成交|中选|中价|中租|结果|入围'}
- entity_filter:
- entity_type: money
- notes_in: ['招标或中标金额']
- label: 2
- set_label: 0
- set_prob: {value: 0.55}
- golden_examples:
- - input: '某监理服务项目招标公告'
- should_match: true
- - input: '某货物采购项目公告'
- should_match: false
- - id: fix_m_title_winner_amount
- description: >-
- 同 fix_m_title_tenderee_amount 的触发条件,但标题+正文前100字含
- 中标|成交|中选|中价|中租|结果|入围(中标/成交类公告):
- 将 notes=招标或中标金额 且 label=2 的金额实体改为中标金额(values[1]=0.55)。
- stage: doc_title
- applies_to: title
- pattern: '监理|施工|设计|勘察'
- or_trigger:
- - {type: regex, on: content, pattern: '服务金额'}
- guard:
- - type: any
- of:
- - type: all
- of:
- - {type: count_eq, on: title, pattern: '监理|施工|设计|勘察', equals: 1}
- - {type: regex_not, on: title, pattern: '施工|总承包|epc|EPC'}
- - {type: regex, on: content, pattern: '服务金额'}
- - {type: regex, on: title_content_head, size: 100, pattern: '中标|成交|中选|中价|中租|结果|入围'}
- entity_filter:
- entity_type: money
- notes_in: ['招标或中标金额']
- label: 2
- set_label: 1
- set_prob: {value: 0.55}
- golden_examples:
- - input: '某监理服务项目中标公告'
- should_match: true
- - input: '某货物采购项目公告'
- should_match: false
|