Przeglądaj źródła

feat:添加676实验

zhaohaipeng 10 miesięcy temu
rodzic
commit
8675ecc1fa

+ 7 - 6
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/container/ThresholdModelContainer.java

@@ -26,24 +26,25 @@ public class ThresholdModelContainer {
     @Value("${ad.predict.t-digest.position:0.52}")
     private double position;
 
-    public static Map<String,ThresholdPredictModel> modelMap=new HashMap<>();
+    public static Map<String, ThresholdPredictModel> modelMap = new HashMap<>();
 
 
     private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
     @PostConstruct
     public void init() {
-        Map<String,ThresholdPredictModel> beanMap= applicationContext.getBeansOfType(ThresholdPredictModel.class);
-        beanMap.forEach((s,model)->{
+        Map<String, ThresholdPredictModel> beanMap = applicationContext.getBeansOfType(ThresholdPredictModel.class);
+        beanMap.forEach((s, model) -> {
             modelMap.put(model.getName(), model);
         });
 
     }
 
-    public static ThresholdPredictModel getThresholdPredictModel(String modelName){
-        return modelMap.getOrDefault(modelName,getBasicPredictModel());
+    public static ThresholdPredictModel getThresholdPredictModel(String modelName) {
+        return modelMap.getOrDefault(modelName, getBasicPredictModel());
     }
 
-    public static ThresholdPredictModel getBasicPredictModel(){
+    public static ThresholdPredictModel getBasicPredictModel() {
         return modelMap.get("basic");
     }
 

+ 16 - 9
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/helper/NewExpInfoHelper.java

@@ -51,22 +51,29 @@ public class NewExpInfoHelper {
         }
     }
 
-    public static boolean checkInNewExpGroupAndSetParamIfIn(String appId, int groupNumber, String expId, ThresholdPredictModelParam modelParam){
+    public static boolean checkInNewExpGroupAndSetParamIfIn(Collection<String> abCodes, String appId, int groupNumber, String expId, ThresholdPredictModelParam modelParam) {
+        if (abCodes.contains(NewExpInfoHelper.flagId)) {
+            return checkInNewExpGroupAndSetParamIfIn(appId, groupNumber, expId, modelParam);
+        }
+        return false;
+    }
+
+    public static boolean checkInNewExpGroupAndSetParamIfIn(String appId, int groupNumber, String expId, ThresholdPredictModelParam modelParam) {
         try {
-            if(appExpIdCache.get(appId)==null||!appExpIdCache.get(appId).contains(expId)){
+            if (appExpIdCache.get(appId) == null || !appExpIdCache.get(appId).contains(expId)) {
                 return false;
             }
-            if((expIdAndRangeCache.get(expId).getAllEnter()&&groupNumber<0)
-                    ||(
-                    expIdAndRangeCache.get(expId).getRange()[0]<=groupNumber&&expIdAndRangeCache.get(expId).getRange()[1]>=groupNumber)
-            ){
-                for(Map.Entry<String,Object> entry:expIdAndRangeCache.get(expId).getParam().entrySet()){
-                    modelParam.getExtraParam().put(entry.getKey(),entry.getValue());
+            if ((expIdAndRangeCache.get(expId).getAllEnter() && groupNumber < 0)
+                    || (
+                    expIdAndRangeCache.get(expId).getRange()[0] <= groupNumber && expIdAndRangeCache.get(expId).getRange()[1] >= groupNumber)
+            ) {
+                for (Map.Entry<String, Object> entry : expIdAndRangeCache.get(expId).getParam().entrySet()) {
+                    modelParam.getExtraParam().put(entry.getKey(), entry.getValue());
                 }
                 return true;
             }
             return false;
-        }catch (Exception e){
+        } catch (Exception e) {
             return false;
         }
     }

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

@@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+
 //
 @Service
 public class PredictModelServiceImpl implements PredictModelService {
@@ -63,23 +64,23 @@ public class PredictModelServiceImpl implements PredictModelService {
     @Value("${ad.predict.without.ad.video_ids:0}")
     private String withoutAdVideoIds;
     @Value("${ad.predict.old.exp.appId:0,3,4,5,6,17,18,19,21,22}")
-    private String oldExpGroupAppId="";
-    List<Integer> appIdArr=Arrays.asList(new Integer[]{0,3,4,5,6,17,18,19,21,22});
+    private String oldExpGroupAppId = "";
+    List<Integer> appIdArr = Arrays.asList(new Integer[]{0, 3, 4, 5, 6, 17, 18, 19, 21, 22});
 
 
     public Map<String, Object> adPredict(ThresholdPredictModelRequestParam requestParam) {
-        Map<String,Object> result=new HashMap<>();
+        Map<String, Object> result = new HashMap<>();
         result.put("pqtId", requestParam.getPqtId());
         try {
-            String[] withoutAdVideoIdsArr=withoutAdVideoIds.split(",");
-            for(String videoId:withoutAdVideoIdsArr){
-                if(videoId.equals(requestParam.getVideoId()+"")){
-                    if(requestParam.getAppType().equals(0)
-                            ||requestParam.getAppType().equals(4)
-                            ||requestParam.getAppType().equals(5)
-                            ||requestParam.getAppType().equals(21)
-                    ){
-                         result=new HashMap<>();
+            String[] withoutAdVideoIdsArr = withoutAdVideoIds.split(",");
+            for (String videoId : withoutAdVideoIdsArr) {
+                if (videoId.equals(requestParam.getVideoId() + "")) {
+                    if (requestParam.getAppType().equals(0)
+                            || requestParam.getAppType().equals(4)
+                            || requestParam.getAppType().equals(5)
+                            || requestParam.getAppType().equals(21)
+                    ) {
+                        result = new HashMap<>();
                         result.put("ad_predict", 1);
                         result.put("no_ad_strategy", "no_ad_with_video_in_white_list");
                         return result;
@@ -88,28 +89,28 @@ public class PredictModelServiceImpl implements PredictModelService {
             }
 
 
-            List<Map<String,Object>> mapList=(List)requestParam.getAbExpInfo().get("ab_test002");
+            List<Map<String, Object>> mapList = (List) requestParam.getAbExpInfo().get("ab_test002");
 
-            Map<String,List<JSONObject>> configMap=new HashMap<>();
-            //该用户所有实验合集
-            Set<String> expCodes=new HashSet<>();
-            for(Map<String,Object> map:mapList){
-                String expCode=map.getOrDefault("abExpCode","").toString();
+            Map<String, List<JSONObject>> configMap = new HashMap<>();
+            // 该用户所有实验合集
+            Set<String> expCodes = new HashSet<>();
+            for (Map<String, Object> map : mapList) {
+                String expCode = map.getOrDefault("abExpCode", "").toString();
                 expCodes.add(expCode);
-                if("555".equals(expCode)){
-                    configMap=JSONObject.parseObject(map.get("configValue").toString(),Map.class);
+                if ("555".equals(expCode)) {
+                    configMap = JSONObject.parseObject(map.get("configValue").toString(), Map.class);
                 }
             }
-            //先判断是否开启实验 和是否不出广告时间 而后判断默认0-8
-            //不出广告时间判定
-            int hourOfDay= DateUtils.getCurrentHour();
-            Boolean condition1=abTestConfigContainer.inAdTimeTest(requestParam.getAbExpInfo());
-            Boolean condition2=abTestConfigContainer.containsCode(configMap,requestParam.getAbTestCode());
-            if(condition1
+            // 先判断是否开启实验 和是否不出广告时间 而后判断默认0-8
+            // 不出广告时间判定
+            int hourOfDay = DateUtils.getCurrentHour();
+            Boolean condition1 = abTestConfigContainer.inAdTimeTest(requestParam.getAbExpInfo());
+            Boolean condition2 = abTestConfigContainer.containsCode(configMap, requestParam.getAbTestCode());
+            if (condition1
                     &&
                     condition2
                     &&
-                    abTestConfigContainer.inWithoutAdTime(configMap,requestParam.getAbTestCode(),hourOfDay)){
+                    abTestConfigContainer.inWithoutAdTime(configMap, requestParam.getAbTestCode(), hourOfDay)) {
                 // 开启555 & 555的配置包含abcode & 命中555为这个code配置的不出广告时间
                 result.put("ad_predict", 1);
                 result.put("no_ad_strategy", "no_ad_time_with_time_plan");
@@ -123,20 +124,20 @@ public class PredictModelServiceImpl implements PredictModelService {
                 result.put("no_ad_strategy", "no_ad_time_with_fixed_time");
                 return result;
             }
-            String abtestId=null;
-            String abTestConfigTag=null;
-            Map<String, Object> abtestParam=null;
-            String midGroup =null;
-            String shareType =null;
+            String abtestId = null;
+            String abTestConfigTag = null;
+            Map<String, Object> abtestParam = null;
+            String midGroup = null;
+            String shareType = null;
 
-            String[] appIdArr=oldExpGroupAppId.split(",");
+            String[] appIdArr = oldExpGroupAppId.split(",");
             // 新老实验系统
-            List<String> appIdList=Arrays.asList(appIdArr);
-            if(appIdList.contains(requestParam.getAppType().toString())){
+            List<String> appIdList = Arrays.asList(appIdArr);
+            if (appIdList.contains(requestParam.getAppType().toString())) {
 //            if(appIdArr.contains(requestParam.getAppType())){
                 String[] abParamArr = abConfig.getAbParams(requestParam.getAbTestCode(), requestParam.getAbExpInfo());
                 if (abParamArr == null) {
-                    abParamArr= NewExpUserGroupConfig.newExpUserGroupMap.get(requestParam.getAppType().toString());
+                    abParamArr = NewExpUserGroupConfig.newExpUserGroupMap.get(requestParam.getAppType().toString());
                     if (abParamArr == null) {
                         result.put("msg", "abConfig_error");
                         return result;
@@ -159,11 +160,11 @@ public class PredictModelServiceImpl implements PredictModelService {
 //        }else {
 //            midGroup = redisHelper.getString(midGroupKeyName);
 //        }
-                //没有时为新用户或者无分享用户
-                shareType =midGroup;
+                // 没有时为新用户或者无分享用户
+                shareType = midGroup;
                 if (midGroup == null) {
                     midGroup = "mean_group";
-                    shareType="noShare";
+                    shareType = "noShare";
                 }
                 String[] noAdMidGroupList = new String[0];
                 noAdMidGroupList = ((JSONArray) abtestParam.get("no_ad_mid_group_list")).toArray(noAdMidGroupList);
@@ -175,7 +176,7 @@ public class PredictModelServiceImpl implements PredictModelService {
                         break;
                     }
                 }
-                //不出广告组
+                // 不出广告组
                 if (inNoAdGroup) {
                     // User is in the no-ad group, no ad should be shown
                     result.put("mid_group", midGroup);
@@ -183,7 +184,7 @@ public class PredictModelServiceImpl implements PredictModelService {
                     result.put("no_ad_strategy", "no_ad_mid_group_with_video");
                     return result;
                 }
-                //top1广告不出视频
+                // top1广告不出视频
                 Map<String, List<String>> noAdGroupWithVideoMapping = (Map) abtestParam.getOrDefault("no_ad_group_with_video_mapping", new HashMap<>());
                 if (noAdGroupWithVideoMapping.keySet().contains(midGroup)
                         &&
@@ -194,22 +195,21 @@ public class PredictModelServiceImpl implements PredictModelService {
                     result.put("no_ad_strategy", "no_ad_mid_group_with_video");
                     return result;
                 }
-            }else {
-                String midGroupKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_MID_GROUP +  "class1:" + requestParam.getMid();
+            } else {
+                String midGroupKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_MID_GROUP + "class1:" + requestParam.getMid();
                 midGroup = redisHelper.getString(midGroupKeyName);
-                shareType =midGroup;
+                shareType = midGroup;
                 if (midGroup == null) {
                     midGroup = "mean_group";
-                    shareType="noShare";
+                    shareType = "noShare";
                 }
             }
 
 
-
-            //市-中文
+            // 市-中文
             requestParam.setRegion(requestParam.getRegion().replace("省", ""));
             requestParam.setCity(requestParam.getCity().replace("市", ""));
-            //设置信息
+            // 设置信息
             ThresholdPredictModelParam modelParam = ThresholdPredictModelParam.builder()
                     .build();
             BeanUtils.copyProperties(requestParam, modelParam);
@@ -219,34 +219,45 @@ public class PredictModelServiceImpl implements PredictModelService {
             modelParam.setAbtestParam(abtestParam);
             modelParam.setMidGroup(midGroup);
             modelParam.setExtraParam(new HashMap<>());
-            modelParam.addUserExtraFuture("shareType",shareType);
+            modelParam.addUserExtraFuture("shareType", shareType);
             setExtraParam(modelParam);
 
+            String appTypeStr = requestParam.getAppType().toString();
+
+            boolean in676Exp = expCodes.contains("676")
+                    || NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(expCodes, appTypeStr, requestParam.getNewExpGroup(), "676", modelParam);
+            if (in676Exp) {
+                result = ThresholdModelContainer.getThresholdPredictModel("random676").predict(modelParam);
+                // 如果676实验返回结果,表示未命中规则即对应的用户来源和所属层存在配置,使用676实验的结果,否则继续走599实验
+                if (Objects.nonNull(result)) {
+                    return result;
+                }
+            }
+
             // 新老实验系统兼容
-            if(expCodes.contains("599")||
-                    (expCodes.contains(NewExpInfoHelper.flagId)&&NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(),requestParam.getNewExpGroup(),"599",modelParam))){
+            if (expCodes.contains("599") ||
+                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "599", modelParam))) {
                 // NewExpInfoHelper.flagId   647
                 result = ThresholdModelContainer.
                         getThresholdPredictModel("random")
                         .predict(modelParam);
-            }else if(expCodes.contains("667")||
-                    (expCodes.contains(NewExpInfoHelper.flagId)&&NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(),requestParam.getNewExpGroup(),"667",modelParam))){
+            } else if (expCodes.contains("667") ||
+                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "667", modelParam))) {
                 // NewExpInfoHelper.flagId   647
                 result = ThresholdModelContainer.
                         getThresholdPredictModel("random667")
                         .predict(modelParam);
-            }else if(inExpList(expCodes,adPredictImmersionExpCode)
+            } else if (inExpList(expCodes, adPredictImmersionExpCode)
                     ||
-                    (expCodes.contains(NewExpInfoHelper.flagId)&&NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
-                            requestParam.getAppType().toString(),requestParam.getNewExpGroup(),"607",modelParam))){
+                    (expCodes.contains(NewExpInfoHelper.flagId) && NewExpInfoHelper.checkInNewExpGroupAndSetParamIfIn(
+                            requestParam.getAppType().toString(), requestParam.getNewExpGroup(), "607", modelParam))) {
                 // adPredictImmersionExpCode 607 631
                 result = ThresholdModelContainer.
                         getThresholdPredictModel("immersion")
                         .predict(modelParam);
-            }
-            else {
+            } else {
                 Object thresholdMixFunc = abtestParam.getOrDefault("threshold_mix_func", "basic");
                 result = ThresholdModelContainer.
                         getThresholdPredictModel(thresholdMixFunc.toString())
@@ -254,9 +265,9 @@ public class PredictModelServiceImpl implements PredictModelService {
             }
 
             return result;
-        }catch (Exception e){
+        } catch (Exception e) {
             log.error("svc=adPredict appType={} group={} newGroup={} pqtId={}"
-                    ,requestParam.getAppType(),requestParam.getAbTestCode(),requestParam.getNewExpGroup(),requestParam.getPqtId());
+                    , requestParam.getAppType(), requestParam.getAbTestCode(), requestParam.getNewExpGroup(), requestParam.getPqtId());
             result.put("ad_predict", 1);
             result.put("no_ad_strategy", "error");
             return result;
@@ -292,24 +303,25 @@ public class PredictModelServiceImpl implements PredictModelService {
                 .predict(modelParam);
     }
 
-    public void setExtraParam(ThresholdPredictModelParam modelParam){
-        String[] ids=testIds.split(",");
-        List<String> idList=Arrays.asList(ids);
-        List<Map<String,Object>> mapList=(List)modelParam.getAbExpInfo().get("ab_test002");
-        Collections.sort(mapList,new Comparator<Map<String, Object>>() {
+    public void setExtraParam(ThresholdPredictModelParam modelParam) {
+        String[] ids = testIds.split(",");
+        List<String> idList = Arrays.asList(ids);
+        List<Map<String, Object>> mapList = (List) modelParam.getAbExpInfo().get("ab_test002");
+        Collections.sort(mapList, new Comparator<Map<String, Object>>() {
             @Override
             public int compare(Map<String, Object> map1, Map<String, Object> map2) {
-                int abExpCode1 =Integer.parseInt(map1.get("abExpCode").toString()) ;
-                int abExpCode2 =Integer.parseInt(map2.get("abExpCode").toString());
+                int abExpCode1 = Integer.parseInt(map1.get("abExpCode").toString());
+                int abExpCode2 = Integer.parseInt(map2.get("abExpCode").toString());
                 return Integer.compare(abExpCode1, abExpCode2);
             }
         });
-        Map<String,Object> configMap;
-        for(Map<String,Object> map:mapList){
-            if(idList.contains(map.getOrDefault("abExpCode",""))){
-                configMap=JSONObject.parseObject(map.get("configValue").toString(),new TypeReference<Map<String,Object>>(){});
-                for(Map.Entry<String,Object> entry:configMap.entrySet()){
-                    modelParam.getExtraParam().put(entry.getKey(),entry.getValue());
+        Map<String, Object> configMap;
+        for (Map<String, Object> map : mapList) {
+            if (idList.contains(map.getOrDefault("abExpCode", ""))) {
+                configMap = JSONObject.parseObject(map.get("configValue").toString(), new TypeReference<Map<String, Object>>() {
+                });
+                for (Map.Entry<String, Object> entry : configMap.entrySet()) {
+                    modelParam.getExtraParam().put(entry.getKey(), entry.getValue());
                 }
             }
         }
@@ -318,10 +330,10 @@ public class PredictModelServiceImpl implements PredictModelService {
     }
 
 
-    boolean inExpList(Set<String> set,String expCodes){
-        String[] expArr=expCodes.split(",");
-        for(String str:expArr){
-            if(set.contains(str)){
+    boolean inExpList(Set<String> set, String expCodes) {
+        String[] expArr = expCodes.split(",");
+        for (String str : expArr) {
+            if (set.contains(str)) {
                 return true;
             }
         }

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

@@ -0,0 +1,69 @@
+package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
+
+import com.alibaba.fastjson.JSON;
+import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
+import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
+import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 676实验
+ */
+@Component
+public class RandomPredict676Model extends ThresholdPredictModel {
+    private final static Logger log = LoggerFactory.getLogger(RandomPredict676Model.class);
+
+    @Override
+    String initName() {
+        return "random676";
+    }
+
+
+    @Override
+    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
+        // 如果用户的外部来源和分享所属层为空,则跳过
+        if (StringUtils.isAnyBlank(modelParam.getUserExternalSource(), modelParam.getShareLayer())) {
+            return null;
+        }
+
+        //  如果配置不存在,则跳过
+        String abParamKey = String.format("%s:%s", modelParam.getUserExternalSource(), modelParam.getShareLayer());
+        if (!modelParam.getExtraParam().containsKey(abParamKey)) {
+            return null;
+        }
+
+        Map<String, Object> abParam = new HashMap<>();
+        try {
+            abParam.putAll((Map<String, ?>) modelParam.getExtraParam().get(abParamKey));
+        } catch (Exception e) {
+            log.error("get abParam error: ", e);
+        }
+        int hash = modelParam.getMid().hashCode();
+        hash = hash < 0 ? -hash : hash;
+        double score = (hash + RandWContainer.getRandW()) % 100 / 100d;
+
+        String keySuffix = modelParam.getUserExtraFuture("shareType").toString()
+                .replace("return", "")
+                .replace("mids", "");
+        Integer appType = modelParam.getAppType();
+
+        double threshold = Double.parseDouble(abParam.getOrDefault(appType + "_" + keySuffix, -1).toString());
+        if (threshold < 0d) {
+            threshold = Double.parseDouble(abParam.getOrDefault("default_" + keySuffix, "-1").toString());
+        }
+        Map<String, Object> result = new HashMap<>();
+        result.put("ad_predict", score < threshold ? 2 : 1);
+        result.put("score", score);
+        result.put("threshold", threshold);
+        result.put("model", "random");
+
+        return result;
+    }
+
+}

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

@@ -42,6 +42,18 @@ public class ThresholdPredictModelParam {
     String city = "-1";
     MachineInfoParam machineInfo = new MachineInfoParam();
 
+
+    private String userExternalSource;
+
+    /**
+     * 分享所属层
+     * <br />
+     * 1. firstLayer: 首层
+     * <br />
+     * 2. otherLayer: 裂变层
+     */
+    private String shareLayer;
+
     Map<String,Object> extraParam=new HashMap<>();
     Map<String,Object> userExtraFutureMap=new HashMap<>();
 

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

@@ -22,8 +22,19 @@ public class ThresholdPredictModelRequestParam {
     Long careModelStatus;
     Integer newExpGroup;
     String region = "-1";
-    //市-中文
+    // 市-中文
     String city = "-1";
     String pqtId;
     MachineInfoParam machineInfo = new MachineInfoParam();
+
+    private String userExternalSource;
+
+    /**
+     * 分享所属层
+     * <br />
+     * 1. firstLayer: 首层
+     * <br />
+     * 2. otherLayer: 裂变层
+     */
+    private String shareLayer;
 }