Просмотр исходного кода

feat(roi-control): apply qiwei reference multiplier

刘立冬 4 дней назад
Родитель
Сommit
552a7033aa

+ 1 - 1
examples/auto_put_ad_mini/docs/roi/T15成熟系数迁移指南.md

@@ -352,7 +352,7 @@ HORIZON = 15
 5. **转化目标接入**:当前日常ROI旧流程尚未加载“人群包+转化目标”新参数,迁移工程必须确认日常数据是否包含转化目标。
 6. **收入边界**:接入前必须再次确认“首层实际效率收入”不包含准备单独放大的T0裂变收入,避免收入重复。
 7. **公众号新账号**:首层UV不超过500的公众号不会进入精确参数查询;应使用合作方或渠道回退。
-8. **企微渠道**:企微T0裂变口径仍待复核,本次迁移不包含企微成熟系数
+8. **企微渠道**:企微T0裂变口径仍待复核,本次迁移不包含企微正式传播裂变系数;日级ROI临时统一使用参考系数2.5,且不进入阈值和调控
 9. **源表稳定性**:`opengid_base_data`与`user_share_log`生产逻辑变更时,需要重新做字段血缘和归因覆盖验证。
 
 ## 12. 回滚方案

+ 2 - 2
examples/auto_put_ad_mini/docs/unified_services_deployment.md

@@ -155,8 +155,8 @@ docker compose --env-file /dev/null run --rm \
 
 日级 ROI 单独分两阶段启用:
 
-当前 `north_star_roi_t15_v3` 使用版本化传播裂变参数,报表版本为 `roi_report_v4`。小程序按人群包和转化目标、
-公众号按合作方和公众号匹配传播裂变系数;企微口径未确认,当前按渠道/合作方使用临时参考系数 1.0 保留展示,但不进入阈值和调控。T0 收入是实际值,
+当前 `north_star_roi_t15_v4` 使用版本化传播裂变参数,报表版本为 `roi_report_v4`。小程序按人群包和转化目标、
+公众号按合作方和公众号匹配传播裂变系数;企微口径未确认,当前按渠道/合作方统一使用临时参考系数 2.5 保留展示,但不进入阈值和调控。T0 收入是实际值,
 只预测 T1-T15 增量。日级任务不会现场重算 cohort 参数。部署前应保持
 `ROI_FISSION_PARAMETER_VERSION=20260712_A0-A15_v1`。参数必须先发布到 MySQL,
 启动日志、数据库发布版本和 Excel 摘要中的参数版本、cohort 日期必须一致。

+ 11 - 4
examples/auto_put_ad_mini/roi_control/fission_multiplier.py

@@ -35,6 +35,7 @@ MATCH_GZH_EXACT = "gzh_partner_account_exact"
 MATCH_GZH_PARTNER = "gzh_partner_fallback"
 MATCH_GZH_CHANNEL = "gzh_channel_fallback"
 MATCH_QIWEI_REFERENCE = "qiwei_channel_reference_pending"
+QIWEI_REFERENCE_MULTIPLIER = 2.5
 
 
 @dataclass(frozen=True)
@@ -158,9 +159,10 @@ class FissionMultiplierParameters:
 
         if entity_type == "qiwei":
             return FissionMultiplierMatch(
-                1.0,
+                QIWEI_REFERENCE_MULTIPLIER,
                 MATCH_QIWEI_REFERENCE,
-                f"企微渠道临时参考系数1.0_待补算:{normalize_name(partner)}",
+                f"企微渠道临时参考系数{QIWEI_REFERENCE_MULTIPLIER:g}_待补算:"
+                f"{normalize_name(partner)}",
             )
 
         raise ValueError(f"不支持的ROI实体类型: {entity_type}")
@@ -571,11 +573,16 @@ def apply_fission_multiplier(
     result["传播裂变参数cohort日期"] = parameters.release.cohort_date
     qiwei = result["entity_type"].eq("qiwei")
     result["传播裂变参数状态"] = "正式参数"
-    result.loc[qiwei, "传播裂变参数状态"] = "临时参考系数1.0_待分渠道补算"
+    result.loc[qiwei, "传播裂变参数状态"] = (
+        f"临时参考系数{QIWEI_REFERENCE_MULTIPLIER:g}_待分渠道补算"
+    )
     result["调控参与状态"] = "参与阈值和调控"
     result.loc[qiwei, "调控参与状态"] = "仅展示_不进入阈值和调控"
     result["ROI计算口径"] = (
         "首层实际效率收入+T0实际裂变收入+预测T1-T15裂变收入"
     )
-    result.loc[qiwei, "ROI计算口径"] = "仅使用实际T0_传播裂变系数临时取1"
+    result.loc[qiwei, "ROI计算口径"] = (
+        "首层实际效率收入+T0实际裂变收入+预测T1-T15裂变收入_"
+        f"传播裂变系数临时取{QIWEI_REFERENCE_MULTIPLIER:g}"
+    )
     return result

+ 2 - 2
examples/auto_put_ad_mini/roi_control/metrics.py

@@ -18,8 +18,8 @@ from .fission_multiplier import (
 )
 
 
-METRIC_VERSION = "north_star_roi_t15_v3"
-METRIC_RUN_SUFFIX = "m3"
+METRIC_VERSION = "north_star_roi_t15_v4"
+METRIC_RUN_SUFFIX = "m4"
 
 SELF_CHANNEL = "小程序投流-稳定"
 GZH_CHANNEL = "公众号合作-即转-稳定"

+ 1 - 1
examples/auto_put_ad_mini/roi_control/reporting.py

@@ -242,7 +242,7 @@ def _write_summary(
         ),
         (
             "企微口径",
-            "企微按渠道/合作方保留展示,临时参考系数为1.0,待补算正式参数;不进入阈值样本池和调控。",
+            "企微按渠道/合作方保留展示,临时参考系数为2.5,待补算正式参数;不进入阈值样本池和调控。",
         ),
         ("阈值口径", "小程序和公众号合格实体进入同一全局池:三日聚合ROI的P10=关停线、P80=扩量线;企微不参与"),
         (

+ 2 - 0
examples/auto_put_ad_mini/roi_control/service.py

@@ -24,6 +24,7 @@ from .metrics import ENTITY_QIWEI, METRIC_RUN_SUFFIX, METRIC_VERSION
 from .fission_multiplier import (
     DEFAULT_FISSION_PARAMETER_VERSION,
     FissionMultiplierParameters,
+    QIWEI_REFERENCE_MULTIPLIER,
     parameters_from_database,
 )
 from .policy import annotate_execution
@@ -106,6 +107,7 @@ def run_daily_roi(
     )
     run_config = config.snapshot()
     run_config["fission_multiplier"] = fission_parameters.snapshot()
+    run_config["qiwei_reference_multiplier"] = QIWEI_REFERENCE_MULTIPLIER
     run_config["report_version"] = REPORT_VERSION
     client = ODPSClient(project=os.getenv("ODPS_PROJECT", "loghubods"))
     end_date = resolve_end_date(client, requested_end_date)

+ 35 - 1
examples/auto_put_ad_mini/test_roi_fission_multiplier.py

@@ -15,6 +15,7 @@ from roi_control.fission_multiplier import (
     MATCH_MINIAPP_GOAL,
     MATCH_MINIAPP_PACKAGE,
     MATCH_QIWEI_REFERENCE,
+    QIWEI_REFERENCE_MULTIPLIER,
     load_fission_multiplier_parameters,
     parameter_content_sha256,
     parameter_values,
@@ -87,9 +88,42 @@ class RoiFissionMultiplierTest(unittest.TestCase):
     def test_qiwei_uses_reference_multiplier_without_control_semantics(self):
         match = self.parameters.match("qiwei", partner="企微合作方")
         self.assertEqual(match.match_level, MATCH_QIWEI_REFERENCE)
-        self.assertEqual(match.multiplier, 1.0)
+        self.assertEqual(match.multiplier, QIWEI_REFERENCE_MULTIPLIER)
         self.assertIn("待补算", match.source)
 
+    def test_qiwei_roi_uses_reference_multiplier(self):
+        frame = pd.DataFrame(
+            [
+                {
+                    "dt": "20260727",
+                    "entity_type": "qiwei",
+                    "channel": "群/企微合作-稳定",
+                    "代理名称": "",
+                    "账号id": "",
+                    "账号名称": "",
+                    "广告id": "",
+                    "广告名称": "",
+                    "包名": "",
+                    "广告优化目标": "",
+                    "创意id": "",
+                    "合作方名": "企微合作方",
+                    "公众号名": "",
+                    "首层UV": 100,
+                    "T0裂变数": 20,
+                    "成本": 100,
+                    "效率收入": 50,
+                    "多层裂变收入": 30,
+                }
+            ]
+        )
+        result = prepare_daily_metrics(frame, self.parameters).iloc[0]
+        self.assertAlmostEqual(
+            result["预测全链路效率收入"],
+            50 + 30 * QIWEI_REFERENCE_MULTIPLIER,
+        )
+        self.assertAlmostEqual(result["ROI"], 1.25)
+        self.assertEqual(result["调控参与状态"], "仅展示_不进入阈值和调控")
+
     def test_database_parameter_round_trip_preserves_release(self):
         metadata = self.parameters.snapshot()
         metadata["file_sha256"] = dict(self.parameters.release.file_sha256)