Pārlūkot izejas kodu

add relevant-top

liqian 3 gadi atpakaļ
vecāks
revīzija
4e43b18308
2 mainītis faili ar 97 papildinājumiem un 5 dzēšanām
  1. 3 1
      config.py
  2. 94 4
      recommend.py

+ 3 - 1
config.py

@@ -35,7 +35,8 @@ class BaseConfig(object):
         'top': 'op_manual',  # 置顶
         'bottom': 'bottom_strategy',  # 一层兜底
         'bottom_last': 'bottom_strategy_last',  # 二层兜底
-        'position_insert': 'position_insert'  # 按位置插入
+        'position_insert': 'position_insert',  # 按位置插入
+        'relevant_video_op': 'relevant_video_op',  # 相关推荐强插
     }
     # category id mapping
     CATEGORY = {
@@ -270,6 +271,7 @@ class ProductionConfig(BaseConfig):
 def set_config():
     # 获取环境变量 ROV_SERVER_ENV
     env = os.environ.get('ROV_SERVER_ENV')
+    # env = 'dev'
     if env is None:
         log_.error('ENV ERROR: is None!')
         return

+ 94 - 4
recommend.py

@@ -1,3 +1,4 @@
+import json
 import time
 import multiprocessing
 import traceback
@@ -18,6 +19,64 @@ log_ = Log()
 config_ = set_config()
 
 
+def relevant_video_top_recommend(app_type, mid, uid, head_vid, videos, size):
+    """
+    相关推荐强插 运营给定置顶相关性视频
+    :param app_type: 产品标识 type-int
+    :param mid: mid
+    :param uid: uid
+    :param head_vid: 相关推荐头部视频id type-int
+    :param videos: 当前相关推荐结果 type-list
+    :param size: 返回视频个数 type-int
+    :return: rank_result
+    """
+    # 获取头部视频对应的相关性视频
+    key_name = '{}{}'.format(config_.RELEVANT_VIDEOS_WITH_OP_KEY_NAME, head_vid)
+    redis_helper = RedisHelper()
+    relevant_videos = redis_helper.get_data_from_redis(key_name=key_name)
+    if relevant_videos is None:
+        # 该视频没有指定的相关性视频
+        return videos
+    relevant_videos = json.loads(relevant_videos)
+    # 按照指定顺序排序
+    relevant_videos_sorted = sorted(relevant_videos, key=lambda x: x['order'], reverse=False)
+
+    # 过滤
+    relevant_video_ids = [int(item['recommend_vid']) for item in relevant_videos_sorted]
+    filter_helper = FilterVideos(app_type=app_type, video_ids=relevant_video_ids, mid=mid, uid=uid)
+    filtered_ids = filter_helper.filter_videos()
+    if filtered_ids is None:
+        return videos
+
+    # 获取生效中的视频
+    now = int(time.time())
+    relevant_videos_in_effect = [
+        {'videoId': int(item['recommend_vid']), 'pushFrom': config_.PUSH_FROM['relevant_video_op'],
+         'abCode': config_.AB_CODE['relevant_video_op']}
+        for item in relevant_videos_sorted
+        if item['start_time'] < now < item['finish_time'] and int(item['recommend_vid']) in filtered_ids
+    ]
+
+    if len(relevant_videos_in_effect) == 0:
+        return videos
+
+    # 与现有排序结果 进行合并重排
+    # 获取现有排序结果中流量池视频 及其位置
+    flow_pool_videos = []
+    other_videos = []
+    for i, item in enumerate(videos):
+        if item.get('pushFrom', None) == config_.PUSH_FROM['flow_recall']:
+            flow_pool_videos.append((i, item))
+        else:
+            other_videos.append(item)
+    # 重排,保持流量池视频位置不变
+    rank_result = relevant_videos_in_effect + other_videos
+    for i, item in flow_pool_videos:
+        rank_result.insert(i, item)
+
+    return rank_result[:size]
+
+
 def video_position_recommend(mid, uid, app_type, videos):
     # videos = video_recommend(mid=mid, uid=uid, size=size, app_type=app_type,
     #                          algo_type=algo_type, client_info=client_info)
@@ -55,6 +114,7 @@ def video_position_recommend(mid, uid, app_type, videos):
 
     return videos[:10]
 
+
 def positon_duplicate(pos1_vids, pos2_vids, videos):
     s = set()
     if pos1_vids is not None and len(pos1_vids) >0:
@@ -70,6 +130,7 @@ def positon_duplicate(pos1_vids, pos2_vids, videos):
             l.append(item)
     return l
 
+
 def video_recommend(mid, uid, size, app_type, algo_type, client_info):
     """
     首页线上推荐逻辑
@@ -161,6 +222,17 @@ def ab_test_op(rank_result, ab_code_list, app_type, mid, uid, **kwargs):
         log_.info('app_type: {}, mid: {}, uid: {}, rank_by_position_insert_result: {}'.format(
             app_type, mid, uid, rank_result))
 
+    # 相关推荐强插
+    if config_.AB_CODE['relevant_video_op'] in ab_code_list \
+            and app_type in config_.AB_TEST.get('relevant_video_op', []):
+        head_vid = kwargs['head_vid']
+        size = kwargs['size']
+        rank_result = relevant_video_top_recommend(
+            app_type=app_type, mid=mid, uid=uid, head_vid=head_vid, videos=rank_result, size=size
+        )
+        log_.info('app_type: {}, mid: {}, uid: {}, head_vid: {}, rank_by_relevant_video_op_result: {}'.format(
+            app_type, mid, uid, head_vid, rank_result))
+
     return rank_result
 
 
@@ -270,8 +342,11 @@ def video_relevant_recommend(video_id, mid, uid, size, app_type):
                                                        algo_type='', client_info=None)
     # ab-test
     result = ab_test_op(rank_result=rank_result,
-                        ab_code_list=[config_.AB_CODE['position_insert']],
-                        app_type=app_type, mid=mid, uid=uid, video_id=video_id)
+                        ab_code_list=[
+                            config_.AB_CODE['position_insert'],
+                            config_.AB_CODE['relevant_video_op']
+                        ],
+                        app_type=app_type, mid=mid, uid=uid, head_vid=video_id, size=size)
     # redis数据刷新
     update_redis_data(result=result, app_type=app_type, mid=mid, last_rov_recall_key=last_rov_recall_key)
 
@@ -279,5 +354,20 @@ def video_relevant_recommend(video_id, mid, uid, size, app_type):
 
 
 if __name__ == '__main__':
-    videos = [{'videoId': '12345', 'flowPool': '133#442#2', 'distributeCount': 10}]
-    update_local_distribute_count(videos)
+    videos = [
+        {"videoId": 10136461, "rovScore": 99.971, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 10239014, "rovScore": 99.97, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 9851154, "rovScore": 99.969, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 10104347, "rovScore": 99.968, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 10141507, "rovScore": 99.967, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 10292817, "flowPool": "2#6#2#1641780979606", "rovScore": 53.926690610816486,
+         "pushFrom": "flow_pool", "abCode": 10000},
+        {"videoId": 10224932, "flowPool": "2#5#1#1641800279644", "rovScore": 53.47890460059617, "pushFrom": "flow_pool",
+         "abCode": 10000},
+        {"videoId": 9943255, "rovScore": 99.966, "pushFrom": "recall_pool", "abCode": 10000},
+        {"videoId": 10282970, "flowPool": "2#5#1#1641784814103", "rovScore": 52.682815076325575,
+         "pushFrom": "flow_pool", "abCode": 10000},
+        {"videoId": 10282205, "rovScore": 99.965, "pushFrom": "recall_pool", "abCode": 10000}
+    ]
+    res = relevant_video_top_recommend(app_type=4, mid='', uid=1111, head_vid=123, videos=videos, size=10)
+    print(res)