فهرست منبع

add ad abtest: 173-t

liqian 1 سال پیش
والد
کامیت
8bba60452b
2فایلهای تغییر یافته به همراه151 افزوده شده و 78 حذف شده
  1. 94 42
      ad_recommend.py
  2. 57 36
      config.py

+ 94 - 42
ad_recommend.py

@@ -1,3 +1,4 @@
+import json
 import traceback
 import datetime
 from utils import RedisHelper
@@ -70,13 +71,66 @@ def get_threshold(abtest_id, abtest_config_tag, ab_test_code, mid_group, care_mo
     return threshold
 
 
-def predict_mid_video_res(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status):
+def predict_with_rate_process(now_date, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status, mid_group):
     now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
     user_data_key = abtest_param['user'].get('data')
     user_rule_key = abtest_param['user'].get('rule')
     video_data_key = abtest_param['video'].get('data')
+    # 获取用户组分享率
+    group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{now_dt}"
+    if not redis_helper.key_exists(group_share_rate_key):
+        redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
+        group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{redis_dt}"
+    group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)
+    # 获取视频分享率
+    video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}"
+    if not redis_helper.key_exists(video_share_rate_key):
+        redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
+        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{redis_dt}"
+    video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
+    if video_share_rate is None:
+        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)
+
+    # 计算 mid-video 分享率
+    if group_share_rate is None or video_share_rate is None:
+        return None
+    mid_video_predict_res = float(group_share_rate) * float(video_share_rate)
+
+    # 获取对应的阈值
+    threshold = get_threshold(
+        abtest_id=abtest_id,
+        abtest_config_tag=abtest_config_tag,
+        ab_test_code=ab_test_code,
+        mid_group=mid_group,
+        care_model_status=care_model_status,
+        abtest_param=abtest_param
+    )
+    # 阈值判断
+    if mid_video_predict_res > threshold:
+        # 大于阈值,出广告
+        ad_predict = 2
+    else:
+        # 否则,不出广告
+        ad_predict = 1
+    result = {
+        'mid_group': mid_group,
+        'group_share_rate': group_share_rate,
+        'video_share_rate': video_share_rate,
+        'mid_video_predict_res': mid_video_predict_res,
+        'threshold': threshold,
+        'ad_predict': ad_predict
+    }
+    return result
+
+
+def predict_mid_video_res(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status, app_type):
+    # now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
+    # user_data_key = abtest_param['user'].get('data')
+    # user_rule_key = abtest_param['user'].get('rule')
+    # video_data_key = abtest_param['video'].get('data')
     group_class_key = abtest_param.get('group_class_key')
     no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
+    no_ad_group_with_video_mapping = abtest_param.get('no_ad_group_with_video_mapping', {})
 
     # 判断mid所属分组
     mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
@@ -90,52 +144,49 @@ def predict_mid_video_res(now_date, mid, video_id, abtest_param, abtest_id, abte
         ad_predict = 1
         result = {
             'mid_group': mid_group,
-            'ad_predict': ad_predict
+            'ad_predict': ad_predict,
+            'no_ad_strategy': 'no_ad_mid_group'
         }
-    else:
-        # 获取用户组分享率
-        group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{now_dt}"
-        if not redis_helper.key_exists(group_share_rate_key):
-            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
-            group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{redis_dt}"
-        group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)
-        # 获取视频分享率
-        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}"
-        if not redis_helper.key_exists(video_share_rate_key):
-            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
-            video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{redis_dt}"
-        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
-        if video_share_rate is None:
-            video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)
-
-        # 计算 mid-video 分享率
-        if group_share_rate is None or video_share_rate is None:
-            return None
-        mid_video_predict_res = float(group_share_rate) * float(video_share_rate)
+    elif mid_group in no_ad_group_with_video_mapping:
+        # 用户组在特定内容不出广告设置中
+        # 获取对应的特定内容
+        video_mapping_key_list = no_ad_group_with_video_mapping.get(mid_group, [])
+        no_ad_videos = redis_helper.get_data_from_redis(key_name=f"{config_.KEY_NAME_PREFIX_NO_AD_VIDEOS}{app_type}")
+        no_ad_videos = json.loads(no_ad_videos)
+        no_ad_video_list = []
+        for video_mapping_key in video_mapping_key_list:
+            no_ad_video_list.extend(no_ad_videos.get(video_mapping_key, []))
+        # 判断此次请求视频是否在免广告视频列表中
+        if video_id in no_ad_video_list:
+            # 在,则不出广告
+            ad_predict = 1
+            result = {
+                'mid_group': mid_group,
+                'ad_predict': ad_predict,
+                'no_ad_strategy': 'no_ad_mid_group_with_video'
+            }
+        else:
+            result = predict_with_rate_process(
+                now_date=now_date,
+                video_id=video_id,
+                abtest_param=abtest_param,
+                abtest_id=abtest_id,
+                abtest_config_tag=abtest_config_tag,
+                ab_test_code=ab_test_code,
+                care_model_status=care_model_status,
+                mid_group=mid_group)
 
-        # 获取对应的阈值
-        threshold = get_threshold(
+    else:
+        result = predict_with_rate_process(
+            now_date=now_date,
+            video_id=video_id,
+            abtest_param=abtest_param,
             abtest_id=abtest_id,
             abtest_config_tag=abtest_config_tag,
             ab_test_code=ab_test_code,
-            mid_group=mid_group,
             care_model_status=care_model_status,
-            abtest_param=abtest_param
-        )
-        # 阈值判断
-        if mid_video_predict_res > threshold:
-            # 大于阈值,出广告
-            ad_predict = 2
-        else:
-            # 否则,不出广告
-            ad_predict = 1
-        result = {
-            'mid_group': mid_group,
-            'group_share_rate': group_share_rate,
-            'video_share_rate': video_share_rate,
-            'mid_video_predict_res': mid_video_predict_res,
-            'threshold': threshold,
-            'ad_predict': ad_predict}
+            mid_group=mid_group)
+
     return result
 
 
@@ -404,7 +455,8 @@ def ad_recommend_predict(app_type, mid, video_id, ab_exp_info, ab_test_code, car
                 abtest_id=abtest_id,
                 abtest_config_tag=abtest_config_tag,
                 ab_test_code=ab_test_code,
-                care_model_status=care_model_status
+                care_model_status=care_model_status,
+                app_type=app_type
             )
 
         # user_data_key = abtest_param['user'].get('data')

+ 57 - 36
config.py

@@ -1093,42 +1093,42 @@ class BaseConfig(object):
             'care_model_status_param': 1,
             'care_model_ab_mid_group': ['mean_group'],
         },  # 所有广告类型数据 + 优化阈值计算方式 + else未开启关怀模式人群多出广告 + 使用以是否直接跳出为目标的数据
-        '173-o': {
-            'video': {'data': 'videos0out'},
-            'user': {'data': 'user0out', 'rule': 'rule2'},
-            'group_class_key': 'class1',
-            'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
-            'care_model_status_param': 1,
-            'care_model_ab_mid_group': ['mean_group', 'return0share1mids'],
-        },  # 所有广告类型数据 + 优化阈值计算方式 + [else, return0share1mids]非关怀模式人群多出广告 + 使用以是否直接跳出为目标的数据
-        '173-p': {
-            'share': {'video': {'data': 'videos0'}, 'user': {'data': 'user0', 'rule': 'rule2'}},
-            'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
-            'group_class_key': 'class1',
-            'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
-            'care_model_status_param': 1,
-            'care_model_ab_mid_group': ['mean_group'],
-            'threshold_mix_func': 'add',
-            'mix_param': {'share_weight': 0.2, 'out_weight': 0.8}
-        },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案一(加权融合: k1*p(不直接跳出|出广告) + k2*p(分享|出广告))
-        '173-q': {
-            'share': {'video': {'data': 'videos0'}, 'user': {'data': 'user0', 'rule': 'rule2'}},
-            'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
-            'group_class_key': 'class1',
-            'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
-            'care_model_status_param': 1,
-            'care_model_ab_mid_group': ['mean_group'],
-            'threshold_mix_func': 'multiply',
-        },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案二(乘积融合: p(不直接跳出|出广告) * p(分享|出广告))
-        '173-r': {
-            'share': {'video': {'data': 'videos0new'}, 'user': {'data': 'user0new', 'rule': 'rule2'}},
-            'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
-            'group_class_key': 'class1',
-            'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
-            'care_model_status_param': 1,
-            'care_model_ab_mid_group': ['mean_group'],
-            'threshold_mix_func': 'multiply',
-        },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案三(乘积融合: p(不直接跳出|出广告) * p(分享|出广告), 标准贝叶斯公式)
+        # '173-o': {
+        #     'video': {'data': 'videos0out'},
+        #     'user': {'data': 'user0out', 'rule': 'rule2'},
+        #     'group_class_key': 'class1',
+        #     'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
+        #     'care_model_status_param': 1,
+        #     'care_model_ab_mid_group': ['mean_group', 'return0share1mids'],
+        # },  # 所有广告类型数据 + 优化阈值计算方式 + [else, return0share1mids]非关怀模式人群多出广告 + 使用以是否直接跳出为目标的数据
+        # '173-p': {
+        #     'share': {'video': {'data': 'videos0'}, 'user': {'data': 'user0', 'rule': 'rule2'}},
+        #     'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
+        #     'group_class_key': 'class1',
+        #     'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
+        #     'care_model_status_param': 1,
+        #     'care_model_ab_mid_group': ['mean_group'],
+        #     'threshold_mix_func': 'add',
+        #     'mix_param': {'share_weight': 0.2, 'out_weight': 0.8}
+        # },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案一(加权融合: k1*p(不直接跳出|出广告) + k2*p(分享|出广告))
+        # '173-q': {
+        #     'share': {'video': {'data': 'videos0'}, 'user': {'data': 'user0', 'rule': 'rule2'}},
+        #     'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
+        #     'group_class_key': 'class1',
+        #     'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
+        #     'care_model_status_param': 1,
+        #     'care_model_ab_mid_group': ['mean_group'],
+        #     'threshold_mix_func': 'multiply',
+        # },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案二(乘积融合: p(不直接跳出|出广告) * p(分享|出广告))
+        # '173-r': {
+        #     'share': {'video': {'data': 'videos0new'}, 'user': {'data': 'user0new', 'rule': 'rule2'}},
+        #     'out': {'video': {'data': 'videos0out'}, 'user': {'data': 'user0out', 'rule': 'rule2'}},
+        #     'group_class_key': 'class1',
+        #     'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
+        #     'care_model_status_param': 1,
+        #     'care_model_ab_mid_group': ['mean_group'],
+        #     'threshold_mix_func': 'multiply',
+        # },  # 所有广告类型本端视频数据 + 优化阈值计算方式 + else非关怀模式人群多出广告 + 分享与不直接跳出融合方案三(乘积融合: p(不直接跳出|出广告) * p(分享|出广告), 标准贝叶斯公式)
         '173-s': {
             'video': {'data': 'videos0out'},
             'user': {'data': 'user0out', 'rule': 'rule3'},
@@ -1137,6 +1137,24 @@ class BaseConfig(object):
             'care_model_status_param': 1,
             'care_model_ab_mid_group': ['mean_group'],
         },  # 所有广告类型数据 + 优化阈值计算方式 + else未开启关怀模式人群多出广告 + 使用以是否直接跳出为目标的数据 + ['return25_nmids', 'return9_24mids']用户不出广告
+        '173-t': {
+            'video': {'data': 'videos0out'},
+            'user': {'data': 'user0out', 'rule': 'rule2'},
+            'group_class_key': 'class1',
+            'no_ad_mid_group_list': NO_AD_MID_GROUP_LIST['class1'],
+            'care_model_status_param': 1,
+            'care_model_ab_mid_group': ['mean_group'],
+            'no_ad_group_with_video_mapping': {
+                'mean_group': ['top3'],
+                'return0share1mids': ['top3'],
+                'return0share2_nmids': ['top3'],
+                'return1mids': ['top3'],
+                'return2_3mids': ['top3'],
+                'return4_8mids': ['top3'],
+                'return9_24mids': ['top3'],
+                'return25_nmids': ['top3'],
+            }
+        },  # 所有广告类型数据 + 优化阈值计算方式 + else未开启关怀模式人群多出广告 + 使用以是否直接跳出为目标的数据 + return25_nmids用户不出广告 + mean_group & top2不出广告
 
         # 票圈视频+
         # '190-a': {
@@ -1812,6 +1830,9 @@ class BaseConfig(object):
     # 广告推荐关怀模式实验阈值结果存放 redis key 前缀,完整格式:ad:threshold:care:{abtestId}:{abtestConfigTag}:{abtestGroup}:{group}
     KEY_NAME_PREFIX_AD_THRESHOLD_CARE_MODEL = 'ad:threshold:care:'
 
+    # 特定视频不出广告视频列表存放 redis key 前缀,完整格式:no:ad:videos:{appType}
+    KEY_NAME_PREFIX_NO_AD_VIDEOS = 'no:ad:videos:'
+
     # 新策略使用
     # 视频有广告时的分享率预测结果存放 redis key 前缀,完整格式:video:predict:share:rate:with:ad:{video_data_key}:{date}
     KEY_NAME_PREFIX_VIDEO_WITH_AD = 'video:predict:share:rate:with:ad:'