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

use long-retention play and share sources

刘立冬 13 часов назад
Родитель
Сommit
4c96e27635

+ 4 - 1
README.md

@@ -62,7 +62,10 @@ python3 scripts/run_impact_report.py \
 DataWorks ODPS SQL节点,并配置`mid`、`anchor_dt`、`window_start_dt`、
 `window_end_dt`四个节点参数。SQL合并全部6类基础行为特征,最终输出一名用户一行。
 180天是请求窗口,实际覆盖还受源表分区保留期限制;交付或解释结果时应先检查
-`video_play_log`和`video_action_log_applet`的最早可用分区。
+`ods_video_play_log_day`、`user_share_log`、`video_action_log_applet`和
+`simpleevent_log`的最早可用分区。有效播放使用`ods_video_play_log_day`的
+`videoRealPlay`,分享使用`user_share_log.topic='share'`。
+2026-08-14的完整检查结果保存在`fixtures/source_table_retention_20260814.csv`。
 
 ## 口径边界
 

+ 8 - 0
fixtures/source_table_retention_20260814.csv

@@ -0,0 +1,8 @@
+表名,当前最早分区,当前最晚分区,请求窗口天数,窗口内可用天数,窗口内缺失天数,窗口覆盖率,主要影响指标
+loghubods.useractive_log,20250327,20260813,180,180,0,100.00%,活跃天数、来源群、返回前台
+loghubods.ods_video_play_log_day,20240624,20260813,180,180,0,100.00%,有效播放次数
+loghubods.video_action_log_applet,20260416,20260814,180,116,64,64.44%,设备机型、地域、部分风险事件排除条件
+loghubods.user_share_log,20190629,20260813,180,180,0,100.00%,分享次数、卡片点击、来源场景、shareid回流
+loghubods.ad_own_open_conv,20250814,20260813,180,180,0,100.00%,长按扫码转化
+loghubods.ad_action_log_own,20250814,20260813,180,180,0,100.00%,广告点击、曝光、关闭、落地页行为
+loghubods.simpleevent_log,20260615,20260813,180,56,124,31.11%,广告播放中截图、切后台返回、pageView/videoClick排除条件

+ 11 - 10
sql/dataworks_single_user_180d_all_in_one.sql

@@ -4,9 +4,11 @@
 -- window_start_dt=20260211
 -- window_end_dt=20260809
 -- 窗口为锚点前180个自然日,不包含锚点当天。
--- 注意:各指标还受源表实际分区保留期限制。2026-08-14检查时,
--- video_play_log最早分区为20260715,video_action_log_applet最早分区为20260416;
--- 如果window_start_dt早于源表最早分区,有效播放和分享只能统计现存分区。
+-- 注意:各指标还受源表实际分区保留期限制。2026-08-14检查时:
+-- ods_video_play_log_day和user_share_log可完整覆盖示例180天窗口;
+-- video_action_log_applet最早分区为20260416,设备/地域及部分风险排除条件覆盖116天;
+-- simpleevent_log最早分区为20260615,截图及切后台相关指标只能覆盖56天。
+-- 其余本SQL使用的表可完整覆盖示例180天窗口,详见fixtures下的分区快照。
 
 WITH input_user AS (
   SELECT
@@ -32,20 +34,19 @@ active_metrics AS (
 real_play_metrics AS (
   SELECT i.mid, COUNT(p.mid) AS real_play_cnt
   FROM input_user i
-  LEFT JOIN loghubods.video_play_log p
+  LEFT JOIN loghubods.ods_video_play_log_day p
     ON p.mid = i.mid
    AND p.dt BETWEEN '${window_start_dt}' AND '${window_end_dt}'
    AND p.businesstype = 'videoRealPlay'
   GROUP BY i.mid
 ),
 share_metrics AS (
-  SELECT i.mid, COUNT(v.mid) AS video_share_cnt
+  SELECT i.mid, COUNT(s.machinecode) AS video_share_cnt
   FROM input_user i
-  LEFT JOIN loghubods.video_action_log_applet v
-    ON v.mid = i.mid
-   AND v.dt BETWEEN '${window_start_dt}' AND '${window_end_dt}'
-   AND v.business = 'videoShareFriend'
-   AND v.businesstype = 'videoShareFriend'
+  LEFT JOIN loghubods.user_share_log s
+    ON s.machinecode = i.mid
+   AND s.dt BETWEEN '${window_start_dt}' AND '${window_end_dt}'
+   AND s.topic = 'share'
   GROUP BY i.mid
 ),
 click_events AS (

+ 7 - 8
src/feature_sql.py

@@ -49,7 +49,7 @@ active_metrics AS (
 real_play_metrics AS (
   SELECT i.mid, COUNT(p.mid) AS real_play_cnt
   FROM input_users i
-  LEFT JOIN loghubods.video_play_log p
+  LEFT JOIN loghubods.ods_video_play_log_day p
     ON p.mid = i.mid
    AND p.dt BETWEEN '{global_start}' AND '{global_end}'
    AND p.dt BETWEEN i.window_start_dt AND i.window_end_dt
@@ -57,14 +57,13 @@ real_play_metrics AS (
   GROUP BY i.mid
 ),
 share_metrics AS (
-  SELECT i.mid, COUNT(v.mid) AS video_share_cnt
+  SELECT i.mid, COUNT(s.machinecode) AS video_share_cnt
   FROM input_users i
-  LEFT JOIN loghubods.video_action_log_applet v
-    ON v.mid = i.mid
-   AND v.dt BETWEEN '{global_start}' AND '{global_end}'
-   AND v.dt BETWEEN i.window_start_dt AND i.window_end_dt
-   AND v.business = 'videoShareFriend'
-   AND v.businesstype = 'videoShareFriend'
+  LEFT JOIN loghubods.user_share_log s
+    ON s.machinecode = i.mid
+   AND s.dt BETWEEN '{global_start}' AND '{global_end}'
+   AND s.dt BETWEEN i.window_start_dt AND i.window_end_dt
+   AND s.topic = 'share'
   GROUP BY i.mid
 ),
 click_events AS (

+ 10 - 0
tests/test_offline_regression.py

@@ -42,6 +42,16 @@ class OfflineRegressionTest(unittest.TestCase):
         suspected = sum(value for (group, _), value in counts.items() if group == "疑似举报人")
         self.assertEqual(suspected, 100)
 
+    def test_long_retention_play_and_share_sources(self) -> None:
+        builder = (PROJECT_DIR / "src" / "feature_sql.py").read_text(encoding="utf-8")
+        dataworks = (
+            PROJECT_DIR / "sql" / "dataworks_single_user_180d_all_in_one.sql"
+        ).read_text(encoding="utf-8")
+        for sql in (builder, dataworks):
+            self.assertIn("loghubods.ods_video_play_log_day", sql)
+            self.assertIn("s.topic = 'share'", sql)
+            self.assertNotIn("LEFT JOIN loghubods.video_play_log p", sql)
+
     def test_social_aggregation_matches_saved_result(self) -> None:
         relationships = aggregate_relationships(self.users, self.relationships)
         groups = aggregate_groups(self.users, self.groups)