fix: tighten yoga precision pass
This commit is contained in:
@@ -1,5 +1,34 @@
|
||||
# 印度占星 Skill 更新日志
|
||||
|
||||
## v6.0.35(2026-06-05)—— Yoga 精度二次提升与 Top FP 收窄
|
||||
|
||||
> **目标**:在 v6.0.34 已大幅提升 F1 后,继续按验证报告 Top FP/FN 队列修正高影响规则,优先降低过宽误报,同时保持质量门禁通过。
|
||||
|
||||
### 对齐与修复
|
||||
|
||||
- 修正 `matsya_yoga`:从过宽的“吉星三方+凶星凶宫”改为 PyJHora/PVR method=2 口径:Lagna 与 9宫仅吉星,5宫同时有吉/凶星,4宫与8宫仅凶星。
|
||||
- 修正 `sankha_yoga`:补齐 PyJHora/BVR-12 双分支:上升主强且5/6宫主互为 Kendra,或1/10宫主合于变动星座且9宫主强。
|
||||
- 修正 `bvr_103_guru_mangala_yoga`:从“木火互为 Kendra”收窄为 PyJHora 定义:木星与火星同宫或互为7宫。
|
||||
- 调整 `bvr_rogagrastha_precise`:对齐 PyJHora D1-safe 条件:上升主在Lagna合凶宫主,或弱上升主合角/三方主。
|
||||
- 修正 `bvr_kaalanirdesat_puthranaasa_yoga`:从单一“5宫主受土/Rahu伤”改为 PyJHora 229/230 组合条件。
|
||||
- 修复 `validate_logic_v2.py` 中 `kaahala_yoga` 的历史别名映射,确保 PyJHora `kaahala_yoga` 正确归入现有 `kahala_yoga`。
|
||||
- 为 custom Yoga 表达式新增 `occupants()`、`only_benefics_in_house()`、`only_malefics_in_house()`、`house_has_benefic()`、`house_has_malefic()`、`house_sign()`、`movable_house()` 与 `MOVABLE_SIGNS`,支持更接近源码的规则表达。
|
||||
|
||||
### 当前验证结果
|
||||
|
||||
- `scripts/validate_logic_v2.py`:Precision **83.84%**,Recall **69.64%**,F1 **76.08%**。
|
||||
- 相比 v6.0.34 的 F1 **74.13%**,提升 **+1.95 个百分点**;相比 v6.0.32/v6.0.33 基线 **58.08%**,累计提升 **+18.00 个百分点**。
|
||||
- `pytest tests/test_yoga_rules_integrity.py tests/test_dasha.py`:25 passed。
|
||||
- `scripts/run_quality_gate.py --skip-yoga-logic`:通过;完整 pytest 35 passed,BPHS/Ashtakavarga 不变量 18/18 通过,golden case 通过。
|
||||
|
||||
### 已知后续优化点
|
||||
|
||||
- 剩余 FN 主要集中在 `mathibhramana`、`matrunasa`、`rogagrastha`、`bahu_puthra`、`kahala`、`nishkapata`、`swaveeryaddhana` 等规则,其中部分需要 D9/Navamsa、tithi/waning Moon 或 Gulika 等当前 D1 静态验证数据未携带的信息。
|
||||
- 剩余 FP 主要集中在 `vanchana_chora_bheethi`、`sankha`、`bhratruvriddhi`、`mridanga`、`dehasthoulya`、`bahu_puthra`、`bandhu_pujya` 等规则。
|
||||
- v6.0.36 建议优先升级验证数据结构,把 D9、tithi、Gulika/Upagraha 等上下文纳入同盘验证,避免 D1-only 规则反复在召回和准确率之间拉扯。
|
||||
|
||||
---
|
||||
|
||||
## v6.0.34(2026-06-05)—— Yoga 逻辑对齐与 F1 提升
|
||||
|
||||
> **目标**:继续 v6.0.32 的“同盘逻辑正确性”路线,优先修复验证报告中高 FP/FN 的规则,而不是只堆规则名称。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: jyotish-vedic-astrology
|
||||
version: 6.0.34
|
||||
version: 6.0.35
|
||||
description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、Shadbala、Ashtakavarga、HTML报告、深度解盘。
|
||||
---
|
||||
|
||||
@@ -10,7 +10,7 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力
|
||||
> **严格路由**:`references/strict-workflow-router.md`(⭐涉及事业/婚恋/财务/应期/技法验证时必须优先读取)
|
||||
> **覆盖矩阵**:`references/technique-capability-matrix.md`(⭐判断技法 covered/partial/missing 时必须参考)
|
||||
> **机器注册表**:`references/technique_registry.json` + `scripts/audit_capabilities.py`(⭐用于自动审计与CI门禁)
|
||||
> **版本**:v6.0.34-yoga-logic-alignment | **详细变更**:`CHANGELOG.md`
|
||||
> **版本**:v6.0.35-yoga-precision-pass | **详细变更**:`CHANGELOG.md`
|
||||
|
||||
---
|
||||
|
||||
@@ -301,9 +301,9 @@ $PYTHON $SCRIPT <子命令> [参数]
|
||||
|
||||
---
|
||||
|
||||
**版本**:v6.0.34-yoga-logic-alignment
|
||||
**版本**:v6.0.35-yoga-precision-pass
|
||||
**创建日期**:2026-04-20
|
||||
**最后更新**:2026-06-05(v6.0.34 对齐 PyJHora/B.V. Raman 多个高影响 Yoga 条件;当前 473 条 JSON 规则、379 条启用规则,D1/Rasi 逻辑验证 F1=74.13%,报告以 `references/validation_logic_report.json` 为准)
|
||||
**最后更新**:2026-06-05(v6.0.35 继续对齐 PyJHora/B.V. Raman 高影响 Yoga 条件,重点收窄 Top FP 并修复 Kahala 映射;当前 473 条 JSON 规则、379 条启用规则,D1/Rasi 逻辑验证 F1=76.08%,报告以 `references/validation_logic_report.json` 为准)
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1220
-1460
File diff suppressed because it is too large
Load Diff
+15
-52
@@ -1278,8 +1278,8 @@
|
||||
"category": "auspicious",
|
||||
"logic": {
|
||||
"type": "custom",
|
||||
"expr": "\nlord_5 = lord(5)\nlord_6 = lord(6)\nif lord_5 in ctx.planets and lord_6 in ctx.planets:\n l5h = house_of(lord_5)\n l6h = house_of(lord_6)\n (kendra(l5h) or trikona(l5h)) and (kendra(l6h) or trikona(l6h))\nelse:\n False\n",
|
||||
"combo_template": "5宫主与6宫主均在有力宫位"
|
||||
"expr": "\n# PyJHora/BVR-12: (L1 strong and L5/L6 in mutual kendras) OR\n# (L1 and L10 together in a movable sign and L9 strong).\nl1, l5, l6, l9, l10 = [lord(h) for h in [1, 5, 6, 9, 10]]\nif not all(p in ctx.planets for p in [l1, l5, l6, l9, l10]):\n False\nelse:\n l1h, l5h, l6h, l9h, l10h = [house_of(p) for p in [l1, l5, l6, l9, l10]]\n cond1 = strong(l1) and offset(l5h, l6h) in [0, 3, 6, 9] and offset(l6h, l5h) in [0, 3, 6, 9]\n cond2 = strong(l9) and same_house(l1, l10) and movable_house(l1h)\n cond1 or cond2\n",
|
||||
"combo_template": "上升主强且5/6宫主互为Kendra,或1/10宫主合于变动星座且9宫主强"
|
||||
},
|
||||
"effects": [
|
||||
"学识渊博",
|
||||
@@ -1386,8 +1386,8 @@
|
||||
"category": "auspicious",
|
||||
"logic": {
|
||||
"type": "custom",
|
||||
"expr": "\nben_in_trikona = [p for p in BENEFICS if p in ctx.planets and house_of(p) in [5, 9]]\nmal_in_dusthana = [p for p in MALEFICS if p in ctx.planets and house_of(p) in [6, 8]]\nbool(ben_in_trikona and mal_in_dusthana)\n",
|
||||
"combo_template": "吉星在三方宫+凶星在凶宫"
|
||||
"expr": "\n# PyJHora/PVR method=2: benefics only in Lagna and 9th; 5th contains\n# both benefic and malefic; 4th and 8th contain only malefics.\ncond1 = only_benefics_in_house(1) and only_benefics_in_house(9)\ncond2 = house_has_benefic(5) and house_has_malefic(5)\ncond3 = only_malefics_in_house(4) and only_malefics_in_house(8)\ncond1 and cond2 and cond3\n",
|
||||
"combo_template": "Lagna/9宫仅吉星,5宫吉凶同在,4/8宫仅凶星"
|
||||
},
|
||||
"effects": [
|
||||
"聪慧过人",
|
||||
@@ -9081,8 +9081,8 @@
|
||||
"category": "health",
|
||||
"logic": {
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora BVR-11: (a) Lagna lord in Lagna joined by dusthana lord;\n# (b) weak Lagna lord in kendra/trikona joined by a kendra/trine lord.\nasc_lord = lord(1)\ndusthana_lords = [lord(h) for h in [6, 8, 12]]\nquad_trine_lords = [lord(h) for h in [1, 4, 5, 7, 9, 10]]\nif asc_lord not in ctx.planets:\n False\nelse:\n h = house_of(asc_lord)\n condition_a = h == 1 and any(dl in ctx.planets and same_house(asc_lord, dl) for dl in dusthana_lords)\n condition_b = (kendra(h) or trikona(h)) and not strong(asc_lord) and any(qtl in ctx.planets and same_house(asc_lord, qtl) for qtl in quad_trine_lords if qtl != asc_lord)\n condition_a or condition_b\n",
|
||||
"combo_template": "上升主与凶宫主或角/三方主形成疾病格局"
|
||||
"expr": "\n# PyJHora BVR-11 exact D1-safe logic: (a) Lagna lord in Lagna joined by\n# dusthana lord; (b) weak Lagna lord joined by any kendra/trine lord.\nasc_lord = lord(1)\ndusthana_lords = [lord(h) for h in [6, 8, 12]]\nquad_trine_lords = [lord(h) for h in [1, 4, 5, 7, 9, 10]]\nif asc_lord not in ctx.planets:\n False\nelse:\n condition_a = house_of(asc_lord) == 1 and any(dl in ctx.planets and same_house(asc_lord, dl) for dl in dusthana_lords)\n condition_b = (not strong(asc_lord)) and any(qtl in ctx.planets and same_house(asc_lord, qtl) for qtl in quad_trine_lords)\n condition_a or condition_b\n",
|
||||
"combo_template": "上升主在Lagna合凶宫主,或弱上升主合角/三方主"
|
||||
},
|
||||
"effects": [
|
||||
"疾病",
|
||||
@@ -11236,14 +11236,9 @@
|
||||
"bvr_id": null,
|
||||
"category": "putra",
|
||||
"logic": {
|
||||
"type": "compound_conditions",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "5th_lord_afflicted_by_saturn_or_rahu",
|
||||
"note": "5th lord afflicted by Saturn or Rahu"
|
||||
}
|
||||
],
|
||||
"note": "Loss of children at specific times"
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora 229/230 D1-safe logic. Variant 229: Rahu in 5th, L5 joined\n# malefic, Jupiter debilitated. Variant 230: malefics occupy/aspect both\n# 5th from Lagna and 5th from Jupiter.\nl5 = lord(5)\nif l5 not in ctx.planets or 'Jupiter' not in ctx.planets:\n False\nelse:\n cond229 = house_of('Rahu') == 5 and debil('Jupiter') and any(m in ctx.planets and same_house(l5, m) for m in MALEFICS if m != l5)\n j5 = ((house_of('Jupiter') - 1 + 4) % 12) + 1\n mal_lagna5 = any(m in ctx.planets and (house_of(m) == 5 or aspects_house(m, 5)) for m in MALEFICS)\n mal_jupiter5 = any(m in ctx.planets and (house_of(m) == j5 or aspects_house(m, j5)) for m in MALEFICS)\n cond229 or (mal_lagna5 and mal_jupiter5)\n",
|
||||
"combo_template": "Rahu/L5/木星或凶星影响Lagna与木星起算第5宫"
|
||||
},
|
||||
"effects": [
|
||||
"Loss of progeny at predetermined periods"
|
||||
@@ -11631,32 +11626,9 @@
|
||||
"bvr_id": null,
|
||||
"category": "special",
|
||||
"logic": {
|
||||
"type": "compound_conditions",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "compound",
|
||||
"operator": "OR",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "jupiter_in_lagna_mars_in_7th",
|
||||
"note": "Jupiter in Lagna and Mars in 7th"
|
||||
},
|
||||
{
|
||||
"type": "saturn_in_lagna_mars_in_5_7_9",
|
||||
"note": "Saturn in Lagna and Mars in 9th/5th/7th"
|
||||
},
|
||||
{
|
||||
"type": "saturn_in_12th_with_waning_moon",
|
||||
"note": "Saturn in 12th with waning Moon"
|
||||
},
|
||||
{
|
||||
"type": "moon_mercury_in_kendra_with_planet",
|
||||
"note": "Moon and Mercury in kendra with another planet"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"note": ""
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora 291/292/294 D1-safe variants. Variant 293 needs tithi/waning Moon\n# and remains unavailable from static planet_positions_60 data.\njm = 'Jupiter' in ctx.planets and 'Mars' in ctx.planets and house_of('Jupiter') == 1 and house_of('Mars') == 7\nsm = 'Saturn' in ctx.planets and 'Mars' in ctx.planets and house_of('Saturn') == 1 and house_of('Mars') in [5, 7, 9]\nmoon_mercury = False\nif 'Moon' in ctx.planets and 'Mercury' in ctx.planets:\n moon_mercury = kendra(house_of('Moon')) and kendra(house_of('Mercury')) and any(p != 'Moon' and aspect(p, 'Moon') for p in ctx.planets) and any(p != 'Mercury' and aspect(p, 'Mercury') for p in ctx.planets)\njm or sm or moon_mercury\n",
|
||||
"combo_template": "木火1/7、土升火5/7/9,或月水角宫并受相位"
|
||||
},
|
||||
"effects": [
|
||||
"Mental disturbance, confusion, erratic behavior"
|
||||
@@ -13633,18 +13605,9 @@
|
||||
"bvr_id": null,
|
||||
"category": "raja",
|
||||
"logic": {
|
||||
"type": "compound_conditions",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "planets_in_mutual_kendras_or_conjunction",
|
||||
"planets": [
|
||||
"Jupiter",
|
||||
"Mars"
|
||||
],
|
||||
"note": "Jupiter and Mars in mutual kendras or in conjunction"
|
||||
}
|
||||
],
|
||||
"note": "Jupiter and Mars in mutual kendras or conjunction"
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora: Jupiter and Mars are together or in the 7th from each other.\n'Jupiter' in ctx.planets and 'Mars' in ctx.planets and offset(house_of('Jupiter'), house_of('Mars')) in [0, 6]\n",
|
||||
"combo_template": "木星与火星同宫或互为7宫"
|
||||
},
|
||||
"effects": [
|
||||
"Courage, wisdom, leadership, military success"
|
||||
|
||||
@@ -96,7 +96,7 @@ PYJHORA_VARIANTS = {
|
||||
# Kedara
|
||||
'kedara_yoga': 'bvr_kedaara_yoga',
|
||||
# Kaahala/Kahala
|
||||
'kaahala_yoga': 'bvr_kahala_yoga',
|
||||
'kaahala_yoga': 'kahala_yoga',
|
||||
# Direct mappings for common yogas
|
||||
'vosi_yoga': 'bvr_vosi_precise',
|
||||
'sunaphaa_yoga': 'bvr_sunaphaa_precise',
|
||||
|
||||
@@ -44,6 +44,7 @@ PLANET_CN = {
|
||||
}
|
||||
BENEFICS = ['Jupiter', 'Venus', 'Mercury', 'Moon']
|
||||
MALEFICS = ['Mars', 'Saturn', 'Sun', 'Rahu', 'Ketu']
|
||||
MOVABLE_SIGNS = ['Aries', 'Cancer', 'Libra', 'Capricorn']
|
||||
ALL_PLANETS = ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']
|
||||
|
||||
|
||||
@@ -921,6 +922,31 @@ class YogaEngine:
|
||||
# PyJHora temporary friends: 2/3/4/10/11/12 from a planet.
|
||||
return offset(ctx.house_of(a), ctx.house_of(b)) in [1, 2, 3, 9, 10, 11]
|
||||
|
||||
def occupants(h):
|
||||
return ctx.planets_in_house(h) if h is not None else []
|
||||
|
||||
def only_benefics_in_house(h):
|
||||
ps = occupants(h)
|
||||
return bool(ps) and all(p in BENEFICS for p in ps)
|
||||
|
||||
def only_malefics_in_house(h):
|
||||
ps = occupants(h)
|
||||
return bool(ps) and all(p in MALEFICS for p in ps)
|
||||
|
||||
def house_has_benefic(h):
|
||||
return any(p in BENEFICS for p in occupants(h))
|
||||
|
||||
def house_has_malefic(h):
|
||||
return any(p in MALEFICS for p in occupants(h))
|
||||
|
||||
def house_sign(h):
|
||||
if h is None:
|
||||
return None
|
||||
return SIGNS[(ctx.asc_idx + h - 1) % 12]
|
||||
|
||||
def movable_house(h):
|
||||
return house_sign(h) in MOVABLE_SIGNS
|
||||
|
||||
def exal(p): return ctx.is_exalted(p)
|
||||
def lord_of_house(h): return ctx.lord_of_house(h)
|
||||
def sign(p): return ctx.sign_of(p)
|
||||
@@ -955,6 +981,7 @@ class YogaEngine:
|
||||
"SIGNS": SIGNS, "SIGN_LORDS": SIGN_LORDS,
|
||||
"EXALTATION": EXALTATION, "DEBILITATION": DEBILITATION,
|
||||
"PLANET_CN": PLANET_CN, "BENEFICS": BENEFICS, "MALEFICS": MALEFICS,
|
||||
"MOVABLE_SIGNS": MOVABLE_SIGNS,
|
||||
"ALL_PLANETS": ALL_PLANETS, "MOOLATRIKONA_SIGN": MOOLATRIKONA_SIGN,
|
||||
# 基础查询
|
||||
"house_of": house_of, "sign_of": sign_of, "deg_of": deg_of,
|
||||
@@ -977,6 +1004,10 @@ class YogaEngine:
|
||||
# v6.0.32: 同宫与相位检查(custom规则常用)
|
||||
"same_house": same_house, "aspect": aspect, "aspects_house": aspects_house,
|
||||
"strong": strong, "associated": associated, "temporal_friend": temporal_friend,
|
||||
"occupants": occupants, "only_benefics_in_house": only_benefics_in_house,
|
||||
"only_malefics_in_house": only_malefics_in_house,
|
||||
"house_has_benefic": house_has_benefic, "house_has_malefic": house_has_malefic,
|
||||
"house_sign": house_sign, "movable_house": movable_house,
|
||||
"exal": exal, "lord_of_house": lord_of_house, "sign": sign,
|
||||
"check_amala_from": check_amala_from,
|
||||
"Benefics": BENEFICS, "Malefics": MALEFICS,
|
||||
|
||||
Reference in New Issue
Block a user