瀏覽代碼

feat:人群选择所有实验支持按人群配置出广告比例

zhaohaipeng 3 周之前
父節點
當前提交
7d72c6ffd4

+ 93 - 78
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/impl/PredictModelServiceImpl.java

@@ -7,9 +7,7 @@ import com.tzld.piaoquan.ad.engine.commons.enums.AppTypeEnum;
 import com.tzld.piaoquan.ad.engine.commons.enums.RedisPrefixEnum;
 import com.tzld.piaoquan.ad.engine.commons.redis.AdRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
-import com.tzld.piaoquan.ad.engine.commons.util.AbUtil;
 import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
-import com.tzld.piaoquan.ad.engine.service.log.LogHubService;
 import com.tzld.piaoquan.ad.engine.service.predict.PredictModelService;
 import com.tzld.piaoquan.ad.engine.service.predict.config.AbConfig;
 import com.tzld.piaoquan.ad.engine.service.predict.config.NewExpUserGroupConfig;
@@ -43,8 +41,6 @@ import java.util.*;
 @Service
 public class PredictModelServiceImpl implements PredictModelService {
     private final static Logger log = LoggerFactory.getLogger(PredictModelServiceImpl.class);
-    @Value("${ad.own.experiment.tier:ab_test002}")
-    private String adOwnExperimentTier;
 
     @Autowired
     private AbTestConfigContainer abTestConfigContainer;
@@ -61,25 +57,31 @@ public class PredictModelServiceImpl implements PredictModelService {
     @Autowired
     RoiModelConfig roiModelConfig;
 
+    // @Autowired
+    // private PredictServiceV2 predictServiceV2;
+    // @Autowired
+    // private RootSessionIdPredict rootSessionIdPredict;
     @Autowired
-    private PredictServiceV2 predictServiceV2;
+    private UserLayerRootSessionIdPredict userLayerRootSessionIdPredict;
     @Autowired
-    private RootSessionIdPredict rootSessionIdPredict;
+    private PredictStrategyBy673 predictStrategyBy673;
     @Autowired
-    private UserLayerRootSessionIdPredict userLayerRootSessionIdPredict;
-
+    private PredictStrategyBy667 predictStrategyBy667;
     @Autowired
-    private UserService userService;
+    private PredictStrategyBy599 predictStrategyBy599;
 
     @Autowired
-    private LogHubService logHubService;
-
-    @Value("${ad.predict.share0.exp.code:000}")
-    private String adPredictNoShareUserExpCode;
+    private UserService userService;
 
+    // @Value("${ad.own.experiment.tier:ab_test002}")
+    // private String adOwnExperimentTier;
+    // @Autowired
+    // private LogHubService logHubService;
+    // @Value("${ad.predict.share0.exp.code:000}")
+    // private String adPredictNoShareUserExpCode;
 
-    @Value("${ad.predict.immersion.exp.code:607}")
-    private String adPredictImmersionExpCode;
+    // @Value("${ad.predict.immersion.exp.code:607}")
+    // private String adPredictImmersionExpCode;
 
     @Value("${ad.predict.param.testIds:0}")
     private String testIds;
@@ -103,7 +105,7 @@ public class PredictModelServiceImpl implements PredictModelService {
     @Autowired
     private AdRedisHelper adRedisHelper;
 
-    List<Integer> appIdArr = Arrays.asList(new Integer[]{0, 3, 4, 5, 6, 17, 18, 19, 21, 22});
+    // List<Integer> appIdArr = Arrays.asList(new Integer[]{0, 3, 4, 5, 6, 17, 18, 19, 21, 22});
 
 
     public Map<String, Object> adPredict(ThresholdPredictModelRequestParam requestParam) {
@@ -169,13 +171,13 @@ public class PredictModelServiceImpl implements PredictModelService {
                 return result;
             }
 
-            if (AbUtil.isInAbExp(expCodes, requestParam.getAppType(), requestParam.getNewExpGroup(), "713")) {
-                PredictContext context = ConvertUtil.predictParam2Context(requestParam);
-                Map<String, Object> resultMap = predictServiceV2.predict(context);
-                logHubService.crowdChooseLogUpload(context);
-                resultMap.put("pqtId", requestParam.getPqtId());
-                return resultMap;
-            }
+            // if (AbUtil.isInAbExp(expCodes, requestParam.getAppType(), requestParam.getNewExpGroup(), "713")) {
+            //     PredictContext context = ConvertUtil.predictParam2Context(requestParam);
+            //     Map<String, Object> resultMap = predictServiceV2.predict(context);
+            //     logHubService.crowdChooseLogUpload(context);
+            //     resultMap.put("pqtId", requestParam.getPqtId());
+            //     return resultMap;
+            // }
 
             String abtestId = null;
             String abTestConfigTag = null;
@@ -261,77 +263,90 @@ public class PredictModelServiceImpl implements PredictModelService {
             // 市-中文
             requestParam.setRegion(requestParam.getRegion().replace("省", ""));
             requestParam.setCity(requestParam.getCity().replace("市", ""));
-            // 设置信息
-            ThresholdPredictModelParam modelParam = ThresholdPredictModelParam.builder()
-                    .build();
-            BeanUtils.copyProperties(requestParam, modelParam);
-            modelParam.setDate(new Date());
-            modelParam.setAbtestId(abtestId);
-            modelParam.setAbTestConfigTag(abTestConfigTag);
-            modelParam.setAbtestParam(abtestParam);
-            modelParam.setMidGroup(midGroup);
-            modelParam.setExtraParam(new HashMap<>());
-            modelParam.addUserExtraFuture("shareType", shareType);
-            setExtraParam(modelParam);
-
             requestParam.setShareType(shareType);
             String userLayer = userService.getUserLayer4Level(requestParam.getMid());
             requestParam.setUserLayer(userLayer);
 
             // 先走rootSessionId 实验
-            Map<String, Object> predict = rootSessionIdPredict.predict(ConvertUtil.predictParam2Context(requestParam));
-            if (MapUtils.isNotEmpty(predict)) {
-                return predict;
-            }
+            // Map<String, Object> predict = rootSessionIdPredict.predict(ConvertUtil.predictParam2Context(requestParam));
+            // if (MapUtils.isNotEmpty(predict)) {
+            //     return predict;
+            // }
 
             Map<String, Object> userLayerPredict = userLayerRootSessionIdPredict.predict(ConvertUtil.predictParam2Context(requestParam));
             if (MapUtils.isNotEmpty(userLayerPredict)) {
                 return userLayerPredict;
             }
 
-            String appTypeStr = requestParam.getAppType().toString();
-
-            List<String> userSourceAndLayerAdRateExpIds = Arrays.asList(userSourceLayerAdRateExpIds.split(","));
-            boolean inAdRateExp = this.checkInAnyExpIdsAndNewAb(expCodes, userSourceAndLayerAdRateExpIds, appTypeStr, requestParam.getNewExpGroup(), modelParam);
-            if (inAdRateExp) {
-                result = ThresholdModelContainer.getThresholdPredictModel("random673").predict(modelParam);
-                // 如果676实验返回结果,表示未命中规则即对应的用户来源和所属层存在配置,使用676实验的结果,否则继续走599实验
-                if (Objects.nonNull(result)) {
-                    return result;
+            if (expCodes.contains("673")) {
+                Map<String, Object> predictResult = predictStrategyBy673.predict(ConvertUtil.predictParam2Context(requestParam));
+                if (Objects.nonNull(predictResult)) {
+                    return predictResult;
                 }
             }
 
-            // 新老实验系统兼容
-            if (expCodes.contains("599") ||
-                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "599", modelParam))) {
-                // NewExpInfoHelper.flagId   647
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel("random")
-                        .predict(modelParam);
-            } else if (expCodes.contains("667") ||
-                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "667", modelParam))) {
-                // NewExpInfoHelper.flagId   647
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel("random667")
-                        .predict(modelParam);
-            } else if (inExpList(expCodes, adPredictImmersionExpCode)
-                    ||
-                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "607", modelParam))) {
-                // adPredictImmersionExpCode 607 631
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel("immersion")
-                        .predict(modelParam);
-            } else {
-                Object thresholdMixFunc = abtestParam.getOrDefault("threshold_mix_func", "basic");
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel(thresholdMixFunc.toString())
-                        .predict(modelParam);
+            if (expCodes.contains("599")){
+                return predictStrategyBy599.predict(ConvertUtil.predictParam2Context(requestParam));
+            }else if (expCodes.contains("667")){
+                return predictStrategyBy667.predict(ConvertUtil.predictParam2Context(requestParam));
+            }else {
+                return predictStrategyBy599.predict(ConvertUtil.predictParam2Context(requestParam));
             }
 
-            return result;
+            // 设置信息
+            // ThresholdPredictModelParam modelParam = ThresholdPredictModelParam.builder()
+            //         .build();
+            // BeanUtils.copyProperties(requestParam, modelParam);
+            // modelParam.setDate(new Date());
+            // modelParam.setAbtestId(abtestId);
+            // modelParam.setAbTestConfigTag(abTestConfigTag);
+            // modelParam.setAbtestParam(abtestParam);
+            // modelParam.setMidGroup(midGroup);
+            // modelParam.setExtraParam(new HashMap<>());
+            // modelParam.addUserExtraFuture("shareType", shareType);
+            // setExtraParam(modelParam);
+
+            // String appTypeStr = requestParam.getAppType().toString();
+            //
+            // List<String> userSourceAndLayerAdRateExpIds = Arrays.asList(userSourceLayerAdRateExpIds.split(","));
+            // boolean inAdRateExp = this.checkInAnyExpIdsAndNewAb(expCodes, userSourceAndLayerAdRateExpIds, appTypeStr, requestParam.getNewExpGroup(), modelParam);
+            // if (inAdRateExp) {
+            //     result = ThresholdModelContainer.getThresholdPredictModel("random673").predict(modelParam);
+            //     // 如果676实验返回结果,表示未命中规则即对应的用户来源和所属层存在配置,使用676实验的结果,否则继续走599实验
+            //     if (Objects.nonNull(result)) {
+            //         return result;
+            //     }
+            // }
+            // // 新老实验系统兼容
+            // if (expCodes.contains("599") ||
+            //         (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+            //                 requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "599", modelParam))) {
+            //     // NewExpInfoHelper.flagId   647
+            //     result = ThresholdModelContainer.
+            //             getThresholdPredictModel("random")
+            //             .predict(modelParam);
+            // } else if (expCodes.contains("667") ||
+            //         (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+            //                 requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "667", modelParam))) {
+            //     // NewExpInfoHelper.flagId   647
+            //     result = ThresholdModelContainer.
+            //             getThresholdPredictModel("random667")
+            //             .predict(modelParam);
+            // } else if (inExpList(expCodes, adPredictImmersionExpCode)
+            //         ||
+            //         (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+            //                 requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "607", modelParam))) {
+            //     // adPredictImmersionExpCode 607 631
+            //     result = ThresholdModelContainer.
+            //             getThresholdPredictModel("immersion")
+            //             .predict(modelParam);
+            // } else {
+            //     Object thresholdMixFunc = abtestParam.getOrDefault("threshold_mix_func", "basic");
+            //     result = ThresholdModelContainer.
+            //             getThresholdPredictModel(thresholdMixFunc.toString())
+            //             .predict(modelParam);
+            // }
+            // return result;
         } catch (Exception e) {
             log.error("svc=adPredict appType={} group={} newGroup={} pqtId={}"
                     , requestParam.getAppType(), requestParam.getAbTestCode(), requestParam.getNewExpGroup(), requestParam.getPqtId(), e);

+ 3 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/BasicPredict.java

@@ -12,6 +12,8 @@ public abstract class BasicPredict {
 
     public abstract Map<String, Object> predict(PredictContext ctx);
 
+    public abstract String name();
+
     protected Map<String, Object> rtnNoAdPredict(PredictContext ctx) {
         Map<String, Object> rtnMap = new HashMap<>();
         rtnMap.put("ad_predict", 1);
@@ -28,6 +30,7 @@ public abstract class BasicPredict {
         return rtnMap;
     }
 
+
     protected double calcScoreByMid(String mid) {
         int hash = mid.hashCode();
         hash = hash < 0 ? -hash : hash;

+ 10 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/PredictContext.java

@@ -6,6 +6,7 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -76,4 +77,13 @@ public class PredictContext {
     private String userLayer;
 
     private PredictLogParam logParam = new PredictLogParam();
+
+    public String getHandleAfterShareType() {
+        if (StringUtils.isEmpty(shareType)) {
+            return "";
+        }
+        return shareType
+                .replace("return", "")
+                .replace("mids", "");
+    }
 }

+ 177 - 177
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/PredictServiceV2.java

@@ -1,177 +1,177 @@
-package com.tzld.piaoquan.ad.engine.service.predict.v2;
-
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
-import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
-import com.tzld.piaoquan.ad.engine.service.feature.Feature;
-import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.MapUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Slf4j
-@Service
-public class PredictServiceV2 extends BasicPredict {
-
-    @Autowired
-    private FeatureService featureService;
-
-    @ApolloJsonValue("${exp.713.config:{}}")
-    private Map<String, Double> exp713Config;
-
-    @Override
-    public Map<String, Object> predict(PredictContext ctx) {
-        Feature feature = featureService.getPredictFeature(ctx);
-        Map<String, Map<String, String>> userFeature = feature.getUserFeature();
-        Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature_v2", new HashMap<>());
-        double minScore = exp713Config.getOrDefault("minScore", 0.1d);
-        double maxScore = exp713Config.getOrDefault("maxScore", 0.8d);
-        double score = maxScore;
-
-        ctx.getLogParam().setBIsNewUser(true);
-
-        if (MapUtils.isNotEmpty(featureMap)) {
-
-            double adViewCnt = Double.parseDouble(featureMap.getOrDefault("ad_view_cnt", "0"));
-            double adClick = Double.parseDouble(featureMap.getOrDefault("ad_click", "0"));
-            double adConver = Double.parseDouble(featureMap.getOrDefault("ad_conver", "0"));
-            double hasAdClick = Double.parseDouble(featureMap.getOrDefault("has_ad_click", "0"));
-            double hasAdShare = Double.parseDouble(featureMap.getOrDefault("has_ad_share", "0"));
-            double hasAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("has_ad_return_cnt", "0"));
-            double noAdClick = Double.parseDouble(featureMap.getOrDefault("no_ad_click", "0"));
-            double noAdShare = Double.parseDouble(featureMap.getOrDefault("no_ad_share", "0"));
-            double noAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("no_ad_return_cnt", "0"));
-
-            // 计算出回流出广告时的收益
-            double adClickValue = NumUtil.div(adClick, adViewCnt) * NumUtil.log10(adClick);
-            double adConverValue = NumUtil.div(adConver, adViewCnt) * NumUtil.log10(adConver);
-            double hasAdShareValue = NumUtil.div(hasAdShare, hasAdClick) * NumUtil.log10(hasAdShare);
-            double hasAdReturnValue = NumUtil.div(hasAdReturnCnt, hasAdClick) * NumUtil.log10(hasAdReturnCnt);
-            double hasAdValue = adClickValue + adConverValue + hasAdShareValue + hasAdReturnValue;
-
-            // 计算回流不出广告时的收益
-            double noAdShareValue = NumUtil.div(noAdShare, noAdClick) * NumUtil.log10(noAdShare);
-            double noAdReturnValue = NumUtil.div(noAdReturnCnt, noAdClick) * NumUtil.log10(noAdReturnCnt + hasAdReturnCnt);
-            double noAdValue = noAdShareValue + noAdReturnValue;
-
-            // 计算最终的收益
-            double hasRate = exp713Config.getOrDefault("hasRate", 1d);
-            double noRate = exp713Config.getOrDefault("noRate", 1d);
-            score = NumUtil.softmax(new double[]{hasAdValue * hasRate, noAdValue * noRate})[0];
-
-
-            ctx.getLogParam().getMetaFeature().putAll(feature.getUserFeature());
-            for (Map.Entry<String, String> entry : featureMap.entrySet()) {
-                ctx.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
-            }
-            ctx.getLogParam().getScoreMap().put("adClickValue", NumUtil.round(adClickValue, 6));
-            ctx.getLogParam().getScoreMap().put("adConverValue", NumUtil.round(adConverValue, 6));
-            ctx.getLogParam().getScoreMap().put("hasAdShareValue", NumUtil.round(hasAdShareValue, 6));
-            ctx.getLogParam().getScoreMap().put("hasAdReturnValue", NumUtil.round(hasAdReturnValue, 6));
-            ctx.getLogParam().getScoreMap().put("hasAdValue", NumUtil.round(hasAdValue, 6));
-            ctx.getLogParam().getScoreMap().put("noAdShareValue", NumUtil.round(noAdShareValue, 6));
-            ctx.getLogParam().getScoreMap().put("noAdReturnValue", NumUtil.round(noAdReturnValue, 6));
-            ctx.getLogParam().getScoreMap().put("noAdValue", NumUtil.round(noAdValue, 6));
-            ctx.getLogParam().getScoreMap().put("originScore", NumUtil.round(score, 6));
-            ctx.getLogParam().getScoreMap().put("hasRate", NumUtil.round(hasRate, 6));
-            ctx.getLogParam().getScoreMap().put("noRate", NumUtil.round(noRate, 6));
-
-            ctx.getLogParam().setBIsNewUser(false);
-        }
-
-        // 分数截断,避免过长或过短
-        if (score < minScore) {
-            score = minScore;
-        } else if (score > maxScore) {
-            score = maxScore;
-        }
-
-        double random = Math.random();
-        boolean isShowAd = random < score;
-        ctx.getLogParam().setExpId("713");
-        ctx.getLogParam().setScore(score);
-        ctx.getLogParam().getScoreMap().put("score", NumUtil.round(score, 6));
-        ctx.getLogParam().setAIsShowAd(isShowAd);
-        ctx.getLogParam().getScoreMap().put("minScore", minScore);
-        ctx.getLogParam().getScoreMap().put("maxScore", maxScore);
-        ctx.getLogParam().getScoreMap().put("random", random);
-
-
-        return isShowAd ? rtnAdPredict(ctx) : rtnNoAdPredict(ctx);
-    }
-
-
-    // public Map<String, Object> adPredictV1(PredictContext context){
-    //
-    //     Feature feature = featureService.getPredictFeature(context);
-    //     Map<String, Map<String, String>> userFeature = feature.getUserFeature();
-    //     Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature", new HashMap<>());
-    //
-    //     double score = -1;
-    //
-    //     // 没有特征为新用户,随机出广告
-    //     if (MapUtils.isEmpty(featureMap)) {
-    //         double newUserShowAdRate = exp713Config.getOrDefault("newUserShowAdRate", 0.8d);
-    //         double randomRate = Math.random();
-    //         if (randomRate < newUserShowAdRate) {
-    //             context.getLogParam().getScoreMap().put("newUserShowAdRate", newUserShowAdRate);
-    //             context.getLogParam().getScoreMap().put("randomRate", randomRate);
-    //             score = 1;
-    //         }
-    //     } else {
-    //         context.getLogParam().getMetaFeature().putAll(userFeature);
-    //         for (Map.Entry<String, String> entry : featureMap.entrySet()) {
-    //             context.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
-    //         }
-    //
-    //         // 获取需要的特征值
-    //         double showAdClickPv = Double.parseDouble(featureMap.getOrDefault("show_ad_click_pv", "0"));
-    //         double noShowAdClickPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_click_pv", "0"));
-    //         double showAdIncome = Double.parseDouble(featureMap.getOrDefault("show_ad_income", "0"));
-    //         double showAdSharePv = Double.parseDouble(featureMap.getOrDefault("show_ad_share_pv", "0"));
-    //         double noShowAdSharePv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_share_pv", "0"));
-    //         double showAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("show_ad_new_return_pv", "0"));
-    //         double noShowAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_new_return_pv", "0"));
-    //
-    //         // 计算中间过程值
-    //         double singleReturnAdIncome = NumUtil.div(showAdIncome, (showAdClickPv + noShowAdClickPv));
-    //         double showAdShareRate = NumUtil.div((showAdSharePv + 1), (showAdClickPv + 1));
-    //         double noShowAdShareRate = NumUtil.div((noShowAdSharePv + 1), (noShowAdClickPv + 1));
-    //         double returnDivShare = NumUtil.div((showAdNewReturnPv + noShowAdNewReturnPv + 1), (showAdSharePv + noShowAdSharePv + 1));
-    //
-    //         double busDauBalanceRate = exp713Config.getOrDefault("busDauBalanceRate", 0.1d);
-    //         score = singleReturnAdIncome + ((showAdShareRate - noShowAdShareRate) * returnDivShare * busDauBalanceRate);
-    //
-    //
-    //         context.getLogParam().getScoreMap().put("singleReturnAdIncome", singleReturnAdIncome);
-    //         context.getLogParam().getScoreMap().put("showAdShareRate", showAdShareRate);
-    //         context.getLogParam().getScoreMap().put("noShowAdShareRate", noShowAdShareRate);
-    //         context.getLogParam().getScoreMap().put("returnDivShare", returnDivShare);
-    //         context.getLogParam().getScoreMap().put("busDauBalanceRate", busDauBalanceRate);
-    //
-    //     }
-    //     double showAdScoreThreshold = exp713Config.getOrDefault("showAdScoreThreshold", 0d);
-    //     boolean isShowAd = score >= showAdScoreThreshold;
-    //
-    //     context.getLogParam().setAIsShowAd(isShowAd);
-    //     context.getLogParam().setExpId("713");
-    //     context.getLogParam().setScore(score);
-    //     context.getLogParam().getScoreMap().put("score", score);
-    //     context.getLogParam().getScoreMap().put("showAdScoreThreshold", showAdScoreThreshold);
-    //
-    //
-    //     logHubService.crowdChooseLogUpload(context);
-    //
-    //
-    //     if (isShowAd) {
-    //         Map<String, Object> rtnMap = rtnAdPredict();
-    //         rtnMap.putAll(context.getLogParam().getScoreMap());
-    //         return rtnMap;
-    //     } else {
-    //         return rtnNoAdPredict("713_exp");
-    //     }
-    // }
-}
+// package com.tzld.piaoquan.ad.engine.service.predict.v2;
+//
+// import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+// import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
+// import com.tzld.piaoquan.ad.engine.service.feature.Feature;
+// import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
+// import lombok.extern.slf4j.Slf4j;
+// import org.apache.commons.collections4.MapUtils;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.stereotype.Service;
+//
+// import java.util.HashMap;
+// import java.util.Map;
+//
+// @Slf4j
+// @Service
+// public class PredictServiceV2 extends BasicPredict {
+//
+//     @Autowired
+//     private FeatureService featureService;
+//
+//     @ApolloJsonValue("${exp.713.config:{}}")
+//     private Map<String, Double> exp713Config;
+//
+//     @Override
+//     public Map<String, Object> predict(PredictContext ctx) {
+//         Feature feature = featureService.getPredictFeature(ctx);
+//         Map<String, Map<String, String>> userFeature = feature.getUserFeature();
+//         Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature_v2", new HashMap<>());
+//         double minScore = exp713Config.getOrDefault("minScore", 0.1d);
+//         double maxScore = exp713Config.getOrDefault("maxScore", 0.8d);
+//         double score = maxScore;
+//
+//         ctx.getLogParam().setBIsNewUser(true);
+//
+//         if (MapUtils.isNotEmpty(featureMap)) {
+//
+//             double adViewCnt = Double.parseDouble(featureMap.getOrDefault("ad_view_cnt", "0"));
+//             double adClick = Double.parseDouble(featureMap.getOrDefault("ad_click", "0"));
+//             double adConver = Double.parseDouble(featureMap.getOrDefault("ad_conver", "0"));
+//             double hasAdClick = Double.parseDouble(featureMap.getOrDefault("has_ad_click", "0"));
+//             double hasAdShare = Double.parseDouble(featureMap.getOrDefault("has_ad_share", "0"));
+//             double hasAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("has_ad_return_cnt", "0"));
+//             double noAdClick = Double.parseDouble(featureMap.getOrDefault("no_ad_click", "0"));
+//             double noAdShare = Double.parseDouble(featureMap.getOrDefault("no_ad_share", "0"));
+//             double noAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("no_ad_return_cnt", "0"));
+//
+//             // 计算出回流出广告时的收益
+//             double adClickValue = NumUtil.div(adClick, adViewCnt) * NumUtil.log10(adClick);
+//             double adConverValue = NumUtil.div(adConver, adViewCnt) * NumUtil.log10(adConver);
+//             double hasAdShareValue = NumUtil.div(hasAdShare, hasAdClick) * NumUtil.log10(hasAdShare);
+//             double hasAdReturnValue = NumUtil.div(hasAdReturnCnt, hasAdClick) * NumUtil.log10(hasAdReturnCnt);
+//             double hasAdValue = adClickValue + adConverValue + hasAdShareValue + hasAdReturnValue;
+//
+//             // 计算回流不出广告时的收益
+//             double noAdShareValue = NumUtil.div(noAdShare, noAdClick) * NumUtil.log10(noAdShare);
+//             double noAdReturnValue = NumUtil.div(noAdReturnCnt, noAdClick) * NumUtil.log10(noAdReturnCnt + hasAdReturnCnt);
+//             double noAdValue = noAdShareValue + noAdReturnValue;
+//
+//             // 计算最终的收益
+//             double hasRate = exp713Config.getOrDefault("hasRate", 1d);
+//             double noRate = exp713Config.getOrDefault("noRate", 1d);
+//             score = NumUtil.softmax(new double[]{hasAdValue * hasRate, noAdValue * noRate})[0];
+//
+//
+//             ctx.getLogParam().getMetaFeature().putAll(feature.getUserFeature());
+//             for (Map.Entry<String, String> entry : featureMap.entrySet()) {
+//                 ctx.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
+//             }
+//             ctx.getLogParam().getScoreMap().put("adClickValue", NumUtil.round(adClickValue, 6));
+//             ctx.getLogParam().getScoreMap().put("adConverValue", NumUtil.round(adConverValue, 6));
+//             ctx.getLogParam().getScoreMap().put("hasAdShareValue", NumUtil.round(hasAdShareValue, 6));
+//             ctx.getLogParam().getScoreMap().put("hasAdReturnValue", NumUtil.round(hasAdReturnValue, 6));
+//             ctx.getLogParam().getScoreMap().put("hasAdValue", NumUtil.round(hasAdValue, 6));
+//             ctx.getLogParam().getScoreMap().put("noAdShareValue", NumUtil.round(noAdShareValue, 6));
+//             ctx.getLogParam().getScoreMap().put("noAdReturnValue", NumUtil.round(noAdReturnValue, 6));
+//             ctx.getLogParam().getScoreMap().put("noAdValue", NumUtil.round(noAdValue, 6));
+//             ctx.getLogParam().getScoreMap().put("originScore", NumUtil.round(score, 6));
+//             ctx.getLogParam().getScoreMap().put("hasRate", NumUtil.round(hasRate, 6));
+//             ctx.getLogParam().getScoreMap().put("noRate", NumUtil.round(noRate, 6));
+//
+//             ctx.getLogParam().setBIsNewUser(false);
+//         }
+//
+//         // 分数截断,避免过长或过短
+//         if (score < minScore) {
+//             score = minScore;
+//         } else if (score > maxScore) {
+//             score = maxScore;
+//         }
+//
+//         double random = Math.random();
+//         boolean isShowAd = random < score;
+//         ctx.getLogParam().setExpId("713");
+//         ctx.getLogParam().setScore(score);
+//         ctx.getLogParam().getScoreMap().put("score", NumUtil.round(score, 6));
+//         ctx.getLogParam().setAIsShowAd(isShowAd);
+//         ctx.getLogParam().getScoreMap().put("minScore", minScore);
+//         ctx.getLogParam().getScoreMap().put("maxScore", maxScore);
+//         ctx.getLogParam().getScoreMap().put("random", random);
+//
+//
+//         return isShowAd ? rtnAdPredict(ctx) : rtnNoAdPredict(ctx);
+//     }
+//
+//
+//     // public Map<String, Object> adPredictV1(PredictContext context){
+//     //
+//     //     Feature feature = featureService.getPredictFeature(context);
+//     //     Map<String, Map<String, String>> userFeature = feature.getUserFeature();
+//     //     Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature", new HashMap<>());
+//     //
+//     //     double score = -1;
+//     //
+//     //     // 没有特征为新用户,随机出广告
+//     //     if (MapUtils.isEmpty(featureMap)) {
+//     //         double newUserShowAdRate = exp713Config.getOrDefault("newUserShowAdRate", 0.8d);
+//     //         double randomRate = Math.random();
+//     //         if (randomRate < newUserShowAdRate) {
+//     //             context.getLogParam().getScoreMap().put("newUserShowAdRate", newUserShowAdRate);
+//     //             context.getLogParam().getScoreMap().put("randomRate", randomRate);
+//     //             score = 1;
+//     //         }
+//     //     } else {
+//     //         context.getLogParam().getMetaFeature().putAll(userFeature);
+//     //         for (Map.Entry<String, String> entry : featureMap.entrySet()) {
+//     //             context.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
+//     //         }
+//     //
+//     //         // 获取需要的特征值
+//     //         double showAdClickPv = Double.parseDouble(featureMap.getOrDefault("show_ad_click_pv", "0"));
+//     //         double noShowAdClickPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_click_pv", "0"));
+//     //         double showAdIncome = Double.parseDouble(featureMap.getOrDefault("show_ad_income", "0"));
+//     //         double showAdSharePv = Double.parseDouble(featureMap.getOrDefault("show_ad_share_pv", "0"));
+//     //         double noShowAdSharePv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_share_pv", "0"));
+//     //         double showAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("show_ad_new_return_pv", "0"));
+//     //         double noShowAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_new_return_pv", "0"));
+//     //
+//     //         // 计算中间过程值
+//     //         double singleReturnAdIncome = NumUtil.div(showAdIncome, (showAdClickPv + noShowAdClickPv));
+//     //         double showAdShareRate = NumUtil.div((showAdSharePv + 1), (showAdClickPv + 1));
+//     //         double noShowAdShareRate = NumUtil.div((noShowAdSharePv + 1), (noShowAdClickPv + 1));
+//     //         double returnDivShare = NumUtil.div((showAdNewReturnPv + noShowAdNewReturnPv + 1), (showAdSharePv + noShowAdSharePv + 1));
+//     //
+//     //         double busDauBalanceRate = exp713Config.getOrDefault("busDauBalanceRate", 0.1d);
+//     //         score = singleReturnAdIncome + ((showAdShareRate - noShowAdShareRate) * returnDivShare * busDauBalanceRate);
+//     //
+//     //
+//     //         context.getLogParam().getScoreMap().put("singleReturnAdIncome", singleReturnAdIncome);
+//     //         context.getLogParam().getScoreMap().put("showAdShareRate", showAdShareRate);
+//     //         context.getLogParam().getScoreMap().put("noShowAdShareRate", noShowAdShareRate);
+//     //         context.getLogParam().getScoreMap().put("returnDivShare", returnDivShare);
+//     //         context.getLogParam().getScoreMap().put("busDauBalanceRate", busDauBalanceRate);
+//     //
+//     //     }
+//     //     double showAdScoreThreshold = exp713Config.getOrDefault("showAdScoreThreshold", 0d);
+//     //     boolean isShowAd = score >= showAdScoreThreshold;
+//     //
+//     //     context.getLogParam().setAIsShowAd(isShowAd);
+//     //     context.getLogParam().setExpId("713");
+//     //     context.getLogParam().setScore(score);
+//     //     context.getLogParam().getScoreMap().put("score", score);
+//     //     context.getLogParam().getScoreMap().put("showAdScoreThreshold", showAdScoreThreshold);
+//     //
+//     //
+//     //     logHubService.crowdChooseLogUpload(context);
+//     //
+//     //
+//     //     if (isShowAd) {
+//     //         Map<String, Object> rtnMap = rtnAdPredict();
+//     //         rtnMap.putAll(context.getLogParam().getScoreMap());
+//     //         return rtnMap;
+//     //     } else {
+//     //         return rtnNoAdPredict("713_exp");
+//     //     }
+//     // }
+// }

+ 43 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/PredictStrategyBy599.java

@@ -0,0 +1,43 @@
+package com.tzld.piaoquan.ad.engine.service.predict.v2;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+public class PredictStrategyBy599 extends ThresholdPredictStrategy {
+    @Override
+    Map<String, Double> thresholdConfig(PredictContext ctx) {
+        try {
+            JSONObject json = ctx.getExpConfigMap().getOrDefault("599", new JSONObject());
+            return json.toJavaObject(new TypeReference<Map<String, Double>>() {
+            });
+        } catch (Exception e) {
+            log.error("PredictStrategyBy599 parse 599 exp param error \n", e);
+            return Collections.emptyMap();
+        }
+    }
+
+    @Override
+    List<String> genThresholdKeys(PredictContext ctx) {
+
+        List<String> keys = new ArrayList<>();
+        for (String appType : Arrays.asList(ctx.getAppType(), "default")) {
+            for (String userLayer : Arrays.asList(ctx.getUserLayer(), "default")) {
+                keys.add(String.join("_", appType, userLayer, ctx.getHandleAfterShareType()));
+            }
+        }
+        keys.add("default_threshold");
+        return keys;
+    }
+
+    @Override
+    public String name() {
+        return "599";
+    }
+
+}

+ 42 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/PredictStrategyBy667.java

@@ -0,0 +1,42 @@
+package com.tzld.piaoquan.ad.engine.service.predict.v2;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+public class PredictStrategyBy667 extends ThresholdPredictStrategy {
+    @Override
+    Map<String, Double> thresholdConfig(PredictContext ctx) {
+        try {
+            JSONObject json = ctx.getExpConfigMap().getOrDefault("667", new JSONObject());
+            return json.toJavaObject(new TypeReference<Map<String, Double>>() {
+            });
+        } catch (Exception e) {
+            log.error("PredictStrategyBy667 parse 667 exp param error \n", e);
+            return Collections.emptyMap();
+        }
+    }
+
+    @Override
+    List<String> genThresholdKeys(PredictContext ctx) {
+        List<String> keys = new ArrayList<>();
+        for (String appType : Arrays.asList(ctx.getAppType(), "default")) {
+            for (String userLayer : Arrays.asList(ctx.getUserLayer(), "default")) {
+                keys.add(String.join("_", appType, userLayer, ctx.getHandleAfterShareType()));
+            }
+        }
+        keys.add("default_threshold");
+        return keys;
+    }
+
+    @Override
+    public String name() {
+        return "667";
+    }
+
+}

+ 98 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/PredictStrategyBy673.java

@@ -0,0 +1,98 @@
+package com.tzld.piaoquan.ad.engine.service.predict.v2;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+public class PredictStrategyBy673 extends ThresholdPredictStrategy {
+    @Override
+    Map<String, Double> thresholdConfig(PredictContext ctx) {
+
+        if (StringUtils.isAnyBlank(ctx.getUserExternalSource(), ctx.getShareLayer())) {
+            return Collections.emptyMap();
+        }
+
+        try {
+            JSONObject json = ctx.getExpConfigMap().getOrDefault("673", new JSONObject());
+            JSONObject configJson = json.getJSONObject(String.format("%s:%s", ctx.getUserExternalSource(), ctx.getShareLayer()));
+            return configJson.toJavaObject(new TypeReference<Map<String, Double>>() {
+            });
+        } catch (Exception e) {
+            log.error("PredictStrategyBy673 parse 673 exp param error \n", e);
+            return Collections.emptyMap();
+        }
+    }
+
+    @Override
+    public Map<String, Object> predict(PredictContext ctx) {
+        Map<String, Double> thresholdConfig = this.thresholdConfig(ctx);
+        if (MapUtils.isEmpty(thresholdConfig)) {
+            return null;
+        }
+        double score = this.calcScoreByMid(ctx.getMid());
+
+        List<String> thresholdKeys = genThresholdKeys(ctx);
+        if (CollectionUtils.isEmpty(thresholdKeys)) {
+            return null;
+        }
+
+        String finalThresholdKeys = "";
+        double threshold = 0d;
+
+        for (String thresholdKey : thresholdKeys) {
+            if (thresholdConfig.containsKey(thresholdKey)) {
+                finalThresholdKeys = thresholdKey;
+                threshold = thresholdConfig.get(thresholdKey);
+                break;
+            }
+        }
+
+        Map<String, Object> rtnMap = new HashMap<>();
+        if (score < threshold) {
+            rtnMap.putAll(rtnAdPredict(ctx));
+            rtnMap.put("model", this.name());
+        } else {
+            rtnMap.putAll(rtnNoAdPredict(ctx));
+            rtnMap.put("no_ad_strategy", this.name());
+        }
+
+        rtnMap.put("score", score);
+        rtnMap.put("threshold", threshold);
+        rtnMap.put("userLayer", ctx.getUserLayer());
+        rtnMap.put("thresholdParamKey", finalThresholdKeys);
+        rtnMap.put("shareType", ctx.getHandleAfterShareType());
+
+        this.printLog(rtnMap, ctx, thresholdConfig);
+
+        return rtnMap;
+
+    }
+
+
+    @Override
+    List<String> genThresholdKeys(PredictContext ctx) {
+
+        List<String> keys = new ArrayList<>();
+        for (String appType : Arrays.asList(ctx.getAppType(), "default")) {
+            for (String userLayer : Arrays.asList(ctx.getUserLayer(), "default")) {
+                keys.add(String.join("_", appType, userLayer, ctx.getHandleAfterShareType()));
+            }
+        }
+        keys.add("default_threshold");
+        return keys;
+    }
+
+    @Override
+    public String name() {
+        return "673";
+    }
+
+}

+ 86 - 86
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/RootSessionIdPredict.java

@@ -1,86 +1,86 @@
-package com.tzld.piaoquan.ad.engine.service.predict.v2;
-
-import com.alibaba.fastjson.JSONObject;
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
-import com.tzld.piaoquan.ad.engine.commons.util.JSONUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Slf4j
-@Component
-public class RootSessionIdPredict extends BasicPredict {
-
-    @ApolloJsonValue("${root.session.id.tail.predict.config:[]}")
-    private List<RootSessionIdTailConfigItem> configItems;
-
-    @Override
-    public Map<String, Object> predict(PredictContext ctx) {
-        String rootSessionId = ctx.getRootSessionId();
-        if (CollectionUtils.isEmpty(configItems) || StringUtils.isEmpty(rootSessionId) || StringUtils.isEmpty(ctx.getShareType())) {
-            return Collections.emptyMap();
-        }
-
-
-        double score = this.calcScoreByMid(ctx.getMid());
-
-        String appType = ctx.getAppType();
-        String tail = rootSessionId.substring(rootSessionId.length() - 1);
-        String shareType = ctx.getShareType()
-                .replace("return", "")
-                .replace("mids", "");
-
-
-        for (RootSessionIdTailConfigItem item : configItems) {
-            if (item.getAppType().contains(appType) && item.getTail().contains(tail)) {
-                double threshold;
-                if (item.getConfig().containsKey(shareType)) {
-                    threshold = item.getConfig().getOrDefault(shareType, 0d);
-                } else {
-                    threshold = item.getConfig().getOrDefault("threshold", 0d);
-                }
-
-                Map<String, Object> returnMap = new HashMap<>();
-
-                if (score < threshold) {
-                    returnMap.putAll(rtnAdPredict(ctx));
-                    returnMap.put("model", "rootSessionIdTailModel");
-                } else {
-                    returnMap.putAll(rtnNoAdPredict(ctx));
-                    returnMap.put("no_ad_strategy", "rootSessionIdTailModel");
-                }
-
-                returnMap.put("score", score);
-                returnMap.put("threshold", threshold);
-
-                JSONObject logJson = new JSONObject();
-                logJson.putAll(returnMap);
-                logJson.put("mid", ctx.getMid());
-                logJson.put("appType", appType);
-                logJson.put("rootSessionIdTail", tail);
-                logJson.put("shareType", shareType);
-
-                logJson.put("expId", "rootSessionIdTailExp");
-                logJson.put("thresholdParamKey", shareType);
-                logJson.put("adPlatformType", ctx.getAdPlatformType());
-                logJson.put("abCode", ctx.getAdAbCode());
-                logJson.put("extraParam", ctx.getExpConfigMap());
-                logJson.put("configItem", item);
-                logJson.put("rootSessionId", ctx.getRootSessionId());
-
-                log.info("广告跳出选择 -- rootSessionId尾号实验结果: {}, 参数: {}",
-                        JSONUtils.toJson(returnMap), logJson.toJSONString());
-
-                return returnMap;
-            }
-        }
-
-        return Collections.emptyMap();
-    }
-}
+// package com.tzld.piaoquan.ad.engine.service.predict.v2;
+//
+// import com.alibaba.fastjson.JSONObject;
+// import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+// import com.tzld.piaoquan.ad.engine.commons.util.JSONUtils;
+// import lombok.extern.slf4j.Slf4j;
+// import org.apache.commons.collections4.CollectionUtils;
+// import org.apache.commons.lang3.StringUtils;
+// import org.springframework.stereotype.Component;
+//
+// import java.util.Collections;
+// import java.util.HashMap;
+// import java.util.List;
+// import java.util.Map;
+//
+// @Slf4j
+// @Component
+// public class RootSessionIdPredict extends BasicPredict {
+//
+//     @ApolloJsonValue("${root.session.id.tail.predict.config:[]}")
+//     private List<RootSessionIdTailConfigItem> configItems;
+//
+//     @Override
+//     public Map<String, Object> predict(PredictContext ctx) {
+//         String rootSessionId = ctx.getRootSessionId();
+//         if (CollectionUtils.isEmpty(configItems) || StringUtils.isEmpty(rootSessionId) || StringUtils.isEmpty(ctx.getShareType())) {
+//             return Collections.emptyMap();
+//         }
+//
+//
+//         double score = this.calcScoreByMid(ctx.getMid());
+//
+//         String appType = ctx.getAppType();
+//         String tail = rootSessionId.substring(rootSessionId.length() - 1);
+//         String shareType = ctx.getShareType()
+//                 .replace("return", "")
+//                 .replace("mids", "");
+//
+//
+//         for (RootSessionIdTailConfigItem item : configItems) {
+//             if (item.getAppType().contains(appType) && item.getTail().contains(tail)) {
+//                 double threshold;
+//                 if (item.getConfig().containsKey(shareType)) {
+//                     threshold = item.getConfig().getOrDefault(shareType, 0d);
+//                 } else {
+//                     threshold = item.getConfig().getOrDefault("threshold", 0d);
+//                 }
+//
+//                 Map<String, Object> returnMap = new HashMap<>();
+//
+//                 if (score < threshold) {
+//                     returnMap.putAll(rtnAdPredict(ctx));
+//                     returnMap.put("model", "rootSessionIdTailModel");
+//                 } else {
+//                     returnMap.putAll(rtnNoAdPredict(ctx));
+//                     returnMap.put("no_ad_strategy", "rootSessionIdTailModel");
+//                 }
+//
+//                 returnMap.put("score", score);
+//                 returnMap.put("threshold", threshold);
+//
+//                 JSONObject logJson = new JSONObject();
+//                 logJson.putAll(returnMap);
+//                 logJson.put("mid", ctx.getMid());
+//                 logJson.put("appType", appType);
+//                 logJson.put("rootSessionIdTail", tail);
+//                 logJson.put("shareType", shareType);
+//
+//                 logJson.put("expId", "rootSessionIdTailExp");
+//                 logJson.put("thresholdParamKey", shareType);
+//                 logJson.put("adPlatformType", ctx.getAdPlatformType());
+//                 logJson.put("abCode", ctx.getAdAbCode());
+//                 logJson.put("extraParam", ctx.getExpConfigMap());
+//                 logJson.put("configItem", item);
+//                 logJson.put("rootSessionId", ctx.getRootSessionId());
+//
+//                 log.info("广告跳出选择 -- rootSessionId尾号实验结果: {}, 参数: {}",
+//                         JSONUtils.toJson(returnMap), logJson.toJSONString());
+//
+//                 return returnMap;
+//             }
+//         }
+//
+//         return Collections.emptyMap();
+//     }
+// }

+ 74 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/ThresholdPredictStrategy.java

@@ -0,0 +1,74 @@
+package com.tzld.piaoquan.ad.engine.service.predict.v2;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.ad.engine.commons.util.JSONUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public abstract class ThresholdPredictStrategy extends BasicPredict {
+
+    abstract Map<String, Double> thresholdConfig(PredictContext ctx);
+
+    abstract List<String> genThresholdKeys(PredictContext ctx);
+
+    @Override
+    public Map<String, Object> predict(PredictContext ctx) {
+        Map<String, Double> thresholdConfig = this.thresholdConfig(ctx);
+
+        double score = this.calcScoreByMid(ctx.getMid());
+
+        List<String> thresholdKeys = genThresholdKeys(ctx);
+
+        String finalThresholdKeys = "";
+        double threshold = 0d;
+
+        for (String thresholdKey : thresholdKeys) {
+            if (thresholdConfig.containsKey(thresholdKey)) {
+                finalThresholdKeys = thresholdKey;
+                threshold = thresholdConfig.get(thresholdKey);
+                break;
+            }
+        }
+
+        Map<String, Object> rtnMap = new HashMap<>();
+        if (score < threshold) {
+            rtnMap.putAll(rtnAdPredict(ctx));
+            rtnMap.put("model", this.name());
+        } else {
+            rtnMap.putAll(rtnNoAdPredict(ctx));
+            rtnMap.put("no_ad_strategy", this.name());
+        }
+
+        rtnMap.put("score", score);
+        rtnMap.put("threshold", threshold);
+        rtnMap.put("userLayer", ctx.getUserLayer());
+        rtnMap.put("thresholdParamKey", finalThresholdKeys);
+        rtnMap.put("shareType", ctx.getHandleAfterShareType());
+
+        this.printLog(rtnMap, ctx, thresholdConfig);
+
+        return rtnMap;
+
+    }
+
+    protected void printLog(Map<String, Object> rtnMap, PredictContext ctx, Map<String, Double> thresholdConfig) {
+        JSONObject logJson = new JSONObject();
+        logJson.putAll(rtnMap);
+        logJson.put("mid", ctx.getMid());
+        logJson.put("appType", ctx.getAppType());
+
+        logJson.put("expId", this.name());
+        logJson.put("adPlatformType", ctx.getAdPlatformType());
+        logJson.put("abCode", ctx.getAdAbCode());
+        logJson.put("configItem", thresholdConfig);
+        logJson.put("rootSessionId", ctx.getRootSessionId());
+
+        log.info("广告跳出选择 -- {}实验结果: {}, 参数: {}",
+                this.name(), JSONUtils.toJson(rtnMap), logJson.toJSONString());
+    }
+}

+ 7 - 7
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/v2/UserLayerRootSessionIdPredict.java

@@ -3,11 +3,9 @@ package com.tzld.piaoquan.ad.engine.service.predict.v2;
 import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.ad.engine.commons.util.JSONUtils;
-import com.tzld.piaoquan.ad.engine.service.user.UserService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.*;
@@ -16,9 +14,6 @@ import java.util.*;
 @Component
 public class UserLayerRootSessionIdPredict extends BasicPredict {
 
-    @Autowired
-    private UserService userService;
-
     @ApolloJsonValue("${user.layer.root.session.id.tail.predict.config:[]}")
     private List<RootSessionIdTailConfigItem> configItems;
 
@@ -59,10 +54,10 @@ public class UserLayerRootSessionIdPredict extends BasicPredict {
 
                 if (score < threshold) {
                     returnMap.putAll(rtnAdPredict(ctx));
-                    returnMap.put("model", "userLayerRootSessionIdTailModel");
+                    returnMap.put("model", this.name());
                 } else {
                     returnMap.putAll(rtnNoAdPredict(ctx));
-                    returnMap.put("no_ad_strategy", "userLayerRootSessionIdTailModel");
+                    returnMap.put("no_ad_strategy", this.name());
                 }
 
                 returnMap.put("score", score);
@@ -93,4 +88,9 @@ public class UserLayerRootSessionIdPredict extends BasicPredict {
 
         return Collections.emptyMap();
     }
+
+    @Override
+    public String name() {
+        return "userLayerRootSessionIdTailModel";
+    }
 }