浏览代码

Merge branch 'feature_break' of algorithm/ad-engine into master

dingyunpeng 1 年之前
父节点
当前提交
9d8d63895d
共有 21 个文件被更改,包括 597 次插入82 次删除
  1. 20 0
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/AdConfig.java
  2. 7 0
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScoreParam.java
  3. 4 3
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScorerUtils.java
  4. 2 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/ModelManager.java
  5. 6 0
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/ThompsonSamplingModel.java
  6. 3 1
      ad-engine-server/src/main/java/com/tzld/piaoquan/ad/engine/server/Application.java
  7. 2 0
      ad-engine-server/src/main/resources/application.yml
  8. 25 0
      ad-engine-server/src/main/resources/feeds_score_config_break.conf
  9. 159 49
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/impl/PredictModelServiceImpl.java
  10. 1 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreThresholdPredictModel.java
  11. 100 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreV2ThresholdPredictModel.java
  12. 19 14
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/ThresholdPredictModelParam.java
  13. 10 6
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/request/ThresholdPredictModelRequestParam.java
  14. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/remote/FeatureRemoteService.java
  15. 42 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/remote/ModelRemoteService.java
  16. 23 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/ServiceBeanFactory.java
  17. 70 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdBreakScorer.java
  18. 42 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdRosAndStrScorer.java
  19. 58 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogMergeBreakScorer.java
  20. 2 4
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceImpl.java
  21. 1 3
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceThompsonImpl.java

+ 20 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/AdConfig.java

@@ -0,0 +1,20 @@
+package com.tzld.piaoquan.ad.engine.commons.score;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author dyp
+ */
+
+public class AdConfig {
+    private static List<Long> adIds;
+
+    public static List<Long> getAdIds() {
+        return adIds;
+    }
+
+    public static void setAdIds(List<Long> adIds) {
+        AdConfig.adIds = Collections.unmodifiableList(adIds);
+    }
+}

+ 7 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScoreParam.java

@@ -10,5 +10,12 @@ import lombok.Data;
 public class ScoreParam {
     private AdRequestContext requestContext;
 
+    private Long videoId;
+    private String mid;
+    private String uid;
+    private String city;
+    private String province;
+
+
 }
 

+ 4 - 3
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScorerUtils.java

@@ -6,12 +6,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.core.SpringProperties;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 
 
@@ -25,11 +23,14 @@ public final class ScorerUtils {
 
     public static String THOMPSON_CONF = "feeds_score_config_thompson.conf";
 
+    public static String BREAK_CONFIG = "feeds_score_config_break.conf";
+
 
     public static void warmUp() {
         log.info("scorer warm up ");
         ScorerUtils.init(BASE_CONF);
         ScorerUtils.init(THOMPSON_CONF);
+        ScorerUtils.init(BREAK_CONFIG);
 
     }
 
@@ -153,7 +154,7 @@ public final class ScorerUtils {
     }
 
 
-    public static void main(String[] args){
+    public static void main(String[] args) {
         ScorerUtils.init(BASE_CONF);
     }
 }

+ 2 - 1
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/ModelManager.java

@@ -85,8 +85,9 @@ public class ModelManager {
      */
     public void registerModel(String modelName, String path, Class<? extends Model> modelClass) throws ModelRegisterException, IOException {
         if (modelPathMap.containsKey(modelName)) {
+            return;
             // fail fast
-            throw new RuntimeException(modelName + " already exists");
+            // throw new RuntimeException(modelName + " already exists");
 //            String oldPath = modelPathMap.get(modelName);
 //            if (path.equals(oldPath)) {
 //                //如果模型的path没有发生改变, 不做任何操作

+ 6 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/ThompsonSamplingModel.java

@@ -1,5 +1,6 @@
 package com.tzld.piaoquan.ad.engine.commons.score.model;
 
+import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdActionFeature;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.model.sample.BaseFeature;
@@ -7,6 +8,7 @@ import com.tzld.piaoquan.recommend.feature.model.sample.GroupedFeature;
 import com.tzld.piaoquan.recommend.feature.model.sample.LRSamples;
 import it.unimi.dsi.fastutil.longs.Long2FloatMap;
 import it.unimi.dsi.fastutil.longs.Long2FloatOpenHashMap;
+import org.apache.commons.lang.math.NumberUtils;
 import org.apache.commons.math3.distribution.BetaDistribution;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,13 +59,17 @@ public class ThompsonSamplingModel extends Model {
         BufferedReader input = new BufferedReader(in);
         String line = null;
         int cnt = 0;
+        List<Long> adIds = new ArrayList<>();
         while ((line = input.readLine()) != null) {
             String[] items = line.split("\t");
             if (items.length < 3) {
                 continue;
             }
+            adIds.add(NumberUtils.toLong(items[0].trim(), 0));
             putFeature(initModel, new BigInteger(items[0].trim()).longValue(), Double.valueOf(items[1].trim()).doubleValue(), Double.valueOf(items[2].trim()).doubleValue(), Double.valueOf(items[3].trim()).doubleValue());
         }
+        // hardcode modelPath 不能重复,所以这里直接赋值
+        AdConfig.setAdIds(adIds);
 
         this.thompsonSamplingModel = initModel;
         LOGGER.info("[MODELLOAD] model load over and size " + cnt);

+ 3 - 1
ad-engine-server/src/main/java/com/tzld/piaoquan/ad/engine/server/Application.java

@@ -20,7 +20,9 @@ import org.springframework.scheduling.annotation.EnableScheduling;
  */
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,SecurityAutoConfiguration.class})
 @ComponentScan({
-        "com.tzld.piaoquan.ad.engine.*","com.tzld.piaoquan.recommend.feature.*"
+        "com.tzld.piaoquan.ad.engine.*",
+        "com.tzld.piaoquan.recommend.feature.*",
+        "com.tzld.piaoquan.recommend.server.*"
 })
 @EnableEurekaClient
 @EnableAspectJAutoProxy

+ 2 - 0
ad-engine-server/src/main/resources/application.yml

@@ -123,4 +123,6 @@ xxl:
 grpc:
   client:
     recommend-feature:
+      negotiationType: PLAINTEXT
+    recommend-server:
       negotiationType: PLAINTEXT

+ 25 - 0
ad-engine-server/src/main/resources/feeds_score_config_break.conf

@@ -0,0 +1,25 @@
+scorer-config = {
+  lr-ctr-score-config = {
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogAdCtrLRScorer"
+    scorer-priority = 99
+    model-path = "ad_ctr_model/model_ad_ctr.txt"
+  }
+  lr-cvr-score-config = {
+      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogAdCvrLRScorer"
+      scorer-priority = 98
+      model-path = "ad_cvr_model/model_ad_cvr.txt"
+  }
+  str-ros-score-config = {
+      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogAdRosAndStrScorer"
+      scorer-priority = 97
+  }
+  break-score-config = {
+      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogAdBreakScorer"
+      scorer-priority = 96
+  }
+  break-merge-config = {
+      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogMergeBreakScorer"
+      scorer-priority = 1
+  }
+
+}

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

@@ -5,15 +5,14 @@ import com.alibaba.fastjson.JSONObject;
 import com.tzld.piaoquan.ad.engine.commons.enums.AppTypeEnum;
 import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
-import com.tzld.piaoquan.ad.engine.service.predict.config.RoiModelConfig;
-import com.tzld.piaoquan.ad.engine.service.predict.constant.RuleRedisKeyConst;
 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.RoiModelConfig;
+import com.tzld.piaoquan.ad.engine.service.predict.constant.RuleRedisKeyConst;
 import com.tzld.piaoquan.ad.engine.service.predict.container.AbTestConfigContainer;
 import com.tzld.piaoquan.ad.engine.service.predict.container.ThresholdModelContainer;
 import com.tzld.piaoquan.ad.engine.service.predict.container.TopOneVideoContainer;
 import com.tzld.piaoquan.ad.engine.service.predict.param.RoiThresholdPredictModelParam;
-import com.tzld.piaoquan.ad.engine.service.predict.param.RuleParamHelper;
 import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
 import com.tzld.piaoquan.ad.engine.service.predict.param.request.RoiPredictModelRequestParam;
 import com.tzld.piaoquan.ad.engine.service.predict.param.request.ThresholdPredictModelRequestParam;
@@ -24,7 +23,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Service
 public class PredictModelServiceImpl implements PredictModelService {
@@ -47,50 +49,159 @@ public class PredictModelServiceImpl implements PredictModelService {
     @Autowired
     RoiModelConfig roiModelConfig;
 
-    public  Map<String,Object> adPredict(ThresholdPredictModelRequestParam requestParam){
+    @Value("${ad.predict.break.switch:false}")
+    private boolean adPredictBreakSwitch;
 
-        JSONObject object=requestParam.getAbExpInfo();
+    public Map<String, Object> adPredict(ThresholdPredictModelRequestParam requestParam) {
+        if (adPredictBreakSwitch) {
+            return adPredictNew(requestParam);
+        } else {
+            return adPredictOld(requestParam);
+        }
+    }
+
+    public Map<String, Object> adPredictNew(ThresholdPredictModelRequestParam requestParam) {
+        JSONObject object = requestParam.getAbExpInfo();
         //先判断是否开启实验 和是否不出广告时间 而后判断默认0-8
-        Map<String,Object> result=new HashMap<>();
-        int hourOfDay= DateUtils.getCurrentHour();
-        Boolean condition1=abTestConfigContainer.inAdTimeTest(requestParam.getAbExpInfo());
-        Boolean condition2=abTestConfigContainer.containsCode(requestParam.getAbTestCode());
-        if(condition1
+        Map<String, Object> result = new HashMap<>();
+        int hourOfDay = DateUtils.getCurrentHour();
+        Boolean condition1 = abTestConfigContainer.inAdTimeTest(requestParam.getAbExpInfo());
+        Boolean condition2 = abTestConfigContainer.containsCode(requestParam.getAbTestCode());
+        if (condition1
                 &&
                 condition2
                 &&
-                abTestConfigContainer.inWithoutAdTime(requestParam.getAbTestCode(),hourOfDay)){
+                abTestConfigContainer.inWithoutAdTime(requestParam.getAbTestCode(), hourOfDay)) {
+            result.put("ad_predict", 1);
+            result.put("no_ad_strategy", "no_ad_time_with_time_plan");
+            return result;
+        } else if (
+                (!condition1 || (condition1 && !condition2))
+                        &&
+                        (0 <= hourOfDay && hourOfDay < 8)) {
             result.put("ad_predict", 1);
-            result.put("no_ad_strategy","no_ad_time_with_time_plan");
+            result.put("no_ad_strategy", "no_ad_time_with_fixed_time");
             return result;
-        }else  if(
-                (!condition1 ||(condition1&&!condition2))
+        }
+
+
+        String[] abParamArr = abConfig.getAbParams(requestParam.getAbTestCode(), requestParam.getAbExpInfo());
+        if (abParamArr == null) {
+            result.put("msg", "abConfig_error");
+            return result;
+        }
+        String abtestId = abParamArr[0];
+        String abTestConfigTag = abParamArr[1];
+
+        HashMap<String, Map<String, Object>> abConfigMap = abConfig.getAbConfigMap();
+        Map<String, Object> abtestParam = abConfigMap.getOrDefault(abtestId + "-" + abTestConfigTag, null);
+        if (abtestParam == null) {
+            result.put("msg", "abConfig_error");
+            return result;
+        }
+        //市-中文
+        requestParam.setRegion(requestParam.getRegion().replace("省", ""));
+        requestParam.setCity(requestParam.getCity().replace("市", ""));
+
+
+        // Determine the group to which mid belongs
+        String groupClassKey = (String) abtestParam.get("group_class_key");
+        String midGroupKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_MID_GROUP + groupClassKey + ":" + requestParam.getMid();
+        String midGroup = redisHelper.getString(midGroupKeyName);
+        if (midGroup == null) {
+            midGroup = "mean_group";
+        }
+
+        String[] noAdMidGroupList = new String[0];
+        noAdMidGroupList = ((JSONArray) abtestParam.get("no_ad_mid_group_list")).toArray(noAdMidGroupList);
+
+        boolean inNoAdGroup = false;
+        for (String group : noAdMidGroupList) {
+            if (group.equals(midGroup)) {
+                inNoAdGroup = true;
+                break;
+            }
+        }
+        //不出广告组
+        if (inNoAdGroup) {
+            // User is in the no-ad group, no ad should be shown
+            result.put("mid_group", midGroup);
+            result.put("ad_predict", 1);
+            result.put("no_ad_strategy", "no_ad_mid_group_with_video");
+            return result;
+        }
+
+        //top1广告不出视频
+        Map<String, List<String>> noAdGroupWithVideoMapping = (Map) abtestParam.getOrDefault("no_ad_group_with_video_mapping", new HashMap<>());
+        if (noAdGroupWithVideoMapping.keySet().contains(midGroup)
                 &&
-                        (0<=hourOfDay&&hourOfDay<8)){
+                topOneVideoContainer.inNoAdTopVideo(requestParam.getAppType().longValue(), requestParam.getVideoId())
+        ) {
+            result.put("mid_group", midGroup);
             result.put("ad_predict", 1);
-            result.put("no_ad_strategy","no_ad_time_with_fixed_time");
+            result.put("no_ad_strategy", "no_ad_mid_group_with_video");
             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);
+        result = ThresholdModelContainer.
+                getThresholdPredictModel("modelV2")
+                .predict(modelParam);
+
+        return result;
+    }
 
+    public Map<String, Object> adPredictOld(ThresholdPredictModelRequestParam requestParam) {
 
-        String[] abParamArr=abConfig.getAbParams(requestParam.getAbTestCode(),requestParam.getAbExpInfo());
-        if(abParamArr==null){
-            result.put("msg","abConfig_error");
+        JSONObject object = requestParam.getAbExpInfo();
+        //先判断是否开启实验 和是否不出广告时间 而后判断默认0-8
+        Map<String, Object> result = new HashMap<>();
+        int hourOfDay = DateUtils.getCurrentHour();
+        Boolean condition1 = abTestConfigContainer.inAdTimeTest(requestParam.getAbExpInfo());
+        Boolean condition2 = abTestConfigContainer.containsCode(requestParam.getAbTestCode());
+        if (condition1
+                &&
+                condition2
+                &&
+                abTestConfigContainer.inWithoutAdTime(requestParam.getAbTestCode(), hourOfDay)) {
+            result.put("ad_predict", 1);
+            result.put("no_ad_strategy", "no_ad_time_with_time_plan");
+            return result;
+        } else if (
+                (!condition1 || (condition1 && !condition2))
+                        &&
+                        (0 <= hourOfDay && hourOfDay < 8)) {
+            result.put("ad_predict", 1);
+            result.put("no_ad_strategy", "no_ad_time_with_fixed_time");
+            return result;
+        }
+
+
+        String[] abParamArr = abConfig.getAbParams(requestParam.getAbTestCode(), requestParam.getAbExpInfo());
+        if (abParamArr == null) {
+            result.put("msg", "abConfig_error");
             return result;
         }
-        String abtestId=abParamArr[0];
-        String abTestConfigTag=abParamArr[1];
+        String abtestId = abParamArr[0];
+        String abTestConfigTag = abParamArr[1];
 
-        HashMap<String,Map<String,Object>> abConfigMap=abConfig.getAbConfigMap();
-        Map<String,Object> abtestParam=abConfigMap.getOrDefault(abtestId+"-"+abTestConfigTag,null);
-        if(abtestParam==null){
-            result.put("msg","abConfig_error");
+        HashMap<String, Map<String, Object>> abConfigMap = abConfig.getAbConfigMap();
+        Map<String, Object> abtestParam = abConfigMap.getOrDefault(abtestId + "-" + abTestConfigTag, null);
+        if (abtestParam == null) {
+            result.put("msg", "abConfig_error");
             return result;
         }
         //市-中文
-        requestParam.setRegion(requestParam.getRegion().replace("省",""));
-        requestParam.setCity(requestParam.getCity().replace("市",""));
+        requestParam.setRegion(requestParam.getRegion().replace("省", ""));
+        requestParam.setCity(requestParam.getCity().replace("市", ""));
 
 
         // Determine the group to which mid belongs
@@ -101,8 +212,8 @@ public class PredictModelServiceImpl implements PredictModelService {
             midGroup = "mean_group";
         }
 
-        String[] noAdMidGroupList=new String[0];
-        noAdMidGroupList=((JSONArray) abtestParam.get("no_ad_mid_group_list")).toArray(noAdMidGroupList);
+        String[] noAdMidGroupList = new String[0];
+        noAdMidGroupList = ((JSONArray) abtestParam.get("no_ad_mid_group_list")).toArray(noAdMidGroupList);
 
         boolean inNoAdGroup = false;
         for (String group : noAdMidGroupList) {
@@ -116,55 +227,55 @@ public class PredictModelServiceImpl implements PredictModelService {
             // User is in the no-ad group, no ad should be shown
             result.put("mid_group", midGroup);
             result.put("ad_predict", 1);
-            result.put("no_ad_strategy","no_ad_mid_group_with_video");
+            result.put("no_ad_strategy", "no_ad_mid_group_with_video");
             return result;
         }
 
         //top1广告不出视频
-        Map<String,List<String>> noAdGroupWithVideoMapping=(Map) abtestParam.getOrDefault("no_ad_group_with_video_mapping",new HashMap<>());
-        if(noAdGroupWithVideoMapping.keySet().contains(midGroup)
+        Map<String, List<String>> noAdGroupWithVideoMapping = (Map) abtestParam.getOrDefault("no_ad_group_with_video_mapping", new HashMap<>());
+        if (noAdGroupWithVideoMapping.keySet().contains(midGroup)
                 &&
-                topOneVideoContainer.inNoAdTopVideo(requestParam.getAppType().longValue(),requestParam.getVideoId())
-        ){
+                topOneVideoContainer.inNoAdTopVideo(requestParam.getAppType().longValue(), requestParam.getVideoId())
+        ) {
             result.put("mid_group", midGroup);
             result.put("ad_predict", 1);
-            result.put("no_ad_strategy","no_ad_mid_group_with_video");
+            result.put("no_ad_strategy", "no_ad_mid_group_with_video");
             return result;
         }
 
         //设置信息
-        ThresholdPredictModelParam modelParam=ThresholdPredictModelParam.builder()
+        ThresholdPredictModelParam modelParam = ThresholdPredictModelParam.builder()
                 .build();
-        BeanUtils.copyProperties(requestParam,modelParam);
+        BeanUtils.copyProperties(requestParam, modelParam);
         modelParam.setDate(new Date());
         modelParam.setAbtestId(abtestId);
         modelParam.setAbTestConfigTag(abTestConfigTag);
         modelParam.setAbtestParam(abtestParam);
         modelParam.setMidGroup(midGroup);
-        Object thresholdMixFunc=abtestParam.getOrDefault("threshold_mix_func","basic");
-        result= ThresholdModelContainer.
+        Object thresholdMixFunc = abtestParam.getOrDefault("threshold_mix_func", "basic");
+        result = ThresholdModelContainer.
                 getThresholdPredictModel(thresholdMixFunc.toString())
                 .predict(modelParam);
 
         return result;
     }
 
-    public Map<String,Object> adRecommendPredictByRoiModel(RoiPredictModelRequestParam requestParam){
+    public Map<String, Object> adRecommendPredictByRoiModel(RoiPredictModelRequestParam requestParam) {
 
-        Map<String,Object> result=new HashMap<>();
-        int hourOfDay= DateUtils.getCurrentHour();
-        if(hourOfDay<8&&hourOfDay>=0){
+        Map<String, Object> result = new HashMap<>();
+        int hourOfDay = DateUtils.getCurrentHour();
+        if (hourOfDay < 8 && hourOfDay >= 0) {
             result.put("ad_predict", 1);
-            result.put("no_ad_strategy","no_ad_time");
+            result.put("no_ad_strategy", "no_ad_time");
             return result;
         }
-        RoiThresholdPredictModelParam modelParam=new RoiThresholdPredictModelParam();
-        BeanUtils.copyProperties(requestParam,modelParam);
+        RoiThresholdPredictModelParam modelParam = new RoiThresholdPredictModelParam();
+        BeanUtils.copyProperties(requestParam, modelParam);
         modelParam.setEcpm(requestParam.getAds().get(0).getEcpm());
         modelParam.setAdId(requestParam.getAds().get(0).getAdId());
         modelParam.setAdType(requestParam.getAds().get(0).getAdType());
 
-        String groupClassKey = (String)((Map<String,Object>)roiModelConfig.get(AppTypeEnum.valueOf(modelParam.getAppType()).name())).get("group_class_key");
+        String groupClassKey = (String) ((Map<String, Object>) roiModelConfig.get(AppTypeEnum.valueOf(modelParam.getAppType()).name())).get("group_class_key");
         String midGroupKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_MID_GROUP + groupClassKey + ":" + modelParam.getMid();
         String midGroup = redisHelper.get(midGroupKeyName);
         if (midGroup == null) {
@@ -178,5 +289,4 @@ public class PredictModelServiceImpl implements PredictModelService {
     }
 
 
-
 }

+ 1 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreThresholdPredictModel.java

@@ -118,6 +118,7 @@ public class ScoreThresholdPredictModel extends ThresholdPredictModel{
         double onlineScore=getOlineScore(onlineFeatures);
         double rankScoreBias = (double)configMap.getOrDefault("rank_score_bias", 0.0);
         double finalScore =getFinalScore(onlineScore,offlineScore);
+
         double rankScoreW = (double)configMap.getOrDefault("rank_score_w", 1.0);
         double finalScoreW = (double)configMap.getOrDefault("final_score_w", 1.0);
         double mergeScore = finalScoreW * finalScore + rankScoreW * (rankScore + rankScoreBias);

+ 100 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreV2ThresholdPredictModel.java

@@ -0,0 +1,100 @@
+package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
+
+import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
+import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
+import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
+import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.BREAK_CONFIG;
+
+@Component
+public class ScoreV2ThresholdPredictModel extends ThresholdPredictModel {
+
+    @Autowired
+    private FeatureRemoteService featureRemoteService;
+
+    @Value("${ad.predict.threshold:1}")
+    private double threshold;
+
+    @Override
+    String initName() {
+        return "modelV2";
+    }
+
+    @Override
+    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
+
+        UserAdFeature userAdFeature = featureRemoteService.getUserAdFeature(modelParam.getMid());
+        if (userAdFeature == null) {
+            userAdFeature = new UserAdFeature();
+        }
+        List<AdRankItem> rankItems = featureRemoteService.getAllAdFeatureList(CommonCollectionUtils.toList(AdConfig.getAdIds(), id -> id.toString()));
+
+        // scoreParam
+        AdRequestContext context = new AdRequestContext();
+        context.setApptype(modelParam.getAppType().toString());
+        context.setMachineinfoBrand(modelParam.getMachineInfo().getBrand());
+        context.setMachineinfoModel(modelParam.getMachineInfo().getModel());
+        context.setMachineinfoSdkversion(modelParam.getMachineInfo().getSdkVersion());
+        context.setMachineinfoWchatversion(modelParam.getMachineInfo().getWeChatVersion());
+        LocalDateTime date = LocalDateTime.now();
+        context.setHour(date.getHour() + "");
+        context.setDay(date.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
+        context.setWeek(date.getDayOfWeek().getValue() + "");
+
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setRequestContext(context);
+        scoreParam.getRequestContext().setRegion(modelParam.getRegion().replace("省", ""));
+        scoreParam.getRequestContext().setCity(modelParam.getCity().replace("市", ""));
+        scoreParam.setVideoId(modelParam.getVideoId());
+        scoreParam.setMid(modelParam.getMid());
+        scoreParam.setUid("");
+        scoreParam.setProvince(modelParam.getRegion());
+        scoreParam.setCity(modelParam.getCity());
+
+
+        List<AdRankItem> scoreResult = ScorerUtils
+                .getScorerPipeline(BREAK_CONFIG)
+                .scoring(scoreParam, userAdFeature, rankItems);
+
+        // 找出ctr*cvr最大的
+        double max = -1;
+        AdRankItem maxItem = null;
+        for (int i = 0; i < scoreResult.size(); i++) {
+            AdRankItem item = scoreResult.get(i);
+            double ctrCvr = item.getCtr() * item.getCvr();
+            if (ctrCvr > max) {
+                max = ctrCvr;
+                maxItem = item;
+            }
+        }
+
+        int adPredict;
+        if (maxItem != null && maxItem.getScore() < threshold) {
+            // If final score is below threshold, show the ad
+            adPredict = 2;
+        } else {
+            // Otherwise, do not show the ad
+            adPredict = 1;
+        }
+        Map<String, Object> result = new HashMap<>();
+        result.put("threshold", threshold);
+        result.put("score", maxItem == null ? -1 : maxItem.getScore());
+        result.put("ad_predict", adPredict);
+        return result;
+    }
+}

+ 19 - 14
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/ThresholdPredictModelParam.java

@@ -1,6 +1,7 @@
 package com.tzld.piaoquan.ad.engine.service.predict.param;
 
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.ad.engine.service.score.param.MachineInfoParam;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -10,12 +11,12 @@ import java.util.Date;
 import java.util.Map;
 
 /**
- *  mid mid
- *  videoId video_id
- *  appType  app_id
- *  abTestCode  用户对应的ab组--对应java group
- *  abExpInfo AB实验组参数--封装后对应ab_exp_info
- *  careModelStatus  用户关怀模式状态 1-未开启,2-开启
+ * mid mid
+ * videoId video_id
+ * appType  app_id
+ * abTestCode  用户对应的ab组--对应java group
+ * abExpInfo AB实验组参数--封装后对应ab_exp_info
+ * careModelStatus  用户关怀模式状态 1-未开启,2-开启
  */
 @Data
 @Builder
@@ -25,14 +26,18 @@ public class ThresholdPredictModelParam {
     String mid;
     Long videoId;
     Integer appType;
-    String abTestCode;
-    JSONObject abExpInfo;
-    Long careModelStatus;
-    String abtestId;
-    String abTestConfigTag;
-    Map<String,Object> abtestParam;
+    String abTestCode; // drop
+    JSONObject abExpInfo; // drop
+    Long careModelStatus; // drop
+    String abtestId; // drop
+    String abTestConfigTag; // drop
+    Map<String, Object> abtestParam; // drop
+    String midGroup; // drop
+    Date date = new Date();
 
-    String midGroup;
-    Date date=new Date();
+    String region = "-1";
+    //市-中文
+    String city = "-1";
+    MachineInfoParam machineInfo = new MachineInfoParam();
 
 }

+ 10 - 6
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/request/ThresholdPredictModelRequestParam.java

@@ -1,14 +1,16 @@
 package com.tzld.piaoquan.ad.engine.service.predict.param.request;
 
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.ad.engine.service.score.param.MachineInfoParam;
 import lombok.Data;
+
 /**
- *  mid mid
- *  videoId video_id
- *  appType  app_id
- *  abTestCode  用户对应的ab组--对应java group
- *  abExpInfo AB实验组参数--封装后对应ab_exp_info
- *  careModelStatus  用户关怀模式状态 1-未开启,2-开启
+ * mid mid
+ * videoId video_id
+ * appType  app_id
+ * abTestCode  用户对应的ab组--对应java group
+ * abExpInfo AB实验组参数--封装后对应ab_exp_info
+ * careModelStatus  用户关怀模式状态 1-未开启,2-开启
  */
 @Data
 public class ThresholdPredictModelRequestParam {
@@ -22,4 +24,6 @@ public class ThresholdPredictModelRequestParam {
     String region = "-1";
     //市-中文
     String city = "-1";
+
+    MachineInfoParam machineInfo = new MachineInfoParam();
 }

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/FeatureRemoteService.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/remote/FeatureRemoteService.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.remote;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;

+ 42 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/remote/ModelRemoteService.java

@@ -0,0 +1,42 @@
+package com.tzld.piaoquan.ad.engine.service.remote;
+
+import com.tzld.piaoquan.recommend.server.client.ModelClient;
+import com.tzld.piaoquan.recommend.server.client.ModelType;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+
+/**
+ * @author dyp
+ */
+
+@Slf4j
+@Service
+public class ModelRemoteService {
+
+    @Autowired
+    private ModelClient client;
+
+    public Score getScore(Long videoId, String mid, String uid, String city, String province) {
+        if (StringUtils.isBlank(mid)) {
+            return null;
+        }
+        Map<String, Double> scoreMap = client.getScore(videoId, mid, uid, city, province);
+        Score score = new Score();
+        score.setStr(scoreMap.get(ModelType.STR.getKey()));
+        score.setRos(scoreMap.get(ModelType.ROS.getKey()));
+        return score;
+    }
+
+    @Data
+    public static class Score {
+        private double str;
+        private double ros;
+    }
+
+}

+ 23 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/ServiceBeanFactory.java

@@ -0,0 +1,23 @@
+package com.tzld.piaoquan.ad.engine.service.score;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author dyp
+ */
+@Component
+public class ServiceBeanFactory implements ApplicationContextAware {
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return applicationContext.getBean(clazz);
+    }
+}

+ 70 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdBreakScorer.java

@@ -0,0 +1,70 @@
+package com.tzld.piaoquan.ad.engine.service.score;
+
+
+import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
+import com.tzld.piaoquan.ad.engine.commons.score.BaseLRModelScorer;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScorerConfigInfo;
+import com.tzld.piaoquan.ad.engine.service.predict.config.AdOutV1OnlineWeightConfig;
+import com.tzld.piaoquan.ad.engine.service.predict.constant.RuleRedisKeyConst;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+import org.apache.commons.lang3.math.NumberUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+//@Service
+public class VlogAdBreakScorer extends BaseLRModelScorer {
+
+    private AlgorithmRedisHelper redisHelper;
+
+    public VlogAdBreakScorer(ScorerConfigInfo configInfo) {
+        super(configInfo);
+        this.redisHelper = ServiceBeanFactory.getBean(AlgorithmRedisHelper.class);
+    }
+
+
+    @Override
+    public List<AdRankItem> scoring(final ScoreParam param,
+                                    final UserAdFeature userFeature,
+                                    final List<AdRankItem> rankItems) {
+        // offline score
+        String modelKey = "ad_out_v1";
+        String userKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_AD_OUT_MODEL_SCORE_USER + modelKey + ":" + param.getMid();
+        String itemKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_AD_OUT_MODEL_SCORE_ITEM + modelKey + ":" + param.getVideoId();
+        String userScore = redisHelper.get(userKeyName);
+        String itemScore = redisHelper.get(itemKeyName);
+        double offlineScore = NumberUtils.toDouble(userScore, 0) + NumberUtils.toDouble(itemScore, 0);
+
+        // online score
+        Map<String, String> onlineFeatures = new HashMap<>();
+        onlineFeatures.put("ctx_apptype", param.getRequestContext().getApptype());
+        onlineFeatures.put("ctx_week", param.getRequestContext().getWeek());
+        onlineFeatures.put("ctx_hour", param.getRequestContext().getHour());
+        double onlineScore = getOnlineScore(onlineFeatures);
+        double finalScore = onlineScore + offlineScore;
+        double breakRate = 1.0 / (1.0 + Math.exp(0d - finalScore));
+
+        for (int i = 0; i < rankItems.size(); i++) {
+            rankItems.get(i).setBreakRate(breakRate);
+        }
+        return rankItems;
+    }
+
+    private double getOnlineScore(Map<String, String> onlineFeatures) {
+        double score = AdOutV1OnlineWeightConfig.getWeight("bias");
+        for (Map.Entry<String, String> entry : onlineFeatures.entrySet()) {
+            double featureScore = AdOutV1OnlineWeightConfig.getWeight(entry.getKey() + "#" + entry.getValue());
+            score += featureScore;
+        }
+        return score;
+    }
+
+    @Override
+    public void loadModel() {
+        // nothing;
+    }
+}

+ 42 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdRosAndStrScorer.java

@@ -0,0 +1,42 @@
+package com.tzld.piaoquan.ad.engine.service.score;
+
+
+import com.tzld.piaoquan.ad.engine.commons.score.BaseLRModelScorer;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScorerConfigInfo;
+import com.tzld.piaoquan.ad.engine.service.remote.ModelRemoteService;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+
+import java.util.List;
+
+
+//@Service
+public class VlogAdRosAndStrScorer extends BaseLRModelScorer {
+    private ModelRemoteService modelRemoteService;
+
+    public VlogAdRosAndStrScorer(ScorerConfigInfo scorerConfigInfo) {
+        super(scorerConfigInfo);
+        this.modelRemoteService = ServiceBeanFactory.getBean(ModelRemoteService.class);
+    }
+
+    @Override
+    public List<AdRankItem> scoring(final ScoreParam param,
+                                    final UserAdFeature userFeature,
+                                    final List<AdRankItem> rankItems) {
+        ModelRemoteService.Score score = modelRemoteService.getScore(param.getVideoId(), param.getMid(),
+                param.getUid(), param.getCity(), param.getProvince());
+        if (score != null) {
+            for (AdRankItem item : rankItems) {
+                item.setStr(score.getStr());
+                item.setRos(score.getRos());
+            }
+        }
+        return rankItems;
+    }
+
+    @Override
+    public void loadModel() {
+        // nothing;
+    }
+}

+ 58 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogMergeBreakScorer.java

@@ -0,0 +1,58 @@
+package com.tzld.piaoquan.ad.engine.service.score;
+
+
+import com.tzld.piaoquan.ad.engine.commons.score.BaseLRModelScorer;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScorerConfigInfo;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+
+
+//@Service
+public class VlogMergeBreakScorer extends BaseLRModelScorer {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(VlogMergeBreakScorer.class);
+
+
+    public VlogMergeBreakScorer(ScorerConfigInfo configInfo) {
+        super(configInfo);
+    }
+
+
+    @Override
+    public List<AdRankItem> scoring(final ScoreParam param,
+                                    final UserAdFeature userFeature,
+                                    final List<AdRankItem> rankItems) {
+
+        for (AdRankItem item : rankItems) {
+            double ctr = item.getCtr();
+            double cvr = item.getCvr();
+            double str = item.getStr();
+            double ros = item.getRos();
+
+            double a = 0.7;
+            double b = 1;
+            double c = 0.3;
+
+            BigDecimal ctrCvr = new BigDecimal(Math.pow(70 * ctr * cvr, a));
+            BigDecimal strRos = new BigDecimal(Math.pow(str * ros, b));
+            BigDecimal breakRate = new BigDecimal(Math.pow(item.getBreakRate(), c));
+            BigDecimal score = ctrCvr.divide(strRos, 5, BigDecimal.ROUND_HALF_UP).multiply(breakRate);
+
+            item.setScore(score.doubleValue());
+        }
+        Collections.sort(rankItems);
+        return rankItems;
+    }
+
+    @Override
+    public void loadModel() {
+        // nothing;
+    }
+}

+ 2 - 4
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceImpl.java

@@ -1,8 +1,6 @@
 package com.tzld.piaoquan.ad.engine.service.score.impl;
 
 import com.alibaba.fastjson.JSONObject;
-import com.google.gson.JsonObject;
-import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
 import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformBidCreativeDTO;
 import com.tzld.piaoquan.ad.engine.service.score.param.BidRankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdItemFeature;
@@ -11,7 +9,7 @@ import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
-import com.tzld.piaoquan.ad.engine.service.score.FeatureRemoteService;
+import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
 import com.tzld.piaoquan.ad.engine.service.score.RankService;
 import com.tzld.piaoquan.ad.engine.service.score.convert.RequestConvert;
 import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
@@ -116,7 +114,7 @@ public class RankServiceImpl implements RankService {
         Map<String,List<AdPlatformBidCreativeDTO>> groupMap=request
                 .getCreativeList()
                 .stream()
-                .                                  collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()+""));
+                .collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()+""));
 
         List<AdRankItem> rankItems=featureRemoteService.
                 getAllAdFeatureList(

+ 1 - 3
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceThompsonImpl.java

@@ -3,13 +3,12 @@ package com.tzld.piaoquan.ad.engine.service.score.impl;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
-import com.tzld.piaoquan.ad.engine.service.score.FeatureRemoteService;
+import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
 import com.tzld.piaoquan.ad.engine.service.score.RankService;
 import com.tzld.piaoquan.ad.engine.service.score.convert.RequestConvert;
 import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformBidCreativeDTO;
 import com.tzld.piaoquan.ad.engine.service.score.param.BidRankRecommendRequestParam;
 import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdItemFeature;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
 import org.slf4j.Logger;
@@ -18,7 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
 import java.util.List;
 
 @Service