|  | @@ -1,74 +1,130 @@
 | 
											
												
													
														|  | 
 |  | +import traceback
 | 
											
												
													
														|  |  import datetime
 |  |  import datetime
 | 
											
												
													
														|  |  from utils import RedisHelper
 |  |  from utils import RedisHelper
 | 
											
												
													
														|  |  from config import set_config
 |  |  from config import set_config
 | 
											
												
													
														|  | 
 |  | +from log import Log
 | 
											
												
													
														|  | 
 |  | +log_ = Log()
 | 
											
												
													
														|  |  config_ = set_config()
 |  |  config_ = set_config()
 | 
											
												
													
														|  |  redis_helper = RedisHelper()
 |  |  redis_helper = RedisHelper()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -def ad_recommend_predict(app_type, mid, video_id):
 |  | 
 | 
											
												
													
														|  | 
 |  | +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_test003', 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 app_type: app_type
 | 
											
												
													
														|  |      :param mid: mid
 |  |      :param mid: mid
 | 
											
												
													
														|  |      :param video_id: video_id
 |  |      :param video_id: video_id
 | 
											
												
													
														|  | 
 |  | +    :param ab_exp_info: AB实验组参数
 | 
											
												
													
														|  | 
 |  | +    :param ab_test_code: 用户对应的ab组
 | 
											
												
													
														|  |      :return: ad_predict, type-int, 1-不发放广告,2-发放广告
 |  |      :return: ad_predict, type-int, 1-不发放广告,2-发放广告
 | 
											
												
													
														|  |      """
 |  |      """
 | 
											
												
													
														|  | -    now_date = datetime.datetime.today()
 |  | 
 | 
											
												
													
														|  | -    now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    # 判断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'
 |  | 
 | 
											
												
													
														|  | 
 |  | +    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
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    # 判断用户是否在免广告用户组列表中
 |  | 
 | 
											
												
													
														|  | -    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}{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}{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}{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}{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)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        user_data_key = abtest_param.get('user')
 | 
											
												
													
														|  | 
 |  | +        video_data_key = abtest_param.get('video')
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        # 计算 mid-video 分享率
 |  | 
 | 
											
												
													
														|  | -        mid_video_share_rate = float(group_share_rate) * float(video_share_rate)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        # 判断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'
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        # 获取对应的阈值
 |  | 
 | 
											
												
													
														|  | -        threshold_key_name = f"{config_.KEY_NAME_PREFIX_AD_THRESHOLD}{app_type}:{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:
 |  | 
 | 
											
												
													
														|  | -            # 否则,不出广告
 |  | 
 | 
											
												
													
														|  | 
 |  | +        # 判断用户是否在免广告用户组列表中
 | 
											
												
													
														|  | 
 |  | +        if mid_group in config_.NO_AD_MID_GROUP_LIST:
 | 
											
												
													
														|  | 
 |  | +            # 在免广告用户组列表中,则不出广告
 | 
											
												
													
														|  |              ad_predict = 1
 |  |              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}
 |  | 
 | 
											
												
													
														|  | 
 |  | +            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}{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}{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
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    return result
 |  | 
 | 
											
												
													
														|  | 
 |  | +    except Exception as e:
 | 
											
												
													
														|  | 
 |  | +        log_.error(traceback.format_exc())
 | 
											
												
													
														|  | 
 |  | +        return None
 |