wangyunpeng 3 дней назад
Родитель
Сommit
27e1c57022

+ 24 - 7
examples/auto_put_ad_mini/roi_control/fission_multiplier.py

@@ -241,9 +241,12 @@ class FissionMultiplierParameters:
         if entity_type == "qiwei":
         if entity_type == "qiwei":
             partner_key = normalize_name(partner)
             partner_key = normalize_name(partner)
             if partner_key and partner_key in self.qiwei_by_partner:
             if partner_key and partner_key in self.qiwei_by_partner:
-                return FissionMultiplierMatch(
+                return self._match_result(
                     self.qiwei_by_partner[partner_key],
                     self.qiwei_by_partner[partner_key],
+                    "qiwei",
                     MATCH_QIWEI_PARTNER,
                     MATCH_QIWEI_PARTNER,
+                    partner_key,
+                    "",
                     f"企微合作方精确:{partner_key}",
                     f"企微合作方精确:{partner_key}",
                 )
                 )
             return FissionMultiplierMatch(
             return FissionMultiplierMatch(
@@ -272,12 +275,12 @@ def parameter_values(
         multiplier: float,
         multiplier: float,
     ) -> None:
     ) -> None:
         row = {
         row = {
-                "entity_type": entity_type,
-                "match_level": match_level,
-                "key_primary": key_primary,
-                "key_secondary": key_secondary,
-                "multiplier": float(multiplier),
-            }
+            "entity_type": entity_type,
+            "match_level": match_level,
+            "key_primary": key_primary,
+            "key_secondary": key_secondary,
+            "multiplier": float(multiplier),
+        }
         if parameters.release.includes_total_to_first:
         if parameters.release.includes_total_to_first:
             key = (entity_type, match_level, key_primary, key_secondary)
             key = (entity_type, match_level, key_primary, key_secondary)
             multiplier_vs_first = parameters.total_to_first.get(key)
             multiplier_vs_first = parameters.total_to_first.get(key)
@@ -622,6 +625,8 @@ def load_fission_multiplier_parameters(
         SOURCE_MULTIPLIER_COLUMN,
         SOURCE_MULTIPLIER_COLUMN,
         "样本状态",
         "样本状态",
     }
     }
+    if release.includes_total_to_first:
+        exact_required.add(SOURCE_TOTAL_TO_FIRST_COLUMN)
     miniapp = _read_parameter_file(
     miniapp = _read_parameter_file(
         directory / MINIAPP_FILE,
         directory / MINIAPP_FILE,
         required=exact_required | {"人群包", "转化目标"},
         required=exact_required | {"人群包", "转化目标"},
@@ -803,6 +808,18 @@ def load_fission_multiplier_parameters(
                 SOURCE_TOTAL_TO_FIRST_COLUMN,
                 SOURCE_TOTAL_TO_FIRST_COLUMN,
             )
             )
         )
         )
+        if qiwei is not None:
+            add_total_to_first(
+                "qiwei",
+                MATCH_QIWEI_PARTNER,
+                _mapping(
+                    qiwei,
+                    ["合作方"],
+                    normalizers=[normalize_name],
+                    label="企微合作方参数",
+                    value_column=SOURCE_TOTAL_TO_FIRST_COLUMN,
+                ),
+            )
 
 
     return FissionMultiplierParameters(
     return FissionMultiplierParameters(
         release=release,
         release=release,

+ 5 - 0
examples/auto_put_ad_mini/test_roi_control_metrics.py

@@ -13,6 +13,7 @@ from roi_control.metrics import (
 )
 )
 from roi_control.fission_multiplier import (
 from roi_control.fission_multiplier import (
     DISPLAY_TOTAL_TO_FIRST_COLUMN,
     DISPLAY_TOTAL_TO_FIRST_COLUMN,
+    MATCH_QIWEI_PARTNER,
     QIWEI_REFERENCE_RUN_SUFFIX,
     QIWEI_REFERENCE_RUN_SUFFIX,
     QIWEI_REFERENCE_VERSION,
     QIWEI_REFERENCE_VERSION,
     load_fission_multiplier_parameters,
     load_fission_multiplier_parameters,
@@ -87,6 +88,10 @@ class RoiRulesTest(unittest.TestCase):
         formal = replace(
         formal = replace(
             FISSION_PARAMETERS,
             FISSION_PARAMETERS,
             qiwei_by_partner={"合作方": 2.0},
             qiwei_by_partner={"合作方": 2.0},
+            total_to_first={
+                **FISSION_PARAMETERS.total_to_first,
+                ("qiwei", MATCH_QIWEI_PARTNER, "合作方", ""): 0.75,
+            },
             qiwei_exact_rows=1,
             qiwei_exact_rows=1,
             qiwei_exact_available_rows=1,
             qiwei_exact_available_rows=1,
         )
         )

+ 24 - 1
examples/auto_put_ad_mini/test_roi_fission_multiplier.py

@@ -17,6 +17,7 @@ from roi_control.fission_multiplier import (
     DISPLAY_TOTAL_TO_FIRST_COLUMN,
     DISPLAY_TOTAL_TO_FIRST_COLUMN,
     FALLBACK_FILE,
     FALLBACK_FILE,
     GZH_FILE,
     GZH_FILE,
+    LEGACY_FISSION_PARAMETER_VERSION,
     MATCH_GZH_EXACT,
     MATCH_GZH_EXACT,
     MATCH_GZH_PARTNER,
     MATCH_GZH_PARTNER,
     MATCH_MINIAPP_EXACT,
     MATCH_MINIAPP_EXACT,
@@ -30,6 +31,7 @@ from roi_control.fission_multiplier import (
     QIWEI_REFERENCE_MULTIPLIER,
     QIWEI_REFERENCE_MULTIPLIER,
     QIWEI_REFERENCE_VERSION,
     QIWEI_REFERENCE_VERSION,
     RELEASES,
     RELEASES,
+    SOURCE_TOTAL_TO_FIRST_COLUMN,
     apply_fission_multiplier,
     apply_fission_multiplier,
     load_fission_multiplier_parameters,
     load_fission_multiplier_parameters,
     parameter_content_sha256,
     parameter_content_sha256,
@@ -72,6 +74,11 @@ class RoiFissionMultiplierTest(unittest.TestCase):
         )
         )
         self.assertEqual(
         self.assertEqual(
             parameter_content_sha256(self.parameters),
             parameter_content_sha256(self.parameters),
+            "af62237a0f6ee8de75ad90f9be82b0c880a783ee5a8ecb3e42c27b777e6dd213",
+        )
+        legacy = load_fission_multiplier_parameters(LEGACY_FISSION_PARAMETER_VERSION)
+        self.assertEqual(
+            parameter_content_sha256(legacy),
             "c447dc53fb560a9ca7dd954b27966ec46bb4e25e1dfd6916d607431c106242c6",
             "c447dc53fb560a9ca7dd954b27966ec46bb4e25e1dfd6916d607431c106242c6",
         )
         )
 
 
@@ -171,6 +178,10 @@ class RoiFissionMultiplierTest(unittest.TestCase):
         formal = replace(
         formal = replace(
             self.parameters,
             self.parameters,
             qiwei_by_partner={"合作方A": 2.2},
             qiwei_by_partner={"合作方A": 2.2},
+            total_to_first={
+                **self.parameters.total_to_first,
+                ("qiwei", MATCH_QIWEI_PARTNER, "合作方A", ""): 0.75,
+            },
             qiwei_exact_rows=2,
             qiwei_exact_rows=2,
             qiwei_exact_available_rows=1,
             qiwei_exact_available_rows=1,
         )
         )
@@ -179,6 +190,7 @@ class RoiFissionMultiplierTest(unittest.TestCase):
         fallback = formal.match("qiwei", partner="未知合作方")
         fallback = formal.match("qiwei", partner="未知合作方")
         self.assertEqual(exact.match_level, MATCH_QIWEI_PARTNER)
         self.assertEqual(exact.match_level, MATCH_QIWEI_PARTNER)
         self.assertEqual(exact.multiplier, 2.2)
         self.assertEqual(exact.multiplier, 2.2)
+        self.assertEqual(exact.multiplier_vs_first, 0.75)
         self.assertEqual(fallback.match_level, MATCH_QIWEI_REFERENCE)
         self.assertEqual(fallback.match_level, MATCH_QIWEI_REFERENCE)
         self.assertEqual(fallback.multiplier, QIWEI_REFERENCE_MULTIPLIER)
         self.assertEqual(fallback.multiplier, QIWEI_REFERENCE_MULTIPLIER)
 
 
@@ -186,6 +198,10 @@ class RoiFissionMultiplierTest(unittest.TestCase):
         formal = replace(
         formal = replace(
             self.parameters,
             self.parameters,
             qiwei_by_partner={"合作方A": 2.2},
             qiwei_by_partner={"合作方A": 2.2},
+            total_to_first={
+                **self.parameters.total_to_first,
+                ("qiwei", MATCH_QIWEI_PARTNER, "合作方A", ""): 0.75,
+            },
             qiwei_exact_rows=2,
             qiwei_exact_rows=2,
             qiwei_exact_available_rows=1,
             qiwei_exact_available_rows=1,
         )
         )
@@ -223,6 +239,10 @@ class RoiFissionMultiplierTest(unittest.TestCase):
         formal = replace(
         formal = replace(
             self.parameters,
             self.parameters,
             qiwei_by_partner={"合作方A": 2.2},
             qiwei_by_partner={"合作方A": 2.2},
+            total_to_first={
+                **self.parameters.total_to_first,
+                ("qiwei", MATCH_QIWEI_PARTNER, "合作方A", ""): 0.75,
+            },
             qiwei_exact_rows=2,
             qiwei_exact_rows=2,
             qiwei_exact_available_rows=1,
             qiwei_exact_available_rows=1,
         )
         )
@@ -255,7 +275,7 @@ class RoiFissionMultiplierTest(unittest.TestCase):
             / "roi_control"
             / "roi_control"
             / "data"
             / "data"
             / "fission_multiplier"
             / "fission_multiplier"
-            / DEFAULT_FISSION_PARAMETER_VERSION
+            / self.parameters.release.source_version
         )
         )
         with tempfile.TemporaryDirectory() as temporary:
         with tempfile.TemporaryDirectory() as temporary:
             parameter_root = Path(temporary)
             parameter_root = Path(temporary)
@@ -273,6 +293,7 @@ class RoiFissionMultiplierTest(unittest.TestCase):
                         "首层UV": 600,
                         "首层UV": 600,
                         "A0活跃裂变UV": 200,
                         "A0活跃裂变UV": 200,
                         "A0-A15累计裂变活跃人次": 400,
                         "A0-A15累计裂变活跃人次": 400,
+                        SOURCE_TOTAL_TO_FIRST_COLUMN: 400 / 600,
                         "T1-T15相对T0尾部系数": 1.0,
                         "T1-T15相对T0尾部系数": 1.0,
                         "T15成熟系数(相对T0)": 2.0,
                         "T15成熟系数(相对T0)": 2.0,
                         "样本状态": "可用",
                         "样本状态": "可用",
@@ -293,6 +314,8 @@ class RoiFissionMultiplierTest(unittest.TestCase):
                     name: sha256(target / name)
                     name: sha256(target / name)
                     for name in (MINIAPP_FILE, GZH_FILE, QIWEI_FILE, FALLBACK_FILE)
                     for name in (MINIAPP_FILE, GZH_FILE, QIWEI_FILE, FALLBACK_FILE)
                 },
                 },
+                source_version=version,
+                includes_total_to_first=True,
             )
             )
             with patch.dict(RELEASES, {version: release}):
             with patch.dict(RELEASES, {version: release}):
                 parameters = load_fission_multiplier_parameters(
                 parameters = load_fission_multiplier_parameters(