فهرست منبع

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

zhaohaipeng 2 روز پیش
والد
کامیت
b115725174

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

@@ -26,7 +26,9 @@ import com.tzld.piaoquan.ad.engine.service.predict.param.request.ThresholdPredic
 import com.tzld.piaoquan.ad.engine.service.predict.v2.ConvertUtil;
 import com.tzld.piaoquan.ad.engine.service.predict.v2.PredictContext;
 import com.tzld.piaoquan.ad.engine.service.predict.v2.PredictServiceV2;
+import com.tzld.piaoquan.ad.engine.service.predict.v2.RootSessionIdPredict;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +65,9 @@ public class PredictModelServiceImpl implements PredictModelService {
 
     @Autowired
     private PredictServiceV2 predictServiceV2;
+    @Autowired
+    private RootSessionIdPredict rootSessionIdPredict;
+
     @Autowired
     private LogHubService logHubService;
 
@@ -163,7 +168,7 @@ public class PredictModelServiceImpl implements PredictModelService {
 
             if (AbUtil.isInAbExp(expCodes, requestParam.getAppType(), requestParam.getNewExpGroup(), "713")) {
                 PredictContext context = ConvertUtil.predictParam2Context(requestParam);
-                Map<String, Object> resultMap = predictServiceV2.adPredict(context);
+                Map<String, Object> resultMap = predictServiceV2.predict(context);
                 logHubService.crowdChooseLogUpload(context);
                 resultMap.put("pqtId", requestParam.getPqtId());
                 return resultMap;
@@ -266,6 +271,14 @@ public class PredictModelServiceImpl implements PredictModelService {
             modelParam.addUserExtraFuture("shareType", shareType);
             setExtraParam(modelParam);
 
+            // 先走rootSessionId 实验
+            PredictContext ctx = ConvertUtil.predictParam2Context(requestParam);
+            ctx.setShareType(shareType);
+            Map<String, Object> predict = rootSessionIdPredict.predict(ctx);
+            if (MapUtils.isNotEmpty(predict)) {
+                return predict;
+            }
+
             String appTypeStr = requestParam.getAppType().toString();
 
             List<String> userSourceAndLayerAdRateExpIds = Arrays.asList(userSourceLayerAdRateExpIds.split(","));

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

@@ -39,4 +39,6 @@ public class ThresholdPredictModelRequestParam {
      * 2. otherLayer: 裂变层
      */
     private String shareLayer;
+
+    private String rootSessionId;
 }

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

@@ -0,0 +1,25 @@
+package com.tzld.piaoquan.ad.engine.service.predict.v2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class BasicPredict {
+
+    public abstract Map<String, Object> predict(PredictContext ctx);
+
+    protected Map<String, Object> rtnNoAdPredict(PredictContext ctx) {
+        Map<String, Object> rtnMap = new HashMap<>();
+        rtnMap.put("ad_predict", 1);
+        rtnMap.put("no_ad_strategy", "713_exp");
+        rtnMap.put("pqtId", ctx.getPqtId());
+        return rtnMap;
+    }
+
+    protected Map<String, Object> rtnAdPredict(PredictContext ctx) {
+        Map<String, Object> rtnMap = new HashMap<>();
+        rtnMap.put("ad_predict", 2);
+        rtnMap.putAll(ctx.getLogParam().getScoreMap());
+        rtnMap.put("pqtId", ctx.getPqtId());
+        return rtnMap;
+    }
+}

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

@@ -27,6 +27,9 @@ public class ConvertUtil {
         context.setShareLayer(param.getShareLayer());
         context.setMachineInfo(param.getMachineInfo());
 
+        context.setRootSessionId(param.getRootSessionId());
+        context.setAdPlatformType(param.getAdPlatformType());
+
         JSONObject abExpInfo = param.getAbExpInfo();
         Map<String, JSONObject> expConfigMap = ConvertUtil.parseAbTest002Info(abExpInfo);
         context.setExpCodeSet(expConfigMap.keySet());

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

@@ -64,5 +64,14 @@ public class PredictContext {
      */
     private String shareLayer;
 
+    /**
+     * 用户分享和回流的分组
+     */
+    private String shareType;
+
+    private String rootSessionId;
+
+    private String adPlatformType;
+
     private PredictLogParam logParam = new PredictLogParam();
 }

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

@@ -14,7 +14,7 @@ import java.util.Map;
 
 @Slf4j
 @Service
-public class PredictServiceV2 {
+public class PredictServiceV2 extends BasicPredict {
 
     @Autowired
     private FeatureService featureService;
@@ -22,15 +22,16 @@ public class PredictServiceV2 {
     @ApolloJsonValue("${exp.713.config:{}}")
     private Map<String, Double> exp713Config;
 
-    public Map<String, Object> adPredict(PredictContext context) {
-        Feature feature = featureService.getPredictFeature(context);
+    @Override
+    public Map<String, Object> predict(PredictContext ctx) {
+        Feature feature = featureService.getPredictFeature(ctx);
         Map<String, Map<String, String>> userFeature = feature.getUserFeature();
         Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature_v2", new HashMap<>());
         double minScore = exp713Config.getOrDefault("minScore", 0.1d);
         double maxScore = exp713Config.getOrDefault("maxScore", 0.8d);
         double score = maxScore;
 
-        context.getLogParam().setBIsNewUser(true);
+        ctx.getLogParam().setBIsNewUser(true);
 
         if (MapUtils.isNotEmpty(featureMap)) {
 
@@ -62,23 +63,23 @@ public class PredictServiceV2 {
             score = NumUtil.softmax(new double[]{hasAdValue * hasRate, noAdValue * noRate})[0];
 
 
-            context.getLogParam().getMetaFeature().putAll(feature.getUserFeature());
+            ctx.getLogParam().getMetaFeature().putAll(feature.getUserFeature());
             for (Map.Entry<String, String> entry : featureMap.entrySet()) {
-                context.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
+                ctx.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
             }
-            context.getLogParam().getScoreMap().put("adClickValue", NumUtil.round(adClickValue, 6));
-            context.getLogParam().getScoreMap().put("adConverValue", NumUtil.round(adConverValue, 6));
-            context.getLogParam().getScoreMap().put("hasAdShareValue", NumUtil.round(hasAdShareValue, 6));
-            context.getLogParam().getScoreMap().put("hasAdReturnValue", NumUtil.round(hasAdReturnValue, 6));
-            context.getLogParam().getScoreMap().put("hasAdValue", NumUtil.round(hasAdValue, 6));
-            context.getLogParam().getScoreMap().put("noAdShareValue", NumUtil.round(noAdShareValue, 6));
-            context.getLogParam().getScoreMap().put("noAdReturnValue", NumUtil.round(noAdReturnValue, 6));
-            context.getLogParam().getScoreMap().put("noAdValue", NumUtil.round(noAdValue, 6));
-            context.getLogParam().getScoreMap().put("originScore", NumUtil.round(score, 6));
-            context.getLogParam().getScoreMap().put("hasRate", NumUtil.round(hasRate, 6));
-            context.getLogParam().getScoreMap().put("noRate", NumUtil.round(noRate, 6));
-
-            context.getLogParam().setBIsNewUser(false);
+            ctx.getLogParam().getScoreMap().put("adClickValue", NumUtil.round(adClickValue, 6));
+            ctx.getLogParam().getScoreMap().put("adConverValue", NumUtil.round(adConverValue, 6));
+            ctx.getLogParam().getScoreMap().put("hasAdShareValue", NumUtil.round(hasAdShareValue, 6));
+            ctx.getLogParam().getScoreMap().put("hasAdReturnValue", NumUtil.round(hasAdReturnValue, 6));
+            ctx.getLogParam().getScoreMap().put("hasAdValue", NumUtil.round(hasAdValue, 6));
+            ctx.getLogParam().getScoreMap().put("noAdShareValue", NumUtil.round(noAdShareValue, 6));
+            ctx.getLogParam().getScoreMap().put("noAdReturnValue", NumUtil.round(noAdReturnValue, 6));
+            ctx.getLogParam().getScoreMap().put("noAdValue", NumUtil.round(noAdValue, 6));
+            ctx.getLogParam().getScoreMap().put("originScore", NumUtil.round(score, 6));
+            ctx.getLogParam().getScoreMap().put("hasRate", NumUtil.round(hasRate, 6));
+            ctx.getLogParam().getScoreMap().put("noRate", NumUtil.round(noRate, 6));
+
+            ctx.getLogParam().setBIsNewUser(false);
         }
 
         // 分数截断,避免过长或过短
@@ -90,33 +91,19 @@ public class PredictServiceV2 {
 
         double random = Math.random();
         boolean isShowAd = random < score;
-        context.getLogParam().setExpId("713");
-        context.getLogParam().setScore(score);
-        context.getLogParam().getScoreMap().put("score", NumUtil.round(score, 6));
-        context.getLogParam().setAIsShowAd(isShowAd);
-        context.getLogParam().getScoreMap().put("minScore", minScore);
-        context.getLogParam().getScoreMap().put("maxScore", maxScore);
-        context.getLogParam().getScoreMap().put("random", random);
+        ctx.getLogParam().setExpId("713");
+        ctx.getLogParam().setScore(score);
+        ctx.getLogParam().getScoreMap().put("score", NumUtil.round(score, 6));
+        ctx.getLogParam().setAIsShowAd(isShowAd);
+        ctx.getLogParam().getScoreMap().put("minScore", minScore);
+        ctx.getLogParam().getScoreMap().put("maxScore", maxScore);
+        ctx.getLogParam().getScoreMap().put("random", random);
 
 
-        return isShowAd ? rtnAdPredict(context) : rtnNoAdPredict(context);
+        return isShowAd ? rtnAdPredict(ctx) : rtnNoAdPredict(ctx);
     }
 
 
-    private Map<String, Object> rtnNoAdPredict(PredictContext context) {
-        Map<String, Object> rtnMap = new HashMap<>();
-        rtnMap.put("ad_predict", 1);
-        rtnMap.put("no_ad_strategy", "713_exp");
-        return rtnMap;
-    }
-
-    private Map<String, Object> rtnAdPredict(PredictContext context) {
-        Map<String, Object> rtnMap = new HashMap<>();
-        rtnMap.put("ad_predict", 2);
-        rtnMap.putAll(context.getLogParam().getScoreMap());
-        return rtnMap;
-    }
-
     // public Map<String, Object> adPredictV1(PredictContext context){
     //
     //     Feature feature = featureService.getPredictFeature(context);

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

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