|
@@ -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)
|