import traceback import datetime from utils import RedisHelper from config import set_config from log import Log log_ = Log() config_ = set_config() redis_helper = RedisHelper() def get_params(ab_exp_info, ab_test_code): """ 根据实验分组给定对应的参数 :param ab_exp_info: AB实验组参数 :param ab_test_code: 用户对应的ab组 :return: """ abtest_id, abtest_config_tag = None, None ad_abtest_id_list = [key.split('-')[0] for key in config_.AD_ABTEST_CONFIG] # 获取广告实验配置 config_value_dict = {} if ab_exp_info: ab_exp_list = ab_exp_info.get('ab_test002', None) if ab_exp_list: for ab_item in ab_exp_list: ab_exp_code = ab_item.get('abExpCode', None) if not ab_exp_code: continue if ab_exp_code in ad_abtest_id_list: config_value = ab_item.get('configValue', None) if config_value: config_value_dict[str(ab_exp_code)] = eval(str(config_value)) if len(config_value_dict) > 0: for ab_exp_code, config_value in config_value_dict.items(): for tag, value in config_value.items(): if ab_test_code in value: abtest_id = ab_exp_code abtest_config_tag = tag break return abtest_id, abtest_config_tag def ad_recommend_predict(app_type, mid, video_id, ab_exp_info, ab_test_code): """ 广告推荐预测 :param app_type: app_type :param mid: mid :param video_id: video_id :param ab_exp_info: AB实验组参数 :param ab_test_code: 用户对应的ab组 :return: ad_predict, type-int, 1-不发放广告,2-发放广告 """ try: now_date = datetime.datetime.today() now_dt = datetime.datetime.strftime(now_date, '%Y%m%d') # 获取实验参数 abtest_id, abtest_config_tag = get_params(ab_exp_info=ab_exp_info, ab_test_code=ab_test_code) if abtest_id is None or abtest_config_tag is None: return None abtest_param = config_.AD_ABTEST_CONFIG.get(f'{abtest_id}-{abtest_config_tag}') if abtest_param is None: return None user_data_key = abtest_param.get('user') video_data_key = abtest_param.get('video') # 判断mid所属分组 mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{mid}" mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name) if mid_group is None: mid_group = 'mean_group' # 判断用户是否在免广告用户组列表中 if mid_group in config_.NO_AD_MID_GROUP_LIST: # 在免广告用户组列表中,则不出广告 ad_predict = 1 result = { 'mid_group': mid_group, 'ad_predict': ad_predict } else: # 获取用户组分享率 group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_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}:{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_share_rate = float(group_share_rate) * float(video_share_rate) # 获取对应的阈值 threshold_key_name = f"{config_.KEY_NAME_PREFIX_AD_THRESHOLD}{abtest_id}:{abtest_config_tag}:{mid_group}" threshold = redis_helper.get_data_from_redis(key_name=threshold_key_name) if threshold is None: threshold = 0 else: threshold = float(threshold) # 阈值判断 if mid_video_share_rate > 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_share_rate': mid_video_share_rate, 'threshold': threshold, 'ad_predict': ad_predict} return result except Exception as e: log_.error(traceback.format_exc()) return None