Browse Source

增加行业校准实验

xueyiming 1 day ago
parent
commit
2195e3a67f

+ 71 - 11
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBasic.java

@@ -107,6 +107,9 @@ public abstract class RankStrategyBasic implements RankStrategy {
     @Value("${filter.ecpm:60}")
     protected String filterEcpm;
 
+    @Value("${calibration.profession.exp:792}")
+    protected String calibrationProfessionExp;
+
     @Autowired
     private FeatureService featureService;
     @Autowired
@@ -124,7 +127,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
     String cidLayerKey = "ad:engine:cid:layer:info:{cid}:{userLayer}";
 
-    String userLayerDataKey = "ad:platform:{layer}:{class}:{type}:{value}";
+    String userLayerDataKey = "ad:platform:{layer}:{class}:{model}:{type}:{value}";
 
 
     private static final double DEFAULT_CORRECTION = 1.0;
@@ -364,7 +367,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
      * 根据人群信息计算保量权重系数(新版本)
      *
      * @param guaranteeView 保量视图对象
-     * @param reqFeature 请求特征信息,包含用户人群layer信息
+     * @param reqFeature    请求特征信息,包含用户人群layer信息
      * @return 保量权重系数
      */
     protected double calculateGuaranteeWeightWithCrowd(GuaranteeView guaranteeView, Map<String, String> reqFeature) {
@@ -407,7 +410,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
                 // 对勾选了保量人群,且不是勾选了全部的保量人群的广告进行额外加权
                 double finalWeight = baseWeight * guaranteeCrowdWeightCoefficient;
                 log.debug("RankStrategyBasic 保量人群加权: userLayer={}, guaranteeCrowdCode={}, baseWeight={}, coefficient={}, finalWeight={}",
-                         userLayer, guaranteeCrowdCode, baseWeight, guaranteeCrowdWeightCoefficient, finalWeight);
+                        userLayer, guaranteeCrowdCode, baseWeight, guaranteeCrowdWeightCoefficient, finalWeight);
                 return finalWeight;
             } else {
                 // 用户不在保量人群范围内,权重设为1
@@ -422,18 +425,18 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
     /**
      * 计算保量权重系数(原有逻辑)
-     *
+     * <p>
      * 保量逻辑说明:
      * 1. 根据广告主的保量配置(保量比例、保量上限)和实际曝光情况计算权重
      * 2. 权重用于调整广告排序分数,帮助未达到保量目标的广告主获得更多曝光
      * 3. 已达到保量上限的广告主权重为0,避免过度曝光
      *
      * @param guaranteeView 保量视图对象,包含广告主保量相关数据
-     *                     - adrId: 广告主ID
-     *                     - adrAlgoViewNum: 广告主当天算法曝光数
-     *                     - allAlgoViewNum: 全平台当天算法曝光数
-     *                     - guaranteeNum: 保量上限(广告主最大允许曝光数)
-     *                     - guaranteeRate: 保量比例(广告主期望占全平台曝光的百分比)
+     *                      - adrId: 广告主ID
+     *                      - adrAlgoViewNum: 广告主当天算法曝光数
+     *                      - allAlgoViewNum: 全平台当天算法曝光数
+     *                      - guaranteeNum: 保量上限(广告主最大允许曝光数)
+     *                      - guaranteeRate: 保量比例(广告主期望占全平台曝光的百分比)
      * @return 保量权重系数,范围[0.0, 2.0],默认1.0
      */
     protected double calculateGuaranteedWeight(GuaranteeView guaranteeView) {
@@ -648,6 +651,62 @@ public abstract class RankStrategyBasic implements RankStrategy {
                 log.error("calibrationCtcvrScore error", e);
             }
         }
+
+        if (scoreParam.getExpCodeSet().contains(calibrationProfessionExp)) {
+            try {
+                calibrationProfessionCtcvrScore(items, modelName, reqFeature);
+            } catch (Exception e) {
+                log.error("calibrationProfessionCtcvrScore error", e);
+            }
+        }
+    }
+
+    private void calibrationProfessionCtcvrScore(List<AdRankItem> items, String modelName, Map<String, String> reqFeature) {
+        if (StringUtils.isEmpty(modelName)) {
+            return;
+        }
+        // 构建Key模板
+        String layerKeyTemplate = userLayerDataKey
+                .replace("{model}", modelName)
+                .replace("{layer}", reqFeature.get("layer"))
+                .replace("{class}", reqFeature.get("clazz"))
+                .replace("{type}", "profession");
+        List<String> professions = items.stream().map(AdRankItem::getProfession).distinct().collect(Collectors.toList());
+        List<String> professionRedisKeys = professions.stream().map(e -> layerKeyTemplate.replace("{value}", e)).collect(Collectors.toList());
+        List<String> redisValues = adRedisHelper.mget(professionRedisKeys);
+        Map<String, CalibrationModelCtcvrData> map = new HashMap<>();
+        for (int i = 0; i < professions.size(); i++) {
+            String value = redisValues.get(i);
+            if (StringUtils.isEmpty(value)) {
+                continue;
+            }
+            JSONObject json = JSONObject.parseObject(value);
+            CalibrationModelCtcvrData calibrationModelCtcvrData = new CalibrationModelCtcvrData();
+            calibrationModelCtcvrData.setRealCtcvr(json.getDouble("ctcvr"));
+            calibrationModelCtcvrData.setView(json.getInteger("view"));
+            calibrationModelCtcvrData.setPCtcvr(json.getDouble("pCtcvr"));
+            map.put(professions.get(i), calibrationModelCtcvrData);
+        }
+
+
+        for (AdRankItem item : items) {
+            CalibrationModelCtcvrData calibrationModelCtcvrData = map.get(item.getProfession());
+            item.getExt().put("calibrationModelProfessionCtcvrData", JSONObject.toJSONString(calibrationModelCtcvrData));
+            if (calibrationModelCtcvrData.getPCtcvr() == null
+                    || calibrationModelCtcvrData.getPCtcvr() == 0.0
+                    || calibrationModelCtcvrData.getRealCtcvr() == null
+                    || calibrationModelCtcvrData.getRealCtcvr() == 0.0) {
+                continue;
+            }
+            double diff = calibrationModelCtcvrData.getRealCtcvr() / calibrationModelCtcvrData.getPCtcvr();
+            if (Math.abs(diff - 1) < 0.1) {
+                continue;
+            }
+            double calibratedCtcvrScore = item.getLrScore() * diff;
+            item.getScoreMap().put("layerModelProfessionCtcvrScore", calibratedCtcvrScore);
+            item.getScoreMap().put("ctcvrScore", calibratedCtcvrScore);
+            item.setLrScore(calibratedCtcvrScore);
+        }
     }
 
     protected void calibrationCtcvrScore(List<AdRankItem> items, RankRecommendRequestParam request, Map<String, String> reqFeature) {
@@ -883,7 +942,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
      * 判断用户人群是否在保量人群范围内
      *
      * @param guaranteeCrowdCode 保量人群代码字符串,格式如"1,2,3"
-     * @param userCrowdCode 用户人群代码
+     * @param userCrowdCode      用户人群代码
      * @return true表示用户在保量人群范围内
      */
     private boolean isUserInGuaranteeCrowd(String guaranteeCrowdCode, Integer userCrowdCode) {
@@ -908,6 +967,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
     /**
      * 判断是否全部保量人群
+     *
      * @param guaranteeCrowdCode 保量人群代码字符串
      * @return true表示是全部保量人群
      */
@@ -936,7 +996,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
         } catch (Exception e) {
             log.error("判断保量人群加权失败: guaranteeCrowdCode={}",
-                     guaranteeCrowdCode, e);
+                    guaranteeCrowdCode, e);
             return false;
         }
     }