소스 검색

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

zhaohaipeng 5 달 전
부모
커밋
20cb453593
46개의 변경된 파일1284개의 추가작업 그리고 552개의 파일을 삭제
  1. 1 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/dto/AdDirectionScore.java
  2. 1 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/dto/AdPlatformCreativeDTO.java
  3. 1 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/MachineInfoParam.java
  4. 2 2
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/RankRecommendRequestParam.java
  5. 1 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/RecommendRequestParam.java
  6. 1 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/StatisticsLogParam.java
  7. 4 0
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScoreParam.java
  8. 2 3
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScorerUtils.java
  9. 0 4
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/CalibrationModel.java
  10. 14 31
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/XGBCalibrationModel.java
  11. 11 1
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/util/AbUtil.java
  12. 128 0
      ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/util/WeightRandom.java
  13. 2 2
      ad-engine-server/src/main/java/com/tzld/piaoquan/ad/engine/server/controller/AdRecommendController.java
  14. 1 1
      ad-engine-server/src/main/resources/ad_score_config_20240626.conf
  15. 1 1
      ad-engine-server/src/main/resources/ad_score_config_20240813.conf
  16. 1 1
      ad-engine-server/src/main/resources/ad_score_config_xgboost.conf
  17. 3 3
      ad-engine-server/src/main/resources/ad_score_config_xgboost_20240909.conf
  18. 13 0
      ad-engine-server/src/main/resources/ad_score_config_xgboost_20241105.conf
  19. 1 1
      ad-engine-server/src/main/resources/ad_score_config_xgboost_683.conf
  20. 0 27
      ad-engine-server/src/main/resources/feeds_score_config_cvr_adjusting.conf
  21. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/log/LogHubService.java
  22. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/log/impl/LogHubServiceImpl.java
  23. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/ThresholdPredictModelParam.java
  24. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/param/request/ThresholdPredictModelRequestParam.java
  25. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankService.java
  26. 3 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/ServiceBeanFactory.java
  27. 22 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/convert/RequestConvert.java
  28. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/BidRankRecommendRequestParam.java
  29. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/RankServiceThompsonImpl.java
  30. 0 92
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/TacticsAndLRModelScoreRankService.java
  31. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/VideoAdThompsonScorerV2.java
  32. 0 166
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/VlogAdCvrLRAdjustingScorer.java
  33. 168 159
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceImpl.java
  34. 147 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/ScoreCalibrationScorer.java
  35. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/VlogRovFMScorer.java
  36. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/VlogRovLRScorer.java
  37. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/XGBoostScorer.java
  38. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/XGBoostScorer683.java
  39. 3 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategy.java
  40. 14 7
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBasic.java
  41. 617 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy679.java
  42. 13 8
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy680.java
  43. 5 5
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy683.java
  44. 5 5
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy687.java
  45. 5 5
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy688.java
  46. 77 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyByWeight.java

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/dto/AdDirectionScore.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/dto/AdDirectionScore.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score.dto;
+package com.tzld.piaoquan.ad.engine.commons.dto;
 
 import lombok.Builder;
 import lombok.Data;

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/dto/AdPlatformCreativeDTO.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/dto/AdPlatformCreativeDTO.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score.dto;
+package com.tzld.piaoquan.ad.engine.commons.dto;
 
 import lombok.Builder;
 import lombok.Data;

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/param/MachineInfoParam.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/MachineInfoParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score.param;
+package com.tzld.piaoquan.ad.engine.commons.param;
 
 import lombok.Data;
 

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/param/RankRecommendRequestParam.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/RankRecommendRequestParam.java

@@ -1,6 +1,6 @@
-package com.tzld.piaoquan.ad.engine.service.score.param;
+package com.tzld.piaoquan.ad.engine.commons.param;
 
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/param/RecommendRequestParam.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/RecommendRequestParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score.param;
+package com.tzld.piaoquan.ad.engine.commons.param;
 
 import lombok.Data;
 import lombok.ToString;

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/param/StatisticsLogParam.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/StatisticsLogParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score.param;
+package com.tzld.piaoquan.ad.engine.commons.param;
 
 import lombok.Data;
 

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

@@ -24,5 +24,9 @@ public class ScoreParam {
 
     private Set<String> expCodeSet;
 
+    /**
+     * 本次命中的实验
+     */
+    private String expCode;
 }
 

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

@@ -23,13 +23,12 @@ public final class ScorerUtils {
 
     public static String THOMPSON_CONF = "feeds_score_config_thompson.conf";
 
-    public static String CVR_ADJUSTING = "feeds_score_config_cvr_adjusting.conf";
-
     public static String LR_ROV_SCORE_20240626 = "ad_score_config_20240626.conf";
 
     public static String XGBOOST_SCORE_CONF = "ad_score_config_xgboost.conf";
     public static String XGBOOST_SCORE_CONF_683 = "ad_score_config_xgboost_683.conf";
     public static String XGBOOST_SCORE_CONF_20240909 = "ad_score_config_xgboost_20240909.conf";
+    public static String XGBOOST_SCORE_CONF_20241105 = "ad_score_config_xgboost_20241105.conf";
 
     public static void warmUp() {
         log.info("scorer warm up ");
@@ -39,10 +38,10 @@ public final class ScorerUtils {
         ScorerUtils.init(XGBOOST_SCORE_CONF_683);
         ScorerUtils.init(XGBOOST_SCORE_CONF);
         ScorerUtils.init(XGBOOST_SCORE_CONF_20240909);
+        ScorerUtils.init(XGBOOST_SCORE_CONF_20241105);
     }
 
     private ScorerUtils() {
-//         init(BASE_CONF);
     }
 
     public static void init(String configFile) {

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

@@ -1,16 +1,12 @@
 package com.tzld.piaoquan.ad.engine.commons.score.model;
 
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdActionFeature;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
-import org.apache.commons.math3.distribution.BetaDistribution;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.math.BigInteger;
-import java.util.HashMap;
 import java.util.TreeMap;
 
 

+ 14 - 31
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/CvrAdjustingModel.java → ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/model/XGBCalibrationModel.java

@@ -7,17 +7,11 @@ import org.slf4j.LoggerFactory;
 
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.List;
-import java.util.Map;
 import java.util.Objects;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
 
-public class CvrAdjustingModel extends Model {
+public class XGBCalibrationModel extends Model {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(CvrAdjustingModel.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(XGBCalibrationModel.class);
 
     private Table<Double, Double, Double> table = HashBasedTable.create();
 
@@ -31,38 +25,27 @@ public class CvrAdjustingModel extends Model {
         Table<Double, Double, Double> initTable = HashBasedTable.create();
         try (BufferedReader input = new BufferedReader(in)) {
             String line;
-            int cnt = 0;
-            Map<Double, Double> initModel = new TreeMap<>();
             while ((line = input.readLine()) != null) {
                 String[] items = line.split("\t");
-                if (items.length < 4) {
+                if (items.length < 2) {
                     continue;
                 }
 
-                double key = new BigDecimal(items[2]).doubleValue();
-                double value = new BigDecimal(items[3]).doubleValue();
-                initModel.put(key, value);
-            }
+                String[] scores = items[0].replaceAll("[(\\]]", "").split(",");
+
+                initTable.put(Double.parseDouble(scores[0]), Double.parseDouble(scores[1]), Double.parseDouble(items[1]));
 
-            // 最终生成的格式为  区间最小值,区间最大值,系数
-            List<Double> keySet = initModel.keySet().stream().sorted().collect(Collectors.toList());
-            double preKey = 0.0;
-            for (Double key : keySet) {
-                initTable.put(preKey, key, initModel.get(key));
-                preKey = key;
             }
-            initTable.put(preKey, Double.MAX_VALUE, initModel.get(preKey));
 
             this.table = initTable;
 
             for (Table.Cell<Double, Double, Double> cell : this.table.cellSet()) {
                 LOGGER.info("cell.row: {}, cell.column: {}, cell.value: {}", cell.getRowKey(), cell.getColumnKey(), cell.getValue());
             }
-            
-            LOGGER.info("[CvrAdjustingModel] model load over and size {}", cnt);
-        } catch (
-                Exception e) {
-            LOGGER.info("[CvrAdjustingModel] model load error ", e);
+
+            LOGGER.info("[XGBCalibrationModel] model load over and size {}", this.table.size());
+        } catch (Exception e) {
+            LOGGER.info("[XGBCalibrationModel] model load error ", e);
         } finally {
             in.close();
 
@@ -70,20 +53,20 @@ public class CvrAdjustingModel extends Model {
         return true;
     }
 
-    public Double getAdjustingCoefficien(double score) {
+    public Double getDiffRate(double score) {
         if (Objects.isNull(table)) {
-            return 1.0;
+            return 0d;
         }
 
         for (Table.Cell<Double, Double, Double> cell : table.cellSet()) {
             double rowKey = cell.getRowKey();
             double columnKey = cell.getColumnKey();
-            if (rowKey <= score & score < columnKey) {
+            if (rowKey < score & score <= columnKey) {
                 LOGGER.info("score {} in {} - {} , value is {}", score, rowKey, columnKey, cell.getValue());
                 return cell.getValue();
             }
         }
 
-        return 1.0;
+        return 0d;
     }
 }

+ 11 - 1
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/util/AbUtil.java

@@ -8,6 +8,8 @@ import java.util.stream.Collectors;
 
 public class AbUtil {
 
+    public static final List<String> adAlgExpCode = Arrays.asList("679", "680", "683", "687", "688");
+
     public static Set<String> unfoldAllExpCode(List<Map<String, String>> adAbMap) {
         if (CollectionUtils.isEmpty(adAbMap)) {
             return new HashSet<>();
@@ -34,6 +36,14 @@ public class AbUtil {
             return NewExpHelper.checkInNewExpGroup(appType.toString(), newExpGroup, expCode);
         }
         return false;
-   }
+    }
 
+    public static String chooseAdAlgExpCode(Set<String> expCodeSet, Object appType, int newExpGroup) {
+        for (String expCode : adAlgExpCode) {
+            if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, expCode)) {
+                return expCode;
+            }
+        }
+        return "";
+    }
 }

+ 128 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/util/WeightRandom.java

@@ -0,0 +1,128 @@
+package com.tzld.piaoquan.ad.engine.commons.util;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * 基于com.alibaba.nacos.client.naming.utils.Chooser 实现
+ *
+ * @param <T>
+ */
+public class WeightRandom<T> {
+
+    private final static Logger log = LoggerFactory.getLogger(WeightRandom.class);
+
+    private final List<T> items = new ArrayList<>();
+    private double[] weights;
+
+    public WeightRandom(List<ItemWithWeight<T>> itemsWithWeight) {
+        this.calWeights(itemsWithWeight);
+    }
+
+    /**
+     * 计算权重,初始化或者重新定义权重时使用
+     */
+    public void calWeights(List<ItemWithWeight<T>> itemsWithWeight) {
+        items.clear();
+
+        // 计算权重总和
+        double originWeightSum = 0;
+        for (ItemWithWeight<T> itemWithWeight : itemsWithWeight) {
+            double weight = itemWithWeight.getWeight();
+            if (weight <= 0) {
+                continue;
+            }
+
+            items.add(itemWithWeight.getItem());
+            if (Double.isInfinite(weight)) {
+                weight = 10000.0D;
+            }
+            if (Double.isNaN(weight)) {
+                weight = 1.0D;
+            }
+            originWeightSum += weight;
+        }
+
+        // 计算每个item的实际权重比例
+        double[] actualWeightRatios = new double[items.size()];
+        int index = 0;
+        for (ItemWithWeight<T> itemWithWeight : itemsWithWeight) {
+            double weight = itemWithWeight.getWeight();
+            if (weight <= 0) {
+                continue;
+            }
+            actualWeightRatios[index++] = weight / originWeightSum;
+        }
+
+        // 计算每个item的权重范围
+        // 权重范围起始位置
+        weights = new double[items.size()];
+        double weightRangeStartPos = 0;
+        for (int i = 0; i < index; i++) {
+            weights[i] = weightRangeStartPos + actualWeightRatios[i];
+            weightRangeStartPos += actualWeightRatios[i];
+        }
+    }
+
+    /**
+     * 基于权重随机算法选择
+     */
+    public T choose() {
+        double random = ThreadLocalRandom.current().nextDouble();
+        int index = Arrays.binarySearch(weights, random);
+        if (index < 0) {
+            index = -index - 1;
+        } else {
+            return items.get(index);
+        }
+
+        if (index < weights.length && random < weights[index]) {
+            return items.get(index);
+        }
+
+        // 通常不会走到这里,为了保证能得到正确的返回,这里随便返回一个
+        return items.get(0);
+    }
+
+    public static <T> T getItemByWeight(List<ItemWithWeight<T>> adItemWeight) {
+        // 权重go
+        WeightRandom<T> weightRandom = new WeightRandom<>(adItemWeight);
+        return weightRandom.choose();
+    }
+
+    public static class ItemWithWeight<T> {
+        T item;
+        double weight;
+
+        public ItemWithWeight() {
+        }
+
+        public ItemWithWeight(T item, double weight) {
+            this.item = item;
+            this.weight = weight;
+        }
+
+        public T getItem() {
+            return item;
+        }
+
+        public void setItem(T item) {
+            this.item = item;
+        }
+
+        public double getWeight() {
+            return weight;
+        }
+
+        public void setWeight(double weight) {
+            this.weight = weight;
+        }
+    }
+
+}

+ 2 - 2
ad-engine-server/src/main/java/com/tzld/piaoquan/ad/engine/server/controller/AdRecommendController.java

@@ -1,9 +1,9 @@
 package com.tzld.piaoquan.ad.engine.server.controller;
 
 import com.tzld.piaoquan.ad.engine.service.score.RankService;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.BidRankRecommendRequestParam;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;

+ 1 - 1
ad-engine-server/src/main/resources/ad_score_config_20240626.conf

@@ -1,6 +1,6 @@
 scorer-config = {
   lr-rov-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.VlogRovFMScorer"
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.VlogRovFMScorer"
     scorer-priority = 99
     model-path = "zhangbo/model_bkb8_v4.txt"
   }

+ 1 - 1
ad-engine-server/src/main/resources/ad_score_config_20240813.conf

@@ -1,6 +1,6 @@
 scorer-config = {
   lr-rov-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.XGBoostScorer"
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.XGBoostScorer"
     scorer-priority = 99
     model-path = "zhangbo/model.tar.gz"
   }

+ 1 - 1
ad-engine-server/src/main/resources/ad_score_config_xgboost.conf

@@ -1,6 +1,6 @@
 scorer-config = {
   lr-rov-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.XGBoostScorer"
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.XGBoostScorer"
     scorer-priority = 99
     model-path = "zhangbo/model_xgb_1000.tar.gz"
   }

+ 3 - 3
ad-engine-server/src/main/resources/ad_score_config_xgboost_20240909.conf

@@ -1,8 +1,8 @@
 scorer-config = {
-  lr-rov-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.XGBoostScorer683"
+  xgb-score-config = {
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.XGBoostScorer683"
     scorer-priority = 99
     model-path = "zhangbo/model_xgb_351_1000_v2.tar.gz"
   }
 
-}
+}

+ 13 - 0
ad-engine-server/src/main/resources/ad_score_config_xgboost_20241105.conf

@@ -0,0 +1,13 @@
+scorer-config = {
+  xgb-score-config = {
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.XGBoostScorer683"
+    scorer-priority = 99
+    model-path = "zhangbo/model_xgb_351_1000_v2.tar.gz"
+  }
+  calibration-score-config = {
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.ScoreCalibrationScorer"
+    scorer-priority = 98
+    model-path = "zhangbo/model_xgb_351_1000_v2_calibration.txt"
+  }
+
+}

+ 1 - 1
ad-engine-server/src/main/resources/ad_score_config_xgboost_683.conf

@@ -1,6 +1,6 @@
 scorer-config = {
   lr-rov-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.XGBoostScorer683"
+    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.scorer.XGBoostScorer683"
     scorer-priority = 99
     model-path = "zhangbo/model_xgb_351_1000.tar.gz"
   }

+ 0 - 27
ad-engine-server/src/main/resources/feeds_score_config_cvr_adjusting.conf

@@ -1,27 +0,0 @@
-scorer-config = {
-  lr-ctr-score-config = {
-    scorer-name = "com.tzld.piaoquan.ad.engine.service.score.deprecated.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.deprecated.VlogAdCvrLRScorer"
-      scorer-priority = 98
-      model-path = "ad_cvr_model/model_ad_cvr.txt"
-  }
-    tf-ctr-score-config = {
-      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.deprecated.VlogAdThompsonScorer"
-      scorer-priority = 97
-      model-path = "ad_thompson_model/model_ad_thompson.txt"
-    }
-    lr-cvr-adjusting-score-config = {
-          scorer-name = "com.tzld.piaoquan.ad.engine.service.score.deprecated.VlogAdCvrLRAdjustingScorer"
-          scorer-priority = 96
-          model-path = "ad_cvr_model/cvr_adjusting_strategy_coefficient.txt"
-    }
-  lr-ecpm-merge-config = {
-      scorer-name = "com.tzld.piaoquan.ad.engine.service.score.deprecated.VlogMergeEcpmScorer"
-      scorer-priority = 1
-  }
-
-}

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/log/LogHubService.java

@@ -1,8 +1,8 @@
 package com.tzld.piaoquan.ad.engine.service.log;
 
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 
 import java.util.List;

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/log/impl/LogHubServiceImpl.java

@@ -6,8 +6,8 @@ import com.google.common.collect.Sets;
 import com.tzld.commons.aliyun.log.AliyunLogManager;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.service.log.LogHubService;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
 import lombok.extern.slf4j.Slf4j;

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

@@ -1,7 +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 com.tzld.piaoquan.ad.engine.commons.param.MachineInfoParam;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;

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

@@ -1,7 +1,7 @@
 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 com.tzld.piaoquan.ad.engine.commons.param.MachineInfoParam;
 import lombok.Data;
 
 /**

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankService.java

@@ -1,9 +1,9 @@
 package com.tzld.piaoquan.ad.engine.service.score;
 
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.BidRankRecommendRequestParam;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
 

+ 3 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/ServiceBeanFactory.java

@@ -1,5 +1,6 @@
 package com.tzld.piaoquan.ad.engine.service.score;
 
+import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -13,8 +14,8 @@ public class ServiceBeanFactory implements ApplicationContextAware {
     private static ApplicationContext applicationContext;
 
     @Override
-    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-        this.applicationContext = applicationContext;
+    public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
+        ServiceBeanFactory.applicationContext = applicationContext;
     }
 
     public static <T> T getBean(Class<T> clazz) {

+ 22 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/convert/RequestConvert.java

@@ -2,8 +2,8 @@ package com.tzld.piaoquan.ad.engine.service.score.convert;
 
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.util.AbUtil;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
 
@@ -42,9 +42,29 @@ public class RequestConvert {
         Set<String> expCodeSet = AbUtil.unfoldAllExpCode(request.getAdAbExpArr());
         scoreParam.setExpCodeSet(expCodeSet);
 
+        // 本次命中的实验
+        String expCode = AbUtil.chooseAdAlgExpCode(expCodeSet, request.getAppType(), request.getNewExpGroup());
+        scoreParam.setExpCode(expCode);
+
         return scoreParam;
     }
 
+    private static String findExpCode(Set<String> expCodeSet, Long appType, Integer newExpGroup) {
+        if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "680")) {
+            return "680";
+        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "683")) {
+            return "683";
+        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "687")) {
+            return "687";
+        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "679")) {
+            return "679";
+        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "688")) {
+            return "688";
+        } else {
+            return "";
+        }
+    }
+
     public static List<AdRankItem> adIdConvertRankItem(List<AdPlatformCreativeDTO> creativeDTOList, RecommendRequestParam request) {
         List<AdRankItem> adRankItems = new ArrayList<>(creativeDTOList.size());
         for (AdPlatformCreativeDTO dto : creativeDTOList) {

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/BidRankRecommendRequestParam.java

@@ -1,7 +1,7 @@
 package com.tzld.piaoquan.ad.engine.service.score.deprecated;
 
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RecommendRequestParam;
 import lombok.Data;
 
 import java.util.List;

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/RankServiceThompsonImpl.java

@@ -1,13 +1,13 @@
 package com.tzld.piaoquan.ad.engine.service.score.deprecated;
 
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 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.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.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
 import org.slf4j.Logger;

+ 0 - 92
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/TacticsAndLRModelScoreRankService.java

@@ -1,92 +0,0 @@
-package com.tzld.piaoquan.ad.engine.service.score.deprecated;
-
-import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
-import com.tzld.piaoquan.ad.engine.service.score.RankService680;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdDirectionScore;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
-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.*;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class TacticsAndLRModelScoreRankService {
-
-    @Autowired
-    private RankService680 rankService680;
-
-    public List<AdRankItem> adItemRank(RankRecommendRequestParam requestParam, ScoreParam scoreParam) {
-
-        // LR模型打分结果
-        List<AdRankItem> result = rankService680.adItemRank(requestParam, scoreParam);
-
-        // List<JSONObject> collect = result.stream().map(item -> {
-        //     JSONObject json = new JSONObject();
-        //     json.put("cid", item.getAdId());
-        //     json.put("score", item.getScore());
-        //     json.put("modelScore", item.getLrScore());
-        //     json.put("allfeature", item.getFeatureMap());
-        //     return json;
-        // }).collect(Collectors.toList());
-
-        Map<Long, AdDirectionScore> adDirectionScoreMap = requestParam.getAdIdList().stream()
-                .collect(Collectors.toMap(AdPlatformCreativeDTO::getCreativeId, AdPlatformCreativeDTO::getAdDirectionScore));
-
-        for (AdRankItem adRankItem : result) {
-
-            this.calcDirectionScore(adRankItem, adDirectionScoreMap.get(adRankItem.getAdId()));
-
-            double s1 = adRankItem.getAdDirectionScore();
-            // 模型的打分结果已经乘CPA,此处不需要重复乘CPA
-            double s2 = adRankItem.getScore();
-            adRankItem.setScore(s1 * s2);
-
-        }
-
-        Collections.sort(result);
-        return result;
-    }
-
-    private void calcDirectionScore(AdRankItem adRankItem, AdDirectionScore adDirectionScore) {
-        if (Objects.isNull(adDirectionScore) || MapUtils.isEmpty(adDirectionScore.getScoreDetail())) {
-            adRankItem.getScoreMap().put("adDirectionScore", 1.0);
-            adRankItem.setAdDirectionScore(1);
-            return;
-        }
-        double exponent = Objects.nonNull(adDirectionScore.getExponent()) ? adDirectionScore.getExponent() : 1;
-        Map<String, String> scoreDetail = adDirectionScore.getScoreDetail();
-
-        double network = Double.parseDouble(scoreDetail.getOrDefault("network", "1"));
-        double phoneModel = Double.parseDouble(scoreDetail.getOrDefault("phoneModel", "1"));
-        double area = Double.parseDouble(scoreDetail.getOrDefault("area", "1"));
-        double peoplePackage = Double.parseDouble(scoreDetail.getOrDefault("peoplePackage", "1"));
-
-
-        double excludeMin = 1.0;
-
-        if (scoreDetail.containsKey("excludeConv") || scoreDetail.containsKey("excludeClick") || scoreDetail.containsKey("excludeView")) {
-            double excludeConv = Double.parseDouble(scoreDetail.getOrDefault("excludeConv", "10000"));
-            double excludeClick = Double.parseDouble(scoreDetail.getOrDefault("excludeClick", "10000"));
-            double excludeView = Double.parseDouble(scoreDetail.getOrDefault("excludeView", "10000"));
-            excludeMin = NumUtil.min(excludeConv, excludeClick, excludeView);
-        }
-
-        double s1 = (network * phoneModel * area * peoplePackage * excludeMin);
-        double s2 = Math.pow(s1, exponent);
-        adRankItem.getScoreMap().put("adDirectionScore", s2);
-        adRankItem.setAdDirectionScore(s2);
-
-        Map<String, String> scoreDetailMap = new HashMap<>(scoreDetail);
-        scoreDetailMap.put("exponent", String.valueOf(exponent));
-        scoreDetailMap.put("excludeMin", String.valueOf(excludeMin));
-        adRankItem.getFeatureMap().putAll(scoreDetailMap);
-    }
-
-}

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/VideoAdThompsonScorerV2.java

@@ -5,7 +5,7 @@ import com.google.gson.Gson;
 import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.util.ComparatorUtil;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.math3.distribution.BetaDistribution;

+ 0 - 166
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/deprecated/VlogAdCvrLRAdjustingScorer.java

@@ -1,166 +0,0 @@
-package com.tzld.piaoquan.ad.engine.service.score.deprecated;
-
-
-import com.tzld.piaoquan.ad.engine.commons.score.AbstractScorer;
-import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.commons.score.ScorerConfigInfo;
-import com.tzld.piaoquan.ad.engine.commons.score.model.CvrAdjustingModel;
-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.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang.NotImplementedException;
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-
-//@Service
-public class VlogAdCvrLRAdjustingScorer extends AbstractScorer {
-
-    private static final int LOCAL_TIME_OUT = 150;
-    private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdCvrLRAdjustingScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
-
-    public VlogAdCvrLRAdjustingScorer(ScorerConfigInfo configInfo) {
-        super(configInfo);
-    }
-
-    @Override
-    public void loadModel() {
-        doLoadModel(CvrAdjustingModel.class);
-    }
-
-    @Override
-    public List<AdRankItem> scoring(final ScoreParam param,
-                                    final UserAdFeature userFeature,
-                                    final List<AdRankItem> rankItems) {
-
-        if (CollectionUtils.isEmpty(rankItems)) {
-            return rankItems;
-        }
-
-        long startTime = System.currentTimeMillis();
-        List<AdRankItem> result = rankByJava(rankItems, param.getRequestContext(), userFeature);
-        LOGGER.debug("ctr ranker time java items size={}, time={} ",
-                result.size(), System.currentTimeMillis() - startTime);
-
-        return result;
-    }
-
-    @Override
-    public List<AdRankItem> scoring(Map<String, String> sceneFeatureMap, Map<String, String> userFeatureMap, List<AdRankItem> rankItems) {
-        throw new NotImplementedException();
-    }
-
-    private List<AdRankItem> rankByJava(final List<AdRankItem> items,
-                                        final AdRequestContext requestContext,
-                                        final UserAdFeature user) {
-        long startTime = System.currentTimeMillis();
-        CvrAdjustingModel model = (CvrAdjustingModel) this.getModel();
-        LOGGER.debug("model size: [{}]", model.getModelSize());
-
-        // 所有都参与打分,按照cvr排序
-        multipleScore(items, requestContext, model);
-
-        // debug log
-        if (LOGGER.isDebugEnabled()) {
-            for (AdRankItem item : items) {
-                LOGGER.debug("after enter feeds model predict cvr adjusting score [{}] [{}]", item, item.getScore());
-            }
-        }
-
-        LOGGER.debug("[ctr ranker time java] items size={}, cost={} ",
-                items.size(), System.currentTimeMillis() - startTime);
-        return items;
-    }
-
-
-    /**
-     * 校准cvr
-     */
-    public void calcScore(final CvrAdjustingModel model,
-                            final AdRankItem item,
-                            final AdRequestContext requestContext) {
-
-        double pro = item.getCvr();
-        try {
-            Double coef = model.getAdjustingCoefficien(pro);
-            if (Objects.nonNull(coef) && coef.doubleValue() > 0.0) {
-                LOGGER.info("[VlogAdCvrLRAdjustingScorer.cvr adjusting] before: {}", pro);
-                pro = pro / coef;
-                LOGGER.info("[VlogAdCvrLRAdjustingScorer.cvr adjusting] after: {}, coef: {}", pro, coef);
-
-            }
-
-        } catch (
-                Exception e) {
-            LOGGER.error("score error for doc={} exception={}",
-                    item.getAdId(), ExceptionUtils.getFullStackTrace(e));
-        }
-        item.setCvr(pro);
-    }
-
-
-    /**
-     * 并行打分
-     *
-     * @param items
-     * @param userInfoBytes
-     * @param requestContext
-     * @param model
-     */
-    private void multipleScore(final List<AdRankItem> items,
-                               final AdRequestContext requestContext,
-                               final CvrAdjustingModel model) {
-
-        List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
-        for (int index = 0; index < items.size(); index++) {
-            final int fIndex = index;
-            calls.add(new Callable<Object>() {
-                @Override
-                public Object call() throws Exception {
-                    try {
-                        calcScore(model, items.get(fIndex), requestContext);
-                    } catch (
-                            Exception e) {
-                        LOGGER.error("ctr exception: [{}] [{}]", items.get(fIndex).adId, ExceptionUtils.getFullStackTrace(e));
-                    }
-                    return new Object();
-                }
-            });
-        }
-
-        List<Future<Object>> futures = null;
-        try {
-            futures = executorService.invokeAll(calls, LOCAL_TIME_OUT, TimeUnit.MILLISECONDS);
-        } catch (
-                InterruptedException e) {
-            LOGGER.error("execute invoke fail: {}", ExceptionUtils.getFullStackTrace(e));
-        }
-
-        // 等待所有请求的结果返回, 超时也返回
-        int cancel = 0;
-        if (futures != null) {
-            for (Future<Object> future : futures) {
-                try {
-                    if (!future.isDone() || future.isCancelled() || future.get() == null) {
-                        cancel++;
-                    }
-                } catch (
-                        InterruptedException e) {
-                    LOGGER.error("InterruptedException {},{}",
-                            requestContext.getApptype(), ExceptionUtils.getFullStackTrace(e));
-                } catch (
-                        ExecutionException e) {
-                    LOGGER.error("ExecutionException {},{}",
-                            requestContext.getApptype(), ExceptionUtils.getFullStackTrace(e));
-                }
-            }
-        }
-        LOGGER.debug("Ctr Score {}, Total: {}, Cancel: {}", requestContext.getApptype(), items.size(), cancel);
-    }
-}

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

@@ -1,25 +1,25 @@
 package com.tzld.piaoquan.ad.engine.service.score.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 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.AbUtil;
 import com.tzld.piaoquan.ad.engine.service.log.LogHubService;
 import com.tzld.piaoquan.ad.engine.service.predict.helper.NewExpInfoHelper;
 import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
 import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
-import com.tzld.piaoquan.ad.engine.service.score.*;
+import com.tzld.piaoquan.ad.engine.service.score.RankService;
+import com.tzld.piaoquan.ad.engine.service.score.ServiceBeanFactory;
 import com.tzld.piaoquan.ad.engine.service.score.convert.RequestConvert;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.BidRankRecommendRequestParam;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.RankServiceThompsonImpl;
-import com.tzld.piaoquan.ad.engine.service.score.deprecated.TacticsAndLRModelScoreRankService;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.VideoAdThompsonScorerV2;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.container.AdCreativeFeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.container.PidLambdaContainer;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.container.PidLambdaForCpcContainer;
 import com.tzld.piaoquan.ad.engine.service.score.deprecated.container.PidLambdaV2Container;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.service.score.strategy.*;
 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;
@@ -56,15 +56,18 @@ public class RankServiceImpl implements RankService {
     private AdCreativeFeatureContainer adCreativeFeatureContainer;
 
     @Autowired
-    private RankService680 rankService680;
+    private RankStrategyBy680 rankStrategyBy680;
     @Autowired
-    private RankService683 rankService683;
+    private RankStrategyBy683 rankStrategyBy683;
     @Autowired
-    private RankService687 rankService687;
+    private RankStrategyBy687 rankStrategyBy687;
     @Autowired
-    private RankStrategyXGBAutoUpdateModel688 rankStrategyXGBAutoUpdateModel688;
+    private RankStrategyBy688 rankStrategyBy688;
     @Autowired
-    private TacticsAndLRModelScoreRankService tacticsAndFmModelScoreRankService;
+    private RankStrategyBy679 rankStrategyBy679;
+
+    @Autowired
+    private RankStrategyByWeight rankStrategyByWeight;
 
     @Value("${ad.model.cpm.max:200}")
     Double cpmMax = 200d;
@@ -81,56 +84,62 @@ public class RankServiceImpl implements RankService {
     @Value("${tactics.fm.mode.score.exp.code:679}")
     private String tacticsAndFmModelScoreExpCode;
 
-    public AdRankItem adItemRank(RankRecommendRequestParam requestParam) {
-        Set<String> expCodeSet = AbUtil.unfoldAllExpCode(requestParam.getAdAbExpArr());
-        Long appType = requestParam.getAppType();
-        Integer newExpGroup = requestParam.getNewExpGroup();
-        if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, fmModelScoreExpCode)) {
-            return rankBy680(requestParam);
-        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "683")) {
-            return rankBy683(requestParam);
-        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "687")) {
-            return rankBy687(requestParam);
-        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, tacticsAndFmModelScoreExpCode)) {
-            return rankBy679(requestParam);
-        } else if (AbUtil.isInAbExp(expCodeSet, appType, newExpGroup, "688")) {
-            return rankStrategyXGBAutoUpdateModel688(requestParam);
-        } else {
-            return adItemRankWithVideoAdThompson(requestParam);
+    public AdRankItem adItemRank(RankRecommendRequestParam request) {
+        ScoreParam scoreParam = RequestConvert.requestConvert(request);
+        RankStrategy rankStrategy = getRankStrategy(scoreParam);
+        List<AdRankItem> adRankItems = rankStrategy.adItemRank(request, scoreParam);
+        logHubService.scoreLogUpload(scoreParam, request.getAdIdList(), adRankItems, request, scoreParam.getExpCode());
+        return adRankItems.get(0);
+    }
+
+    public RankStrategy getRankStrategy(ScoreParam scoreParam) {
+        switch (scoreParam.getExpCode()) {
+            case "687":
+                return ServiceBeanFactory.getBean(RankStrategyBy687.class);
+            case "679":
+                return ServiceBeanFactory.getBean(RankStrategyBy679.class);
+            case "688":
+                return ServiceBeanFactory.getBean(RankStrategyBy688.class);
+            case "680":
+                return ServiceBeanFactory.getBean(RankStrategyBy680.class);
+            case "683":
+                return ServiceBeanFactory.getBean(RankStrategyBy683.class);
+            default:
+                return ServiceBeanFactory.getBean(RankStrategyByWeight.class);
         }
     }
 
     private AdRankItem rankBy687(RankRecommendRequestParam request) {
         ScoreParam scoreParam = RequestConvert.requestConvert(request);
-        List<AdRankItem> adRankItems = rankService687.adItemRank(request, scoreParam);
+        List<AdRankItem> adRankItems = rankStrategyBy687.adItemRank(request, scoreParam);
         logHubService.scoreLogUpload(scoreParam, request.getAdIdList(), adRankItems, request, "687");
         return adRankItems.get(0);
     }
 
     private AdRankItem rankBy680(RankRecommendRequestParam request) {
         ScoreParam scoreParam = RequestConvert.requestConvert(request);
-        List<AdRankItem> adRankItems = rankService680.adItemRank(request, scoreParam);
+        List<AdRankItem> adRankItems = rankStrategyBy680.adItemRank(request, scoreParam);
         logHubService.scoreLogUpload(scoreParam, request.getAdIdList(), adRankItems, request, "680");
         return adRankItems.get(0);
     }
 
     private AdRankItem rankBy683(RankRecommendRequestParam request) {
         ScoreParam scoreParam = RequestConvert.requestConvert(request);
-        List<AdRankItem> adRankItems = rankService683.adItemRank(request, scoreParam);
+        List<AdRankItem> adRankItems = rankStrategyBy683.adItemRank(request, scoreParam);
         logHubService.scoreLogUpload(scoreParam, request.getAdIdList(), adRankItems, request, "683");
         return adRankItems.get(0);
     }
 
     private AdRankItem rankStrategyXGBAutoUpdateModel688(RankRecommendRequestParam request) {
         ScoreParam scoreParam = RequestConvert.requestConvert(request);
-        List<AdRankItem> adRankItems = rankStrategyXGBAutoUpdateModel688.adItemRank(request, scoreParam);
+        List<AdRankItem> adRankItems = rankStrategyBy688.adItemRank(request, scoreParam);
         logHubService.scoreLogUpload(scoreParam, request.getAdIdList(), adRankItems, request, "688");
         return adRankItems.get(0);
     }
 
     private AdRankItem rankBy679(RankRecommendRequestParam requestParam) {
         ScoreParam scoreParam = RequestConvert.requestConvert(requestParam);
-        List<AdRankItem> adRankItems = tacticsAndFmModelScoreRankService.adItemRank(requestParam, scoreParam);
+        List<AdRankItem> adRankItems = rankStrategyBy679.adItemRank(requestParam, scoreParam);
         logHubService.scoreLogUpload(scoreParam, requestParam.getAdIdList(), adRankItems, requestParam, "679");
         double score = adRankItems.get(0).getScore();
         if (score > 0) {
@@ -139,134 +148,134 @@ public class RankServiceImpl implements RankService {
         return null;
     }
 
-    public AdRankItem adItemRankOld(RankRecommendRequestParam request) {
-        ScoreParam param = RequestConvert.requestConvert(request);
-
-        UserAdFeature userAdFeature = featureRemoteService.getUserAdFeature(request.getMid());
-        if (userAdFeature == null) {
-            userAdFeature = new UserAdFeature();
-        }
-        Map<Long, List<AdPlatformCreativeDTO>> groupMap = request
-                .getAdIdList()
-                .stream()
-                .collect(Collectors.groupingBy(AdPlatformCreativeDTO::getCreativeId));
-        Map<Long, AdRankItem> cache = adCreativeFeatureContainer.getAll(new ArrayList<>(groupMap.keySet()));
-        List<AdRankItem> rankItems = Collections.emptyList();
-        if (!cache.isEmpty()) {
-            rankItems = new LinkedList<>(cache.values());
-        }
-        // 避免recommend-feature出问题
-        if (CollectionUtils.isEmpty(rankItems)) {
-            rankItems = new LinkedList<>();
-            for (Long adId : groupMap.keySet()) {
-                AdRankItem item = new AdRankItem();
-                item.setAdId(adId);
-                item.setItemFeature(new AdItemFeature());
-                rankItems.add(item);
-            }
-        }
-        boolean inCpcPidExp = false;
-        boolean inCvrAdjustingExp = false;
-        // if (request.getAdAbExpArr() != null && request.getAdAbExpArr().size() != 0) {
-        //     for (Map<String, Object> map : request.getAdAbExpArr()) {
-        //         if (map.getOrDefault("abExpCode", "").equals(cpcPidExpCode)) {
-        //             inCpcPidExp = true;
-        //         }
-        //         if (map.getOrDefault("abExpCode", "").equals(cvrAdjustingExpCode)) {
-        //             inCvrAdjustingExp = true;
-        //         }
-        //     }
-        // }
-        if (CollectionUtils.isNotEmpty(request.getAdAbExpArr())) {
-            Set<String> abExpCode = request.getAdAbExpArr().stream()
-                    .map(map -> map.get("abExpCode"))
-                    .filter(Objects::nonNull)
-                    .map(Object::toString)
-                    .collect(Collectors.toSet());
-            inCpcPidExp = abExpCode.contains(cpcPidExpCode);
-            inCvrAdjustingExp = abExpCode.contains(cvrAdjustingExpCode);
-        }
-        double lambda = -1d;
-        if (inCpcPidExp) {
-            for (AdRankItem item : rankItems) {
-                try {
-                    AdPlatformCreativeDTO dto = groupMap.get(item.getAdId()).get(0);
-                    item.setBid1(dto.getBid1());
-                    item.setBid2(dto.getBid2());
-                    lambda = PidLambdaForCpcContainer.getPidLambda(item.getAdId());
-                    if (lambda < 0) {
-                        item.setCpa(dto.getCpa());
-                        item.setPidLambda(1);
-                    } else {
-                        if (dto.getCpa() > 1 && lambda <= 1) {
-                            lambda = 2d;
-                        }
-                        item.setCpa(lambda);
-                        item.setPidLambda(1d);
-                    }
-                } catch (Exception e) {
-                    log.error("rankItems info error itemId={}", item.getAdId());
-                    e.printStackTrace();
-                }
-            }
-        } else {
-            for (AdRankItem item : rankItems) {
-                try {
-                    AdPlatformCreativeDTO dto = groupMap.get(item.getAdId()).get(0);
-                    item.setBid1(dto.getBid1());
-                    item.setBid2(dto.getBid2());
-                    item.setCpa(dto.getCpa());
-                    item.setPidLambda(1d);
-                } catch (Exception e) {
-                    log.error("rankItems info error itemId={}", item.getAdId());
-                    e.printStackTrace();
-                }
-            }
-        }
-
-        // 兜底方案
-        List<AdRankItem> rankResult;
-        if (inCvrAdjustingExp) {
-            rankResult = rank(param, userAdFeature, rankItems, ScorerUtils.CVR_ADJUSTING);
-        } else {
-            rankResult = rank(param, userAdFeature, rankItems, ScorerUtils.BASE_CONF);
-        }
-
-        if (!CollectionUtils.isEmpty(rankResult)) {
-            JSONObject object = new JSONObject();
-            object.put("mid", request.getMid());
-            object.put("adid", rankResult.get(0).getAdId());
-            object.put("type", rankResult.get(0).getScore_type());
-            object.put("pctr", rankResult.get(0).getCtr());
-            object.put("pcvr", rankResult.get(0).getCvr());
-            object.put("score", rankResult.get(0).getScore());
-            object.put("pidLambda", rankResult.get(0).getPidLambda());
-            object.put("lrsamples", rankResult.get(0).getLrSampleString());
-            object.put("dataTime", LocalDateTime.now().format(timeFormatter));
-            object.put("creativeId", rankResult.get(0).getAdId());
-            object.put("videoId", request.getVideoId());
-            object.put("pqtId", request.getPqtId());
-            log.info("svc=adItemRank {}", JSONObject.toJSONString(object));
-            object.remove("lrsamples");
-            if (inCpcPidExp) {
-                AdPlatformCreativeDTO dto = groupMap.get(rankResult.get(0).getAdId()).get(0);
-                object.put("cpa", dto.getCpa() * dto.getBid1());
-                object.put("oCpa", dto.getCpa());
-                object.put("realECpm", rankResult.get(0).getEcpm1());
-                log.info("svc=cpc_pid obj={}", JSONObject.toJSONString(object));
-            } else {
-                log.info("svc=pid_log obj={}", JSONObject.toJSONString(object));
-            }
-
-            // 日志上报
-            logHubService.scoreLogUpload(param, request.getAdIdList(), rankResult, request, "531");
-
-            return rankResult.get(0);
-        } else {
-            // 空返回值
-            return new AdRankItem();
-        }
-    }
+    // public AdRankItem adItemRankOld(RankRecommendRequestParam request) {
+    //     ScoreParam param = RequestConvert.requestConvert(request);
+    //
+    //     UserAdFeature userAdFeature = featureRemoteService.getUserAdFeature(request.getMid());
+    //     if (userAdFeature == null) {
+    //         userAdFeature = new UserAdFeature();
+    //     }
+    //     Map<Long, List<AdPlatformCreativeDTO>> groupMap = request
+    //             .getAdIdList()
+    //             .stream()
+    //             .collect(Collectors.groupingBy(AdPlatformCreativeDTO::getCreativeId));
+    //     Map<Long, AdRankItem> cache = adCreativeFeatureContainer.getAll(new ArrayList<>(groupMap.keySet()));
+    //     List<AdRankItem> rankItems = Collections.emptyList();
+    //     if (!cache.isEmpty()) {
+    //         rankItems = new LinkedList<>(cache.values());
+    //     }
+    //     // 避免recommend-feature出问题
+    //     if (CollectionUtils.isEmpty(rankItems)) {
+    //         rankItems = new LinkedList<>();
+    //         for (Long adId : groupMap.keySet()) {
+    //             AdRankItem item = new AdRankItem();
+    //             item.setAdId(adId);
+    //             item.setItemFeature(new AdItemFeature());
+    //             rankItems.add(item);
+    //         }
+    //     }
+    //     boolean inCpcPidExp = false;
+    //     boolean inCvrAdjustingExp = false;
+    //     // if (request.getAdAbExpArr() != null && request.getAdAbExpArr().size() != 0) {
+    //     //     for (Map<String, Object> map : request.getAdAbExpArr()) {
+    //     //         if (map.getOrDefault("abExpCode", "").equals(cpcPidExpCode)) {
+    //     //             inCpcPidExp = true;
+    //     //         }
+    //     //         if (map.getOrDefault("abExpCode", "").equals(cvrAdjustingExpCode)) {
+    //     //             inCvrAdjustingExp = true;
+    //     //         }
+    //     //     }
+    //     // }
+    //     if (CollectionUtils.isNotEmpty(request.getAdAbExpArr())) {
+    //         Set<String> abExpCode = request.getAdAbExpArr().stream()
+    //                 .map(map -> map.get("abExpCode"))
+    //                 .filter(Objects::nonNull)
+    //                 .map(Object::toString)
+    //                 .collect(Collectors.toSet());
+    //         inCpcPidExp = abExpCode.contains(cpcPidExpCode);
+    //         inCvrAdjustingExp = abExpCode.contains(cvrAdjustingExpCode);
+    //     }
+    //     double lambda = -1d;
+    //     if (inCpcPidExp) {
+    //         for (AdRankItem item : rankItems) {
+    //             try {
+    //                 AdPlatformCreativeDTO dto = groupMap.get(item.getAdId()).get(0);
+    //                 item.setBid1(dto.getBid1());
+    //                 item.setBid2(dto.getBid2());
+    //                 lambda = PidLambdaForCpcContainer.getPidLambda(item.getAdId());
+    //                 if (lambda < 0) {
+    //                     item.setCpa(dto.getCpa());
+    //                     item.setPidLambda(1);
+    //                 } else {
+    //                     if (dto.getCpa() > 1 && lambda <= 1) {
+    //                         lambda = 2d;
+    //                     }
+    //                     item.setCpa(lambda);
+    //                     item.setPidLambda(1d);
+    //                 }
+    //             } catch (Exception e) {
+    //                 log.error("rankItems info error itemId={}", item.getAdId());
+    //                 e.printStackTrace();
+    //             }
+    //         }
+    //     } else {
+    //         for (AdRankItem item : rankItems) {
+    //             try {
+    //                 AdPlatformCreativeDTO dto = groupMap.get(item.getAdId()).get(0);
+    //                 item.setBid1(dto.getBid1());
+    //                 item.setBid2(dto.getBid2());
+    //                 item.setCpa(dto.getCpa());
+    //                 item.setPidLambda(1d);
+    //             } catch (Exception e) {
+    //                 log.error("rankItems info error itemId={}", item.getAdId());
+    //                 e.printStackTrace();
+    //             }
+    //         }
+    //     }
+    //
+    //     // 兜底方案
+    //     List<AdRankItem> rankResult;
+    //     if (inCvrAdjustingExp) {
+    //         rankResult = rank(param, userAdFeature, rankItems, ScorerUtils.CVR_ADJUSTING);
+    //     } else {
+    //         rankResult = rank(param, userAdFeature, rankItems, ScorerUtils.BASE_CONF);
+    //     }
+    //
+    //     if (!CollectionUtils.isEmpty(rankResult)) {
+    //         JSONObject object = new JSONObject();
+    //         object.put("mid", request.getMid());
+    //         object.put("adid", rankResult.get(0).getAdId());
+    //         object.put("type", rankResult.get(0).getScore_type());
+    //         object.put("pctr", rankResult.get(0).getCtr());
+    //         object.put("pcvr", rankResult.get(0).getCvr());
+    //         object.put("score", rankResult.get(0).getScore());
+    //         object.put("pidLambda", rankResult.get(0).getPidLambda());
+    //         object.put("lrsamples", rankResult.get(0).getLrSampleString());
+    //         object.put("dataTime", LocalDateTime.now().format(timeFormatter));
+    //         object.put("creativeId", rankResult.get(0).getAdId());
+    //         object.put("videoId", request.getVideoId());
+    //         object.put("pqtId", request.getPqtId());
+    //         log.info("svc=adItemRank {}", JSONObject.toJSONString(object));
+    //         object.remove("lrsamples");
+    //         if (inCpcPidExp) {
+    //             AdPlatformCreativeDTO dto = groupMap.get(rankResult.get(0).getAdId()).get(0);
+    //             object.put("cpa", dto.getCpa() * dto.getBid1());
+    //             object.put("oCpa", dto.getCpa());
+    //             object.put("realECpm", rankResult.get(0).getEcpm1());
+    //             log.info("svc=cpc_pid obj={}", JSONObject.toJSONString(object));
+    //         } else {
+    //             log.info("svc=pid_log obj={}", JSONObject.toJSONString(object));
+    //         }
+    //
+    //         // 日志上报
+    //         logHubService.scoreLogUpload(param, request.getAdIdList(), rankResult, request, "531");
+    //
+    //         return rankResult.get(0);
+    //     } else {
+    //         // 空返回值
+    //         return new AdRankItem();
+    //     }
+    // }
 
     public AdRankItem adItemRankWithVideoAdThompson(RankRecommendRequestParam request) {
         ScoreParam param = RequestConvert.requestConvert(request);

+ 147 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/scorer/ScoreCalibrationScorer.java

@@ -0,0 +1,147 @@
+package com.tzld.piaoquan.ad.engine.service.score.scorer;
+
+import com.tzld.piaoquan.ad.engine.commons.score.AbstractScorer;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScorerConfigInfo;
+import com.tzld.piaoquan.ad.engine.commons.score.model.XGBCalibrationModel;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.*;
+
+public class ScoreCalibrationScorer extends AbstractScorer {
+
+    private static final int LOCAL_TIME_OUT = 150;
+    private static Logger LOGGER = LoggerFactory.getLogger(ScoreCalibrationScorer.class);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+
+
+    public ScoreCalibrationScorer(ScorerConfigInfo scorerConfigInfo) {
+        super(scorerConfigInfo);
+    }
+
+    @Override
+    public void loadModel() {
+        super.doLoadModel(XGBCalibrationModel.class);
+    }
+
+    @Override
+    public List<AdRankItem> scoring(ScoreParam param, UserAdFeature userAdFeature, List<AdRankItem> rankItems) {
+        throw new NoSuchMethodError();
+    }
+
+    public List<AdRankItem> scoring(final Map<String, String> sceneFeatureMap,
+                                    final Map<String, String> userFeatureMap,
+                                    final List<AdRankItem> rankItems) {
+        if (CollectionUtils.isEmpty(rankItems)) {
+            return rankItems;
+        }
+
+        long startTime = System.currentTimeMillis();
+
+        List<AdRankItem> result = rankByJava(sceneFeatureMap, userFeatureMap, rankItems);
+
+        LOGGER.debug("[score calibration] scoring items size={}, time={} ",
+                result.size(), System.currentTimeMillis() - startTime);
+
+        return result;
+    }
+
+    private List<AdRankItem> rankByJava(final Map<String, String> sceneFeatureMap,
+                                        final Map<String, String> userFeatureMap,
+                                        final List<AdRankItem> items) {
+        long startTime = System.currentTimeMillis();
+        XGBCalibrationModel model = (XGBCalibrationModel) this.getModel();
+        LOGGER.debug("model size: [{}]", model.getModelSize());
+
+        // 所有都参与打分,按照ctr排序
+        multipleCtrScore(items, userFeatureMap, sceneFeatureMap, model);
+
+        // debug log
+        if (LOGGER.isDebugEnabled()) {
+            for (AdRankItem item : items) {
+                LOGGER.debug("before enter feeds model predict ctr score [{}] [{}]", item, item);
+            }
+        }
+
+        Collections.sort(items);
+
+        LOGGER.debug("[score calibration] items size={}, cost={} ",
+                items.size(), System.currentTimeMillis() - startTime);
+        return items;
+    }
+
+    private void multipleCtrScore(final List<AdRankItem> items,
+                                  final Map<String, String> userFeatureMap,
+                                  final Map<String, String> sceneFeatureMap,
+                                  final XGBCalibrationModel model) {
+
+        List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
+        for (int index = 0; index < items.size(); index++) {
+            final int fIndex = index;
+            calls.add(new Callable<Object>() {
+                @Override
+                public Object call() throws Exception {
+                    try {
+                        calcScore(model, items.get(fIndex), userFeatureMap, sceneFeatureMap);
+                    } catch (Exception e) {
+                        LOGGER.error("ctr exception: [{}] [{}]", items.get(fIndex), ExceptionUtils.getFullStackTrace(e));
+                    }
+                    return new Object();
+                }
+            });
+        }
+
+        List<Future<Object>> futures = null;
+        try {
+            futures = executorService.invokeAll(calls, LOCAL_TIME_OUT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            LOGGER.error("execute invoke fail: {}", ExceptionUtils.getFullStackTrace(e));
+        }
+
+        // 等待所有请求的结果返回, 超时也返回
+        int cancel = 0;
+        if (futures != null) {
+            for (Future<Object> future : futures) {
+                try {
+                    if (!future.isDone() || future.isCancelled() || future.get() == null) {
+                        cancel++;
+                    }
+                } catch (InterruptedException e) {
+                    LOGGER.error("InterruptedException: ", e);
+                } catch (ExecutionException e) {
+                    LOGGER.error("ExecutionException {},", sceneFeatureMap.size(), e);
+                }
+            }
+        }
+    }
+
+    public double calcScore(final XGBCalibrationModel model,
+                            final AdRankItem item,
+                            final Map<String, String> userFeatureMap,
+                            final Map<String, String> sceneFeatureMap) {
+        double ctcvrScore = item.getLrScore();
+        double newCtcvrScore = ctcvrScore;
+        try {
+
+            double diffRate = model.getDiffRate(ctcvrScore);
+            newCtcvrScore = ctcvrScore / (1 + diffRate);
+            item.setLrScore(newCtcvrScore);
+            item.getScoreMap().put("diff_rate", diffRate);
+            item.getScoreMap().put("originCtcvrScore", ctcvrScore);
+            item.getScoreMap().put("ctcvrScore", newCtcvrScore);
+        } catch (Exception e) {
+            LOGGER.error("[score calibration] calcScore error: ", e);
+        }
+
+        return newCtcvrScore;
+    }
+}

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

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.scorer;
 
 
 import com.tzld.piaoquan.ad.engine.commons.score.BaseFMModelScorer;

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

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.scorer;
 
 
 import com.tzld.piaoquan.ad.engine.commons.score.BaseLRV2ModelScorer;

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

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.scorer;
 
 
 import com.tzld.piaoquan.ad.engine.commons.score.BaseXGBoostModelScorer;

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

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.scorer;
 
 
 import com.tzld.piaoquan.ad.engine.commons.score.BaseXGBoostModelScorer;

+ 3 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankStrategy.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategy.java

@@ -1,11 +1,12 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 
 import java.util.List;
 
 public interface RankStrategy {
+
     List<AdRankItem> adItemRank(RankRecommendRequestParam request, ScoreParam scoreParam);
 }

+ 14 - 7
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankStrategyXGBBasic.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBasic.java

@@ -1,35 +1,35 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.commons.enums.RedisPrefixEnum;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.ad.engine.commons.redis.AdRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
 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 java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Slf4j
-public abstract class RankStrategyXGBBasic implements RankStrategy {
+public abstract class RankStrategyBasic implements RankStrategy {
 
     @ApolloJsonValue("${no.postback.conversion.adverids:[]}")
     private Set<String> noPostbackConversionAdVerIds;
 
+    @ApolloJsonValue("${creative.model.score.coefficient:{}}")
+    private Map<Long, Double> creativeScoreCoefficient;
 
     @Autowired
     private FeatureService featureService;
     @Autowired
     protected AdRedisHelper adRedisHelper;
 
-
     protected Feature getFeature(ScoreParam param, RankRecommendRequestParam request) {
         List<AdPlatformCreativeDTO> adIdList = request.getAdIdList();
         List<String> cidList = adIdList.stream()
@@ -54,6 +54,13 @@ public abstract class RankStrategyXGBBasic implements RankStrategy {
         return noApiAdVerIds;
     }
 
+    protected Map<Long, Double> getCreativeScoreCoefficient() {
+        if (Objects.isNull(creativeScoreCoefficient)) {
+            return new HashMap<>();
+        }
+        return creativeScoreCoefficient;
+    }
+
     protected static class Tuple5 {
         public String f1;
         public String f2;

+ 617 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy679.java

@@ -0,0 +1,617 @@
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
+
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
+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.thread.ThreadPoolFactory;
+import com.tzld.piaoquan.ad.engine.commons.util.*;
+import com.tzld.piaoquan.ad.engine.service.feature.Feature;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.xm.Similarity;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 模型分校准实验
+ */
+@Slf4j
+@Service
+public class RankStrategyBy679 extends RankStrategyBasic {
+
+
+    private Map<String, double[]> bucketsMap = new HashMap<>();
+
+    private Map<String, Double> bucketsLen = new HashMap<>();
+
+    @Value("${word2vec.exp:694}")
+    private String word2vecExp;
+
+    @ApolloJsonValue("${rank.score.weight.679:{}}")
+    private Map<String, Double> weightMap;
+
+    @Override
+    public List<AdRankItem> adItemRank(RankRecommendRequestParam request, ScoreParam scoreParam) {
+
+        Map<String, Double> weightParam = ObjUtil.nullOrDefault(weightMap, new HashMap<>());
+
+        Set<String> noApiAdVerIds = getNoApiAdVerIds();
+
+        Map<Long, Double> creativeScoreCoefficient = getCreativeScoreCoefficient();
+
+        long ts = System.currentTimeMillis() / 1000;
+
+        String brand = scoreParam.getRequestContext().getMachineinfoBrand();
+        if (StringUtils.isNotEmpty(brand)) {
+            scoreParam.getRequestContext().setMachineinfoBrand(brand + "-n");
+        }
+
+        long start = System.currentTimeMillis();
+        // 特征处理
+        // feature1
+        Feature feature = this.getFeature(scoreParam, request);
+
+        Map<String, Map<String, String>> userFeature = feature.getUserFeature();
+        Map<String, Map<String, String>> videoFeature = feature.getVideoFeature();
+        Map<String, Map<String, Map<String, String>>> allAdVerFeature = feature.getAdVerFeature();
+        Map<String, Map<String, Map<String, String>>> allCidFeature = feature.getCidFeature();
+
+        Map<String, String> userFeatureMap = new HashMap<>();
+        Map<String, String> c1Feature = userFeature.getOrDefault("alg_mid_feature_ad_action", new HashMap<>());
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(c1Feature, userFeatureMap);
+
+        Map<String, Double> midTimeDiffMap = this.parseC1FeatureListToTimeDiffMap(midActionList, ts);
+        Map<String, Double> actionStaticMap = this.parseC1FeatureListToActionStaticMap(midActionList);
+
+        Map<String, String> d2Feature = videoFeature.getOrDefault("alg_cid_feature_vid_cf_rank", new HashMap<>());
+        Map<String, String> d3Feature = videoFeature.getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
+
+        Map<String, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(d2Feature);
+
+        Map<String, String> e1Feature = userFeature.getOrDefault("alg_mid_feature_return_tags", new HashMap<>());
+        Map<String, String> e2Feature = userFeature.getOrDefault("alg_mid_feature_share_tags", new HashMap<>());
+
+        Map<String, String> sceneFeatureMap = this.handleSceneFeature(ts);
+        long time1 = System.currentTimeMillis();
+
+        List<AdRankItem> adRankItems = new ArrayList<>();
+        Random random = new Random();
+        List<Future<AdRankItem>> futures = new ArrayList<>();
+        CountDownLatch cdl1 = new CountDownLatch(request.getAdIdList().size());
+        for (AdPlatformCreativeDTO dto : request.getAdIdList()) {
+            Future<AdRankItem> future = ThreadPoolFactory.feature().submit(() -> {
+                AdRankItem adRankItem = new AdRankItem();
+                try {
+                    adRankItem.setAdId(dto.getCreativeId());
+                    adRankItem.setCreativeCode(dto.getCreativeCode());
+                    adRankItem.setAdVerId(dto.getAdVerId());
+                    adRankItem.setVideoId(request.getVideoId());
+                    adRankItem.setCpa(dto.getCpa());
+                    adRankItem.setId(dto.getAdId());
+                    adRankItem.setCampaignId(dto.getCampaignId());
+                    adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
+                    adRankItem.setRandom(random.nextInt(1000));
+                    if (noApiAdVerIds.contains(dto.getAdVerId())) {
+                        adRankItem.getExt().put("isApi", "0");
+                    } else {
+                        adRankItem.getExt().put("isApi", "1");
+                    }
+
+                    String cidStr = dto.getCreativeId().toString();
+                    Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
+                    Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                    Map<String, String> b1Feature = cidFeature.getOrDefault("alg_cid_feature_basic_info", new HashMap<>());
+
+                    Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(dto.getAdVerId(), new HashMap<>());
+
+                    Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
+
+                    this.handleB1Feature(b1Feature, cidFeatureMap, cidStr);
+                    this.handleB2ToB5AndB8ToB9Feature(cidFeature, adVerFeature, cidFeatureMap);
+                    this.handleB6ToB7Feature(cidFeature, cidFeatureMap);
+                    this.handleC1UIFeature(midTimeDiffMap, actionStaticMap, cidFeatureMap, cidStr);
+                    this.handleD1Feature(d1Feature, cidFeatureMap);
+                    this.handleD2Feature(vidRankMaps, cidFeatureMap, cidStr);
+                    return adRankItem;
+                } finally {
+                    cdl1.countDown();
+                }
+            });
+            futures.add(future);
+        }
+        try {
+            cdl1.await(300, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            log.error("handleE1AndE2Feature and handleD3AndB1Feature wait timeout", e);
+        }
+        for (Future<AdRankItem> future : futures) {
+            try {
+                if (future.isDone()) {
+                    adRankItems.add(future.get());
+                }
+            } catch (Exception e) {
+                log.error("Feature handle error", e);
+            }
+        }
+
+        long time2 = System.currentTimeMillis();
+        // feature3
+        CountDownLatch cdl2 = new CountDownLatch(adRankItems.size() * 2);
+        for (AdRankItem item : adRankItems) {
+            String cidStr = String.valueOf(item.getAdId());
+            Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+            Map<String, String> b1Feature = cidFeature.getOrDefault("alg_cid_feature_basic_info", new HashMap<>());
+            String title = b1Feature.getOrDefault("cidtitle", "");
+            ThreadPoolFactory.defaultPool().submit(() -> {
+                try {
+                    this.handleE1AndE2Feature(e1Feature, e2Feature, title, item.getFeatureMap(), scoreParam);
+                } finally {
+                    cdl2.countDown();
+                }
+            });
+            ThreadPoolFactory.defaultPool().submit(() -> {
+                try {
+                    this.handleD3AndB1Feature(d3Feature, title, item.getFeatureMap(), scoreParam);
+                } finally {
+                    cdl2.countDown();
+                }
+            });
+        }
+        long time31 = System.currentTimeMillis();
+        try {
+            cdl2.await(150, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            log.error("handleE1AndE2Feature and handleD3AndB1Feature wait timeout", e);
+        }
+
+        // feature4
+        long time3 = System.currentTimeMillis();
+        // 分桶
+        this.readBucketFile();
+        userFeatureMap = this.featureBucket(userFeatureMap);
+        CountDownLatch cdl4 = new CountDownLatch(adRankItems.size());
+        for (AdRankItem adRankItem : adRankItems) {
+            ThreadPoolFactory.feature().submit(() -> {
+                try {
+                    Map<String, String> featureMap = adRankItem.getFeatureMap();
+                    adRankItem.setFeatureMap(this.featureBucket(featureMap));
+                } finally {
+                    cdl4.countDown();
+                }
+            });
+        }
+        try {
+            cdl4.await(100, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            log.error("handleE1AndE2Feature and handleD3AndB1Feature wait timeout", e);
+        }
+        long time4 = System.currentTimeMillis();
+        // 打分排序
+        // getScorerPipeline
+        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_20241105).scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+        long time5 = System.currentTimeMillis();
+        // loop
+        double cpmCoefficient = weightParam.getOrDefault("cpmCoefficient", 0.9);
+        for (AdRankItem item : result) {
+
+            double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getId(), 1d);
+            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa());
+
+            item.getScoreMap().put("cpa", item.getCpa());
+            item.getScoreMap().put("cpm", item.getCpm());
+            item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
+            item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
+            item.getFeatureMap().putAll(userFeatureMap);
+            item.getFeatureMap().putAll(sceneFeatureMap);
+
+            // 没有转化回传的广告主,使用后台配置的CPM
+            if (noApiAdVerIds.contains(item.getAdVerId())) {
+                item.setScore(item.getCpm() * cpmCoefficient / 1000);
+            }
+
+            for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
+                if (MapUtils.isNotEmpty(entry.getValue())) {
+                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+                }
+            }
+
+            for (Map.Entry<String, Map<String, String>> entry : userFeature.entrySet()) {
+                if (MapUtils.isNotEmpty(entry.getValue())) {
+                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+                }
+            }
+
+            Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(item.getAdVerId(), new HashMap<>());
+            for (Map.Entry<String, Map<String, String>> entry : adVerFeature.entrySet()) {
+                if (MapUtils.isNotEmpty(entry.getValue())) {
+                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+                }
+            }
+
+            Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(String.valueOf(item.getAdId()), new HashMap<>());
+            for (Map.Entry<String, Map<String, String>> entry : cidFeature.entrySet()) {
+                if (MapUtils.isNotEmpty(entry.getValue())) {
+                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+
+        log.info("cost={}, feature1={}, feature2={}, feature31={}, feature32={}, feature4={}, getScorerPipeline={}, " +
+                        "adIdSize={}, adRankItemsSize={}",
+                time5 - start, time1 - start, time2 - time1, time31 - time2, time3 - time31, time4 - time3,
+                time5 - time4, request.getAdIdList().size(), adRankItems.size());
+
+        result.sort(ComparatorUtil.equalsRandomComparator());
+
+        return result;
+    }
+
+    private void handleB1Feature(Map<String, String> b1Feature, Map<String, String> cidFeatureMap, String cid) {
+        cidFeatureMap.put("cid_" + cid, "0.1");
+        if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
+            String adVerId = b1Feature.get("adverid");
+            cidFeatureMap.put("adverid_" + adVerId, "0.1");
+        }
+        if (StringUtils.isNotBlank(b1Feature.get("cpa"))) {
+            String cpa = b1Feature.get("cpa");
+            cidFeatureMap.put("cpa", cpa);
+        }
+    }
+
+    private void handleB2ToB5AndB8ToB9Feature(Map<String, Map<String, String>> c1Feature, Map<String, Map<String, String>> adVerFeature, Map<String, String> cidFeatureMap) {
+        Map<String, String> b2Feature = adVerFeature.getOrDefault("alg_cid_feature_adver_action", new HashMap<>());
+        Map<String, String> b3Feature = c1Feature.getOrDefault("alg_cid_feature_cid_action", new HashMap<>());
+        Map<String, String> b4Feature = c1Feature.getOrDefault("alg_cid_feature_region_action", new HashMap<>());
+        Map<String, String> b5Feature = c1Feature.getOrDefault("alg_cid_feature_app_action", new HashMap<>());
+        Map<String, String> b8Feature = c1Feature.getOrDefault("alg_cid_feature_brand_action", new HashMap<>());
+        Map<String, String> b9Feature = c1Feature.getOrDefault("alg_cid_feature_weChatVersion_action", new HashMap<>());
+
+        List<String> timeList = Arrays.asList("1h", "2h", "3h", "6h", "12h", "1d", "3d", "7d", "yesterday", "today");
+        List<Tuple2<Map<String, String>, String>> featureList = Arrays.asList(
+                new Tuple2<>(b2Feature, "b2"),
+                new Tuple2<>(b3Feature, "b3"),
+                new Tuple2<>(b4Feature, "b4"),
+                new Tuple2<>(b5Feature, "b5"),
+                new Tuple2<>(b8Feature, "b8"),
+                new Tuple2<>(b9Feature, "b9")
+        );
+        for (Tuple2<Map<String, String>, String> tuple2 : featureList) {
+            Map<String, String> feature = tuple2.f1;
+            String prefix = tuple2.f2;
+            for (String time : timeList) {
+                double view = Double.parseDouble(feature.getOrDefault("ad_view_" + time, "0"));
+                double click = Double.parseDouble(feature.getOrDefault("ad_click_" + time, "0"));
+                double conver = Double.parseDouble(feature.getOrDefault("ad_conversion_" + time, "0"));
+                double f2 = NumUtil.div(conver, view);
+                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(NumUtil.div(click, view)));
+                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(f2));
+                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.div(conver, click)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
+
+                cidFeatureMap.put(prefix + "_" + time + "_click", String.valueOf(click));
+                cidFeatureMap.put(prefix + "_" + time + "_conver*log(view)", String.valueOf(conver * NumUtil.log(view)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver*ctcvr", String.valueOf(conver * f2));
+            }
+        }
+
+    }
+
+    private void handleB6ToB7Feature(Map<String, Map<String, String>> c1Feature, Map<String, String> cidFeatureMap) {
+        Map<String, String> b6Feature = c1Feature.getOrDefault("alg_cid_feature_week_action", new HashMap<>());
+        Map<String, String> b7Feature = c1Feature.getOrDefault("alg_cid_feature_hour_action", new HashMap<>());
+
+        List<String> timeList = Arrays.asList("7d", "14d");
+        List<Tuple2<Map<String, String>, String>> featureList = Arrays.asList(
+                new Tuple2<>(b6Feature, "b6"),
+                new Tuple2<>(b7Feature, "b7")
+        );
+        for (Tuple2<Map<String, String>, String> tuple2 : featureList) {
+            Map<String, String> feature = tuple2.f1;
+            String prefix = tuple2.f2;
+            for (String time : timeList) {
+                double view = Double.parseDouble(feature.getOrDefault("ad_view_" + time, "0"));
+                double click = Double.parseDouble(feature.getOrDefault("ad_click_" + time, "0"));
+                double conver = Double.parseDouble(feature.getOrDefault("ad_conversion_" + time, "0"));
+                double f2 = NumUtil.div(conver, view);
+                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(NumUtil.div(click, view)));
+                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(f2));
+                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.div(conver, click)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
+
+                cidFeatureMap.put(prefix + "_" + time + "_click", String.valueOf(click));
+                cidFeatureMap.put(prefix + "_" + time + "_conver*log(view)", String.valueOf(conver * NumUtil.log(view)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver*ctcvr", String.valueOf(conver * f2));
+            }
+        }
+
+    }
+
+    private List<TupleMapEntry<Tuple5>> handleC1Feature(Map<String, String> c1Feature, Map<String, String> featureMap) {
+
+        // 用户特征
+        List<TupleMapEntry<Tuple5>> midActionList = new ArrayList<>();
+        if (c1Feature.containsKey("action")) {
+            String action = c1Feature.get("action");
+            midActionList = Arrays.stream(action.split(","))
+                    .map(r -> {
+                        String[] rList = r.split(":");
+                        Tuple5 tuple5 = new Tuple5(rList[1], rList[2], rList[3], rList[4], rList[5]);
+                        return new TupleMapEntry<>(rList[0], tuple5);
+                    })
+                    // TODO 倒排
+                    .sorted((a, b) -> Integer.compare(Integer.parseInt(b.value.f1), Integer.parseInt(a.value.f1)))
+                    .collect(Collectors.toList());
+        }
+
+        double viewAll = midActionList.size();
+        double clickAll = midActionList.stream().mapToInt(e -> Integer.parseInt(e.value.f2)).sum();
+        double converAll = midActionList.stream().mapToInt(e -> Integer.parseInt(e.value.f3)).sum();
+        double incomeAll = midActionList.stream().mapToInt(e -> Integer.parseInt(e.value.f4)).sum();
+        featureMap.put("viewAll", String.valueOf(viewAll));
+        featureMap.put("clickAll", String.valueOf(clickAll));
+        featureMap.put("converAll", String.valueOf(converAll));
+        featureMap.put("incomeAll", String.valueOf(incomeAll));
+        featureMap.put("ctr_all", String.valueOf(NumUtil.div(clickAll, viewAll)));
+        featureMap.put("ctcvr_all", String.valueOf(NumUtil.div(converAll, viewAll)));
+        featureMap.put("cvr_all", String.valueOf(NumUtil.div(clickAll, converAll)));
+
+        return midActionList;
+    }
+
+    private void handleC1UIFeature(Map<String, Double> midTimeDiffMap, Map<String, Double> midActionStatic, Map<String, String> featureMap, String cid) {
+        if (midTimeDiffMap.containsKey("timediff_view_" + cid)) {
+            featureMap.put("timediff_view", String.valueOf(midTimeDiffMap.getOrDefault("timediff_view_" + cid, 0.0)));
+        }
+        if (midTimeDiffMap.containsKey("timediff_click_" + cid)) {
+            featureMap.put("timediff_click", String.valueOf(midTimeDiffMap.getOrDefault("timediff_click_" + cid, 0.0)));
+        }
+        if (midTimeDiffMap.containsKey("timediff_conver_" + cid)) {
+            featureMap.put("timediff_conver", String.valueOf(midTimeDiffMap.getOrDefault("timediff_conver_" + cid, 0.0)));
+        }
+        if (midActionStatic.containsKey("actionstatic_view_" + cid)) {
+            featureMap.put("actionstatic_view", String.valueOf(midActionStatic.getOrDefault("actionstatic_view_" + cid, 0.0)));
+        }
+        if (midActionStatic.containsKey("actionstatic_click_" + cid)) {
+            featureMap.put("actionstatic_click", String.valueOf(midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0)));
+        }
+        if (midActionStatic.containsKey("actionstatic_conver_" + cid)) {
+            featureMap.put("actionstatic_conver", String.valueOf(midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0)));
+        }
+        if (midActionStatic.containsKey("actionstatic_income_" + cid)) {
+            featureMap.put("actionstatic_income", String.valueOf(midActionStatic.getOrDefault("actionstatic_income_" + cid, 0.0)));
+        }
+        if (midActionStatic.containsKey("actionstatic_view_" + cid) && midActionStatic.containsKey("actionstatic_click_" + cid)) {
+            double ctr = NumUtil.div(
+                    midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0),
+                    midActionStatic.getOrDefault("actionstatic_view_" + cid, 0.0)
+            );
+            featureMap.put("actionstatic_ctr", String.valueOf(ctr));
+        }
+        if (midActionStatic.containsKey("actionstatic_view_" + cid) && midActionStatic.containsKey("actionstatic_conver_" + cid)) {
+            double ctcvr = NumUtil.div(midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0), midActionStatic.getOrDefault("actionstatic_view_" + cid, 0.0));
+            featureMap.put("actionstatic_ctcvr", String.valueOf(ctcvr));
+        }
+        if (midActionStatic.containsKey("actionstatic_conver_" + cid) && midActionStatic.containsKey("actionstatic_click_" + cid)) {
+            double cvr = NumUtil.div(midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0), midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0));
+            featureMap.put("actionstatic_cvr", String.valueOf(cvr));
+        }
+    }
+
+    private void handleD1Feature(Map<String, String> d1Feature, Map<String, String> featureMap) {
+        for (String prefix : Arrays.asList("3h", "6h", "12h", "1d", "3d", "7d")) {
+            double view = Double.parseDouble(d1Feature.getOrDefault("ad_view_" + prefix, "0"));
+            double click = Double.parseDouble(d1Feature.getOrDefault("ad_click_" + prefix, "0"));
+            double conver = Double.parseDouble(d1Feature.getOrDefault("ad_conversion_" + prefix, "0"));
+            double income = Double.parseDouble(d1Feature.getOrDefault("ad_income_" + prefix, "0"));
+            featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(NumUtil.div(click, view)));
+            featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.div(conver, view)));
+            featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.div(conver, click)));
+            featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
+        }
+    }
+
+    private void handleD2Feature(Map<String, Map<String, Double>> vidRankMaps, Map<String, String> featureMap, String cid) {
+        if (MapUtils.isEmpty(vidRankMaps)) {
+            return;
+        }
+
+        List<String> prefixes1 = Arrays.asList("ctr", "ctcvr");
+        List<String> prefixes2 = Arrays.asList("1d", "3d", "7d", "14d");
+
+        for (String prefix1 : prefixes1) {
+            for (String prefix2 : prefixes2) {
+                String combinedKey = prefix1 + "_" + prefix2;
+                if (vidRankMaps.containsKey(combinedKey)) {
+                    Double rank = vidRankMaps.get(combinedKey).getOrDefault(cid, 0.0);
+                    if (rank >= 1.0) {
+                        featureMap.put("vid_rank_" + combinedKey, String.valueOf(NumUtil.div(1, rank)));
+                    }
+                }
+            }
+        }
+    }
+
+    private void handleD3AndB1Feature(Map<String, String> d3Feature, String cTitle, Map<String, String> featureMap,
+                                      ScoreParam scoreParam) {
+        if (MapUtils.isEmpty(d3Feature) || !d3Feature.containsKey("title") || StringUtils.isEmpty(cTitle)) {
+            return;
+        }
+        String vTitle = d3Feature.get("title");
+        double score;
+        if (scoreParam.getExpCodeSet().contains(word2vecExp)) {
+            score = SimilarityUtils.word2VecSimilarity(cTitle, vTitle);
+        } else {
+            score = Similarity.conceptSimilarity(cTitle, vTitle);
+        }
+        featureMap.put("ctitle_vtitle_similarity", String.valueOf(score));
+    }
+
+    private void handleE1AndE2Feature(Map<String, String> e1Feature, Map<String, String> e2Feature, String title,
+                                      Map<String, String> featureMap, ScoreParam scoreParam) {
+        if (StringUtils.isEmpty(title)) {
+            return;
+        }
+
+        List<Tuple2<Map<String, String>, String>> tuple2List = Arrays.asList(new Tuple2<>(e1Feature, "e1"), new Tuple2<>(e2Feature, "e2"));
+
+        List<String> tagsFieldList = Arrays.asList("tags_3d", "tags_7d", "tags_14d");
+        for (Tuple2<Map<String, String>, String> tuple2 : tuple2List) {
+            Map<String, String> feature = tuple2.f1;
+            String prefix = tuple2.f2;
+            if (MapUtils.isEmpty(feature)) {
+                continue;
+            }
+
+            for (String tagsField : tagsFieldList) {
+                if (StringUtils.isNotEmpty(feature.get(tagsField))) {
+                    String tags = feature.get(tagsField);
+                    Double[] doubles;
+                    if (scoreParam.getExpCodeSet().contains(word2vecExp)) {
+                        doubles = ExtractorUtils.funcC34567ForTagsNew(tags, title);
+                    } else {
+                        doubles = ExtractorUtils.funcC34567ForTags(tags, title);
+                    }
+                    featureMap.put(prefix + "_" + tagsField + "_matchnum", String.valueOf(doubles[0]));
+                    featureMap.put(prefix + "_" + tagsField + "_maxscore", String.valueOf(doubles[1]));
+                    featureMap.put(prefix + "_" + tagsField + "_avgscore", String.valueOf(doubles[2]));
+                }
+            }
+        }
+    }
+
+    private Map<String, Double> parseC1FeatureListToTimeDiffMap(List<TupleMapEntry<Tuple5>> midActionList, long ts) {
+        Map<String, Double> midTimeDiffMap = new HashMap<>();
+        for (TupleMapEntry<Tuple5> entry : midActionList) {
+            String cid = entry.key;
+            double tsHistory = Double.parseDouble(entry.value.f1);
+            double click = Double.parseDouble(entry.value.f2);
+            double conver = Double.parseDouble(entry.value.f3);
+            double d = (ts - tsHistory) / 3600 / 24;
+            if (!midTimeDiffMap.containsKey("timediff_view_" + cid)) {
+                midTimeDiffMap.put("timediff_view_" + cid, NumUtil.div(1, d));
+            }
+            if (!midTimeDiffMap.containsKey("timediff_click_" + cid) && click > 0) {
+                midTimeDiffMap.put("timediff_click_" + cid, NumUtil.div(1, d));
+            }
+            if (!midTimeDiffMap.containsKey("timediff_conver_" + cid) && conver > 0) {
+                midTimeDiffMap.put("timediff_conver_" + cid, NumUtil.div(1, d));
+            }
+        }
+        return midTimeDiffMap;
+    }
+
+    private Map<String, Double> parseC1FeatureListToActionStaticMap(List<TupleMapEntry<Tuple5>> midActionList) {
+        Map<String, Double> midActionStaticsMap = new HashMap<>();
+        for (TupleMapEntry<Tuple5> entry : midActionList) {
+            String cid = entry.key;
+            double click = Double.parseDouble(entry.value.f2);
+            double conver = Double.parseDouble(entry.value.f3);
+            double income = Double.parseDouble(entry.value.f4);
+
+            Double viewSum = midActionStaticsMap.getOrDefault("actionstatic_view_" + cid, 0.0);
+            midActionStaticsMap.put("actionstatic_view_" + cid, 1 + viewSum);
+
+            Double clickSum = midActionStaticsMap.getOrDefault("actionstatic_click_" + cid, 0.0);
+            midActionStaticsMap.put("actionstatic_click_" + cid, clickSum + click);
+
+            Double converSum = midActionStaticsMap.getOrDefault("actionstatic_conver_" + cid, 0.0);
+            midActionStaticsMap.put("actionstatic_conver_" + cid, converSum + conver);
+
+            Double incomSum = midActionStaticsMap.getOrDefault("actionstatic_income_" + cid, 0.0);
+            midActionStaticsMap.put("actionstatic_income_" + cid, incomSum + income);
+        }
+
+        return midActionStaticsMap;
+    }
+
+    private Map<String, Map<String, Double>> parseD2FeatureMap(Map<String, String> d2Feature) {
+        Map<String, Map<String, Double>> vidRankMaps = new HashMap<>();
+        for (Map.Entry<String, String> entry : d2Feature.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            Map<String, Double> valueMap = Arrays.stream(value.split(",")).map(r -> r.split(":")).collect(Collectors.toMap(rList -> rList[0], rList -> Double.parseDouble(rList[2])));
+            vidRankMaps.put(key, valueMap);
+        }
+        return vidRankMaps;
+    }
+
+    public Map<String, String> handleSceneFeature(long ts) {
+        Map<String, String> sceneFeatureMap = new HashMap<>();
+        sceneFeatureMap.put("hour_" + DateUtils.getHourByTimestamp(ts), "0.1");
+        sceneFeatureMap.put("dayofweek_" + DateUtils.getDayOrWeekByTimestamp(ts), "0.1");
+        return sceneFeatureMap;
+    }
+
+    private void readBucketFile() {
+        if (MapUtils.isNotEmpty(bucketsMap)) {
+            return;
+        }
+        synchronized (this) {
+            InputStream resourceStream = RankStrategyBy679.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
+            if (resourceStream != null) {
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
+                    Map<String, double[]> bucketsMap = new HashMap<>();
+                    Map<String, Double> bucketsLen = new HashMap<>();
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        // 替换空格和换行符,过滤空行
+                        line = line.replace(" ", "").replaceAll("\n", "");
+                        if (!line.isEmpty()) {
+                            String[] rList = line.split("\t");
+                            if (rList.length == 3) {
+                                String key = rList[0];
+                                double value1 = Double.parseDouble(rList[1]);
+                                bucketsLen.put(key, value1);
+                                double[] value2 = Arrays.stream(rList[2].split(",")).mapToDouble(Double::valueOf).toArray();
+                                bucketsMap.put(key, value2);
+                            }
+                        }
+                    }
+                    this.bucketsMap = bucketsMap;
+                    this.bucketsLen = bucketsLen;
+                } catch (IOException e) {
+                    log.error("something is wrong in parse bucket file:", e);
+                }
+            } else {
+                log.error("no bucket file");
+            }
+        }
+    }
+
+    private Map<String, String> featureBucket(Map<String, String> featureMap) {
+        Map<String, String> newFeatureMap = new ConcurrentHashMap<>(featureMap.size());
+        for (Map.Entry<String, String> entry : featureMap.entrySet()) {
+            String name = entry.getKey();
+            double score = Double.parseDouble(entry.getValue());
+            // 注意:0值、不在分桶文件中的特征,会被过滤掉。
+            if (score > 1E-8) {
+                if (this.bucketsMap.containsKey(name) && this.bucketsLen.containsKey(name)) {
+                    double[] buckets = this.bucketsMap.get(name);
+                    double bucketNum = this.bucketsLen.get(name);
+                    Double scoreNew = 1.0 / bucketNum * (ExtractorUtils.findInsertPosition(buckets, score) + 1.0);
+                    newFeatureMap.put(name, String.valueOf(scoreNew));
+                } else {
+                    newFeatureMap.put(name, String.valueOf(score));
+                }
+            }
+        }
+
+        return newFeatureMap;
+    }
+
+}

+ 13 - 8
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankService680.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy680.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
@@ -6,8 +6,8 @@ import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
@@ -29,8 +29,7 @@ import java.util.stream.Collectors;
 
 @Slf4j
 @Component
-public class RankService680 extends RankStrategyXGBBasic {
-
+public class RankStrategyBy680 extends RankStrategyBasic {
 
     private Map<String, double[]> bucketsMap = new HashMap<>();
 
@@ -47,6 +46,7 @@ public class RankService680 extends RankStrategyXGBBasic {
 
         Map<String, Double> weightParam = ObjUtil.nullOrDefault(weightMap, new HashMap<>());
 
+        Map<Long, Double> creativeScoreCoefficient = getCreativeScoreCoefficient();
         Set<String> noApiAdVerIds = getNoApiAdVerIds();
 
         long ts = System.currentTimeMillis() / 1000;
@@ -202,11 +202,16 @@ public class RankService680 extends RankStrategyXGBBasic {
         long time5 = System.currentTimeMillis();
         // loop
         double cpmCoefficient = weightParam.getOrDefault("cpmCoefficient", 0.9);
+
         for (AdRankItem item : result) {
-            item.setScore(item.getLrScore() * item.getCpa());
+
+            double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getId(), 1d);
+            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa());
+
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
             item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
+            item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
             item.getFeatureMap().putAll(userFeatureMap);
             item.getFeatureMap().putAll(sceneFeatureMap);
 
@@ -484,7 +489,7 @@ public class RankService680 extends RankStrategyXGBBasic {
             for (String tagsField : tagsFieldList) {
                 if (StringUtils.isNotEmpty(feature.get(tagsField))) {
                     String tags = feature.get(tagsField);
-                    //Double[] doubles = ExtractorUtils.funcC34567ForTags(tags, title);
+                    // Double[] doubles = ExtractorUtils.funcC34567ForTags(tags, title);
                     Double[] doubles;
                     if (scoreParam.getExpCodeSet().contains(word2vecExp)) {
                         doubles = ExtractorUtils.funcC34567ForTagsNew(tags, title);
@@ -567,7 +572,7 @@ public class RankService680 extends RankStrategyXGBBasic {
             return;
         }
         synchronized (this) {
-            InputStream resourceStream = RankService680.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
+            InputStream resourceStream = RankStrategyBy680.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
             if (resourceStream != null) {
                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
                     Map<String, double[]> bucketsMap = new HashMap<>();

+ 5 - 5
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankService683.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy683.java

@@ -1,12 +1,12 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 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.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
 
 @Slf4j
 @Component
-public class RankService683 extends RankStrategyXGBBasic {
+public class RankStrategyBy683 extends RankStrategyBasic {
 
     private Map<String, double[]> bucketsMap = new HashMap<>();
 
@@ -546,7 +546,7 @@ public class RankService683 extends RankStrategyXGBBasic {
             return;
         }
         synchronized (this) {
-            InputStream resourceStream = RankService683.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
+            InputStream resourceStream = RankStrategyBy683.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
             if (resourceStream != null) {
                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
                     Map<String, double[]> bucketsMap = new HashMap<>();

+ 5 - 5
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankService687.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy687.java

@@ -1,12 +1,12 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 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.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
 
 @Slf4j
 @Service
-public class RankService687 extends RankStrategyXGBBasic {
+public class RankStrategyBy687 extends RankStrategyBasic {
 
     private Map<String, double[]> bucketsMap = new HashMap<>();
 
@@ -579,7 +579,7 @@ public class RankService687 extends RankStrategyXGBBasic {
             return;
         }
         synchronized (this) {
-            InputStream resourceStream = RankService687.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
+            InputStream resourceStream = RankStrategyBy687.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
             if (resourceStream != null) {
                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
                     Map<String, double[]> bucketsMap = new HashMap<>();

+ 5 - 5
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/RankStrategyXGBAutoUpdateModel688.java → ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy688.java

@@ -1,12 +1,12 @@
-package com.tzld.piaoquan.ad.engine.service.score;
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
 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.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
-import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
-import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
 
 @Slf4j
 @Component
-public class RankStrategyXGBAutoUpdateModel688 extends RankStrategyXGBBasic {
+public class RankStrategyBy688 extends RankStrategyBasic {
 
 
     private Map<String, double[]> bucketsMap = new HashMap<>();
@@ -559,7 +559,7 @@ public class RankStrategyXGBAutoUpdateModel688 extends RankStrategyXGBBasic {
             return;
         }
         synchronized (this) {
-            InputStream resourceStream = RankStrategyXGBAutoUpdateModel688.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
+            InputStream resourceStream = RankStrategyBy688.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
             if (resourceStream != null) {
                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
                     Map<String, double[]> bucketsMap = new HashMap<>();

+ 77 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyByWeight.java

@@ -0,0 +1,77 @@
+package com.tzld.piaoquan.ad.engine.service.score.strategy;
+
+
+import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
+import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+import com.tzld.piaoquan.ad.engine.commons.util.ComparatorUtil;
+import com.tzld.piaoquan.ad.engine.commons.util.ObjUtil;
+import com.tzld.piaoquan.ad.engine.commons.util.WeightRandom;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+/**
+ * 人工权重排序,作为最后的兜底
+ */
+@Slf4j
+@Component
+public class RankStrategyByWeight extends RankStrategyBasic {
+
+    @Override
+    public List<AdRankItem> adItemRank(RankRecommendRequestParam request, ScoreParam scoreParam) {
+        Set<String> noApiAdVerIds = getNoApiAdVerIds();
+
+        List<AdPlatformCreativeDTO> creativeDTOS = request.getAdIdList();
+
+        List<WeightRandom.ItemWithWeight<AdRankItem>> creativeItemWeights = new ArrayList<>(creativeDTOS.size());
+        List<AdRankItem> adRankItems = new ArrayList<>(creativeDTOS.size());
+        Random random = new Random();
+        double originWeightSum = 0;
+        for (AdPlatformCreativeDTO dto : creativeDTOS) {
+            AdRankItem adRankItem = new AdRankItem();
+            adRankItem.setAdId(dto.getCreativeId());
+            adRankItem.setCreativeCode(dto.getCreativeCode());
+            adRankItem.setAdVerId(dto.getAdVerId());
+            adRankItem.setVideoId(scoreParam.getVideoId());
+            adRankItem.setCpa(dto.getCpa());
+            adRankItem.setId(dto.getAdId());
+            adRankItem.setCampaignId(dto.getCampaignId());
+            adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
+            adRankItem.setRandom(random.nextInt(1000));
+            adRankItem.setWeight(dto.getWeight());
+            adRankItem.setScore(0d);
+            adRankItem.getScoreMap().put("weight", dto.getWeight());
+            if (noApiAdVerIds.contains(dto.getAdVerId())) {
+                adRankItem.getExt().put("isApi", "0");
+            } else {
+                adRankItem.getExt().put("isApi", "1");
+            }
+
+
+            adRankItems.add(adRankItem);
+
+            originWeightSum += dto.getWeight();
+            WeightRandom.ItemWithWeight<AdRankItem> itemWithWeight = new WeightRandom.ItemWithWeight<AdRankItem>();
+            itemWithWeight.setItem(adRankItem);
+            itemWithWeight.setWeight(adRankItem.getWeight());
+            creativeItemWeights.add(itemWithWeight);
+        }
+
+        AdRankItem adRankItem = WeightRandom.getItemByWeight(creativeItemWeights);
+
+        for (AdRankItem rankItem : adRankItems) {
+            rankItem.getScoreMap().put("weightSum", originWeightSum);
+            if (Objects.equals(rankItem.getAdId(), adRankItem.getAdId())) {
+                rankItem.setScore(rankItem.getWeight() / originWeightSum);
+            }
+        }
+
+        adRankItems.sort(ComparatorUtil.equalsRandomComparator());
+
+        return adRankItems;
+    }
+
+}