ad_recommend.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import traceback
  2. import datetime
  3. from utils import RedisHelper
  4. from config import set_config
  5. from log import Log
  6. log_ = Log()
  7. config_ = set_config()
  8. redis_helper = RedisHelper()
  9. def get_params(ab_exp_info, ab_test_code):
  10. """
  11. 根据实验分组给定对应的参数
  12. :param ab_exp_info: AB实验组参数
  13. :param ab_test_code: 用户对应的ab组
  14. :return:
  15. """
  16. abtest_id, abtest_config_tag = None, None
  17. ad_abtest_id_list = [key.split('-')[0] for key in config_.AD_ABTEST_CONFIG]
  18. # 获取广告实验配置
  19. config_value_dict = {}
  20. if ab_exp_info:
  21. ab_exp_list = ab_exp_info.get('ab_test002', None)
  22. if ab_exp_list:
  23. for ab_item in ab_exp_list:
  24. ab_exp_code = ab_item.get('abExpCode', None)
  25. if not ab_exp_code:
  26. continue
  27. if ab_exp_code in ad_abtest_id_list:
  28. config_value = ab_item.get('configValue', None)
  29. if config_value:
  30. config_value_dict[str(ab_exp_code)] = eval(str(config_value))
  31. if len(config_value_dict) > 0:
  32. for ab_exp_code, config_value in config_value_dict.items():
  33. for tag, value in config_value.items():
  34. if ab_test_code in value:
  35. abtest_id = ab_exp_code
  36. abtest_config_tag = tag
  37. break
  38. return abtest_id, abtest_config_tag
  39. def ad_recommend_predict(app_type, mid, video_id, ab_exp_info, ab_test_code):
  40. """
  41. 广告推荐预测
  42. :param app_type: app_type
  43. :param mid: mid
  44. :param video_id: video_id
  45. :param ab_exp_info: AB实验组参数
  46. :param ab_test_code: 用户对应的ab组
  47. :return: ad_predict, type-int, 1-不发放广告,2-发放广告
  48. """
  49. try:
  50. now_date = datetime.datetime.today()
  51. now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
  52. # 获取实验参数
  53. abtest_id, abtest_config_tag = get_params(ab_exp_info=ab_exp_info, ab_test_code=ab_test_code)
  54. if abtest_id is None or abtest_config_tag is None:
  55. return None
  56. abtest_param = config_.AD_ABTEST_CONFIG.get(f'{abtest_id}-{abtest_config_tag}')
  57. if abtest_param is None:
  58. return None
  59. user_data_key = abtest_param['user'].get('data')
  60. user_rule_key = abtest_param['user'].get('rule')
  61. video_data_key = abtest_param['video'].get('data')
  62. group_class_key = abtest_param.get('group_class_key')
  63. no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
  64. # 判断mid所属分组
  65. mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{mid}"
  66. mid_group_value = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
  67. if mid_group_value is None:
  68. mid_group = 'mean_group'
  69. else:
  70. mid_group = eval(mid_group_value).get(group_class_key, 'mean_group')
  71. # 判断用户是否在免广告用户组列表中
  72. if mid_group in no_ad_mid_group_list:
  73. # 在免广告用户组列表中,则不出广告
  74. ad_predict = 1
  75. result = {
  76. 'mid_group': mid_group,
  77. 'ad_predict': ad_predict
  78. }
  79. else:
  80. # 获取用户组分享率
  81. group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{now_dt}"
  82. if not redis_helper.key_exists(group_share_rate_key):
  83. redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
  84. group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{redis_dt}"
  85. group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)
  86. # 获取视频分享率
  87. video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}"
  88. if not redis_helper.key_exists(video_share_rate_key):
  89. redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
  90. video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{redis_dt}"
  91. video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
  92. if video_share_rate is None:
  93. video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)
  94. # 计算 mid-video 分享率
  95. if group_share_rate is None or video_share_rate is None:
  96. return None
  97. mid_video_share_rate = float(group_share_rate) * float(video_share_rate)
  98. # 获取对应的阈值
  99. threshold_key_name = f"{config_.KEY_NAME_PREFIX_AD_THRESHOLD}{abtest_id}:{abtest_config_tag}:{mid_group}"
  100. threshold = redis_helper.get_data_from_redis(key_name=threshold_key_name)
  101. if threshold is None:
  102. threshold = 0
  103. else:
  104. threshold = float(threshold)
  105. # 阈值判断
  106. if mid_video_share_rate > threshold:
  107. # 大于阈值,出广告
  108. ad_predict = 2
  109. else:
  110. # 否则,不出广告
  111. ad_predict = 1
  112. result = {
  113. 'mid_group': mid_group,
  114. 'group_share_rate': group_share_rate,
  115. 'video_share_rate': video_share_rate,
  116. 'mid_video_share_rate': mid_video_share_rate,
  117. 'threshold': threshold,
  118. 'ad_predict': ad_predict}
  119. return result
  120. except Exception as e:
  121. log_.error(traceback.format_exc())
  122. return None