role_money_fix.yaml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # PREMPredict.predict_money / correct_money_by_rule 模型后修正规则
  2. # (角色分类流程优化 Phase B 外置 / Phase C 机器可读化)。
  3. #
  4. # 来源:dl/predictors/prem.py
  5. # - PREMPredict.predict_money(约 403-437 行):按 label 分支的金额修正链
  6. # - PREMPredict.correct_money_by_rule(约 440-454 行):标题/正文类别修正
  7. #
  8. # 机器可读语义(Phase C RoleRuleEngine 消费):
  9. # - stage:引擎执行阶段。金额链路固定阶段序(对应原代码 if/elif 短路语义):
  10. # 阈值过滤(label∈[0,1] 且 values[label]<p_model_threshold → label=2,
  11. # 终止)→ 按 label 进入分支阶段:
  12. # label=1 → m1;label=0 → m0;label=2 → m_bid
  13. # (阈值过滤命中的实体不再走任何分支;label 0/1 的 elif 分支必被取走,
  14. # 故 m_bid 阶段仅有模型原始 label=2 的实体到达,原代码
  15. # `label != 1 or values[label] < 0.5` 条件由阶段序保证恒真。)
  16. # doc_title 阶段独立于上述链路,由 correct_money_by_rule 按标题/正文
  17. # 类别批量修正(entity_filter 过滤实体,不依赖 front/behind 切片)。
  18. # - model_labels:规则仅对当前 label 命中列表内值时生效。
  19. # 标签映射:0=招标金额(预算/控制价),1=中标金额(成交价),2=其他金额。
  20. # - applies_to:pattern 匹配的切片。front=金额实体前文(13 字),
  21. # behind=金额实体后文(15 字),title=公告标题(doc_title 阶段用)。
  22. # - window:applies_to 切片的截断(front 取末 size 字 / behind 取前 size 字),
  23. # 对应原代码 front[-N:]/behind[:N]。
  24. # - guard / guard_not / or_trigger:结构化条件(AND / OR-排除 / OR-替代触发),
  25. # 类型见 schema/pattern_schema.json definitions.condition。
  26. # 条件 on=title_content_head 时求值目标为 标题+正文前 size 字,
  27. # 对应原代码 title + content[:100]。
  28. # - entity_filter:doc_title 阶段实体过滤(entity_type / notes_in / label)。
  29. # - set_label / set_prob:命中后改写的标签与概率。set_prob.index 显式指定
  30. # values 写入槽位;缺省 = set_label(若有)否则当前 label。原代码中
  31. # `values[旧label]=x; label=N`(先写概率后改标签)用 index=旧label 表达。
  32. # - 阈值过滤为程序逻辑(非 YAML 规则),引擎用 probability_ladder 的
  33. # p_model_threshold 常量执行。
  34. version: 1
  35. category: MONEY
  36. description: >-
  37. 金额模型预测后的上下文修正规则:按模型预测 label 分支,用金额实体
  38. 前文(front)/后文(behind)模式纠正错分的招标金额/中标金额/其他金额,
  39. 以及按公告标题类别的批量修正。
  40. probability_ladder:
  41. p_model_threshold: 0.5
  42. p_rule_override: 0.501
  43. p_fallback: 0.51
  44. p_title: 0.55
  45. patterns:
  46. # ---- m1:label=1(中标金额)分支 ----
  47. - id: fix_m1_total_price_boost
  48. description: '前文:(总金额|总价|单价|合价): 结尾且前文不含 中标|投标|成交|中价 → 保持 label=1,values[1]=0.5'
  49. stage: m1
  50. model_labels: [1]
  51. applies_to: front
  52. pattern: '[::,。](总金额|总价|单价|合价)((万?元))?:?$'
  53. guard_not:
  54. - {type: regex, on: front, pattern: '中标|投标|成交|中价'}
  55. set_prob: {value: 0.5}
  56. golden_examples:
  57. - input: ',总价:'
  58. should_match: true
  59. - input: '总价'
  60. should_match: false
  61. - id: fix_m1_formula_demote
  62. description: '前文:+(中标金额 / 如中标金额为 等公式变量 → values[1]=0.49。doc 241561780'
  63. stage: m1
  64. model_labels: [1]
  65. applies_to: front
  66. pattern: '[\+=]((中标|成交)(金?额|价格?)|[若如]果?(中标|成交)(金?额|价格?)为?'
  67. set_prob: {value: 0.49}
  68. golden_examples:
  69. - input: '如中标金额为'
  70. should_match: true
  71. - input: '中标金额'
  72. should_match: false
  73. - id: fix_m1_rate_demote
  74. description: '后文[:20]:按N%收取 / 及以上 / +N% / 服务招标费率 / 招标代理服务收费 → values[1]=0.49。doc 628951835'
  75. stage: m1
  76. model_labels: [1]
  77. applies_to: behind
  78. window: {size: 20}
  79. pattern: '^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+|服务招标费率|招标代理服务收费'
  80. set_prob: {value: 0.49}
  81. golden_examples:
  82. - input: '按1.5%收取'
  83. should_match: true
  84. - input: '以上'
  85. should_match: true
  86. - input: '收取'
  87. should_match: false
  88. - id: fix_m1_inclusive_demote
  89. description: '前文:(含|在|包括|大于|达到)$ 或 N%× 结尾 → values[1]=0.49'
  90. stage: m1
  91. model_labels: [1]
  92. applies_to: front
  93. pattern: '(含|在|包括|[大小等高低]于|达到)$|[\d.%]+[+×*-]$'
  94. set_prob: {value: 0.49}
  95. golden_examples:
  96. - input: '控制在'
  97. should_match: true
  98. - input: '100×'
  99. should_match: true
  100. - input: '含税'
  101. should_match: false
  102. # ---- m0:label=0(招标金额)分支 ----
  103. - id: fix_m0_investment_boost
  104. description: '前文:投资(金额|规模): 结尾,或 entity.notes ∈ {投资,总投资,工程造价} → 保持 label=0,values[0]=0.51。doc 545988699'
  105. stage: m0
  106. model_labels: [0]
  107. applies_to: front
  108. pattern: '投资(金额|规模):$'
  109. or_trigger:
  110. - {type: notes_in, values: ['投资', '总投资', '工程造价']}
  111. set_prob: {value: 0.51}
  112. golden_examples:
  113. - input: '投资金额:'
  114. should_match: true
  115. - input: '总金额:'
  116. should_match: false
  117. - id: fix_m0_floor_price_demote
  118. description: '前文:最低限价:/注册资本 或 服务内容:N元- 结尾 → values[0]=0.49 且 label=2'
  119. stage: m0
  120. model_labels: [0]
  121. applies_to: front
  122. pattern: '最低限价:?$|注册资本|服务内容:([\d,.]+万?亿?元?-?)$'
  123. set_label: 2
  124. set_prob: {index: 0, value: 0.49}
  125. golden_examples:
  126. - input: '最低限价:'
  127. should_match: true
  128. - input: '注册资本'
  129. should_match: true
  130. - input: '最高限价:'
  131. should_match: false
  132. - id: fix_m0_rate_demote
  133. description: '后文:按N%收取 / 及以上 / +N% / (含) → values[0]=0.49'
  134. stage: m0
  135. model_labels: [0]
  136. applies_to: behind
  137. pattern: '^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+|(含)'
  138. set_prob: {value: 0.49}
  139. golden_examples:
  140. - input: '以上'
  141. should_match: true
  142. - input: '下'
  143. should_match: false
  144. - id: fix_m0_estimate_demote
  145. description: '前文:预计约?为$ 结尾且前文不含 招标金额|限价|预算|控制价|拦标价 → label=2。doc 565894149'
  146. stage: m0
  147. model_labels: [0]
  148. applies_to: front
  149. pattern: '预计约?为?$'
  150. guard_not:
  151. - {type: regex, on: front, pattern: '招标金额|限价|预算|控制价|拦标价'}
  152. set_label: 2
  153. golden_examples:
  154. - input: '(预计约'
  155. should_match: true
  156. - input: '预算约为'
  157. should_match: false
  158. - id: fix_m0_hangwang_demote
  159. description: '前文:挂网价((万?元)): → label=2。doc 634316533'
  160. stage: m0
  161. model_labels: [0]
  162. applies_to: front
  163. pattern: '挂网价((万?元))?:'
  164. set_label: 2
  165. golden_examples:
  166. - input: '挂网价(元):'
  167. should_match: true
  168. - input: '网价:'
  169. should_match: false
  170. # ---- m_bid:label=2(其他金额)分支(模型原始 label=2 才到达)----
  171. - id: fix_m_bid_total_boost
  172. description: '前文:报价:预估不?含税总价[为:]$ 且(label≠1 或 values[label]<0.5;由阶段序保证恒真)→ label=1,values[1]=0.8'
  173. stage: m_bid
  174. model_labels: [2]
  175. applies_to: front
  176. pattern: '报价:预估不?含税总价[为:]$'
  177. set_label: 1
  178. set_prob: {value: 0.8}
  179. golden_examples:
  180. - input: '报价:预估不含税总价:'
  181. should_match: true
  182. - input: '报价:'
  183. should_match: false
  184. # ---- doc_title:标题/正文类别批量修正(correct_money_by_rule)----
  185. - id: fix_m_title_tenderee_amount
  186. description: >-
  187. 标题恰含一个 监理|施工|设计|勘察 且不含 施工|总承包|EPC,或正文含 服务金额:
  188. 将 notes=招标或中标金额 且 label=2 的金额实体改为招标金额(values[0]=0.55)。
  189. 标题+正文前100字不含 中标|成交|中选|中价|中租|结果|入围 时走本规则,
  190. 否则走 fix_m_title_winner_amount。
  191. stage: doc_title
  192. applies_to: title
  193. pattern: '监理|施工|设计|勘察'
  194. or_trigger:
  195. - {type: regex, on: content, pattern: '服务金额'}
  196. guard:
  197. - type: any
  198. of:
  199. - type: all
  200. of:
  201. - {type: count_eq, on: title, pattern: '监理|施工|设计|勘察', equals: 1}
  202. - {type: regex_not, on: title, pattern: '施工|总承包|epc|EPC'}
  203. - {type: regex, on: content, pattern: '服务金额'}
  204. guard_not:
  205. - {type: regex, on: title_content_head, size: 100, pattern: '中标|成交|中选|中价|中租|结果|入围'}
  206. entity_filter:
  207. entity_type: money
  208. notes_in: ['招标或中标金额']
  209. label: 2
  210. set_label: 0
  211. set_prob: {value: 0.55}
  212. golden_examples:
  213. - input: '某监理服务项目招标公告'
  214. should_match: true
  215. - input: '某货物采购项目公告'
  216. should_match: false
  217. - id: fix_m_title_winner_amount
  218. description: >-
  219. 同 fix_m_title_tenderee_amount 的触发条件,但标题+正文前100字含
  220. 中标|成交|中选|中价|中租|结果|入围(中标/成交类公告):
  221. 将 notes=招标或中标金额 且 label=2 的金额实体改为中标金额(values[1]=0.55)。
  222. stage: doc_title
  223. applies_to: title
  224. pattern: '监理|施工|设计|勘察'
  225. or_trigger:
  226. - {type: regex, on: content, pattern: '服务金额'}
  227. guard:
  228. - type: any
  229. of:
  230. - type: all
  231. of:
  232. - {type: count_eq, on: title, pattern: '监理|施工|设计|勘察', equals: 1}
  233. - {type: regex_not, on: title, pattern: '施工|总承包|epc|EPC'}
  234. - {type: regex, on: content, pattern: '服务金额'}
  235. - {type: regex, on: title_content_head, size: 100, pattern: '中标|成交|中选|中价|中租|结果|入围'}
  236. entity_filter:
  237. entity_type: money
  238. notes_in: ['招标或中标金额']
  239. label: 2
  240. set_label: 1
  241. set_prob: {value: 0.55}
  242. golden_examples:
  243. - input: '某监理服务项目中标公告'
  244. should_match: true
  245. - input: '某货物采购项目公告'
  246. should_match: false