Преглед на файлове

Merge branch 'refs/heads/dev-xym-extract-public-methods' into pre-master

# Conflicts:
#	ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy688.java
xueyiming преди 4 дни
родител
ревизия
34e3c1d1ae

+ 27 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/entity/FeatureContainer.java

@@ -0,0 +1,27 @@
+package com.tzld.piaoquan.ad.engine.service.entity;
+
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+public class FeatureContainer {
+
+    private Map<String, Map<String, String>> userFeature = new HashMap<>();
+    private Map<String, Map<String, String>> videoFeature = new HashMap<>();
+    private Map<String, Map<String, Map<String, String>>> adVerFeature = new HashMap<>();
+    private Map<String, Map<String, Map<String, String>>> cidFeature = new HashMap<>();
+    private Map<String, Map<String, Map<String, String>>> skuFeature = new HashMap<>();
+
+
+    private Map<String, String> reqFeature;
+    private Map<String, String> sceneFeatureMap;
+    private Map<String, String> c1Feature;
+    private Map<String, String> d2Feature;
+    private Map<String, String> d3Feature;
+    private Map<String, String> e1Feature;
+    private Map<String, String> e2Feature;
+    private Map<String, String> g1Feature;
+    private Map<String, String> g2Feature;
+}

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

@@ -4,6 +4,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
+import com.tzld.piaoquan.ad.engine.commons.util.ExtractorUtils;
+import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
+import com.tzld.piaoquan.ad.engine.commons.util.SimilarityUtils;
+import com.tzld.piaoquan.ad.engine.service.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.commons.enums.RedisPrefixEnum;
 import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
@@ -11,16 +15,25 @@ 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.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+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.stream.Collectors;
 
+import static com.tzld.piaoquan.ad.engine.commons.math.Const.*;
+
 @Slf4j
 public abstract class RankStrategyBasic implements RankStrategy {
 
@@ -34,6 +47,10 @@ public abstract class RankStrategyBasic implements RankStrategy {
     protected String guaranteeExp;
     @ApolloJsonValue("${alpha:1.0}")
     protected Double alpha;
+
+    @Value("${word2vec.exp:694}")
+    protected String word2vecExp;
+
     @Autowired
     private FeatureService featureService;
     @Autowired
@@ -135,6 +152,41 @@ public abstract class RankStrategyBasic implements RankStrategy {
         return sceneFeatureMap;
     }
 
+    protected FeatureContainer extractAndProcessFeatures(
+            ScoreParam scoreParam,
+            RankRecommendRequestParam request,
+            long ts) {
+        FeatureContainer container = new FeatureContainer();
+        Feature feature = getFeature(scoreParam, request);
+        // 基础特征
+        container.setUserFeature(feature.getUserFeature());
+        container.setVideoFeature(feature.getVideoFeature());
+        container.setAdVerFeature(feature.getAdVerFeature());
+        container.setCidFeature(feature.getCidFeature());
+        container.setSkuFeature(feature.getSkuFeature());
+
+        // 处理后的特征
+        container.setReqFeature(getReqFeature(scoreParam, request));
+        container.setSceneFeatureMap(handleSceneFeature(ts));
+
+        // 子特征
+        container.setC1Feature(container.getUserFeature()
+                .getOrDefault("alg_mid_feature_ad_action", new HashMap<>()));
+        container.setD2Feature(container.getVideoFeature()
+                .getOrDefault("alg_cid_feature_vid_cf_rank", new HashMap<>()));
+        container.setD3Feature(container.getVideoFeature()
+                .getOrDefault("alg_vid_feature_basic_info", new HashMap<>()));
+        container.setE1Feature(container.getUserFeature()
+                .getOrDefault("alg_mid_feature_return_tags", new HashMap<>()));
+        container.setE2Feature(container.getUserFeature()
+                .getOrDefault("alg_mid_feature_share_tags", new HashMap<>()));
+        container.setG1Feature(container.getUserFeature()
+                .getOrDefault("mid_return_video_cate", new HashMap<>()));
+        container.setG2Feature(container.getUserFeature()
+                .getOrDefault("mid_share_video_cate", new HashMap<>()));
+
+        return container;
+    }
 
     protected static class Tuple5 {
         public String f1;
@@ -264,4 +316,353 @@ public abstract class RankStrategyBasic implements RankStrategy {
             return 1.0;
         }
     }
+
+    protected 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);
+        }
+    }
+
+    protected 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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
+                double cpc = NumUtil.div(income, click);
+                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
+                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
+                double ecpm = ctr * cpc * 1000;
+                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
+                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
+                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
+                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
+
+                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 * ctcvr));
+            }
+        }
+
+    }
+
+    protected 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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
+                double cpc = NumUtil.div(income, click);
+                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
+                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
+                double ecpm = ctr * cpc * 1000;
+                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
+                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
+                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
+                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
+                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
+
+                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 * ctcvr));
+            }
+        }
+
+    }
+
+    protected 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)));
+        featureMap.put("ecpm_all", String.valueOf(NumUtil.div(incomeAll * 1000, viewAll)));
+
+        return midActionList;
+    }
+
+    protected 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));
+        }
+    }
+
+    protected 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"));
+            double cpc = NumUtil.div(income, click);
+            double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
+            featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(ctr));
+            featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR)));
+            featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
+            featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
+            featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(ctr * cpc * 1000));
+        }
+    }
+
+    protected 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", "ecpm");
+        // 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)));
+                    }
+                }
+            }
+        }
+    }
+
+    protected 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));
+    }
+
+    protected 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 = ExtractorUtils.funcC34567ForTags(tags, title);
+                    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]));
+                }
+            }
+        }
+    }
+
+    protected 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;
+    }
+
+    protected 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;
+    }
+
+    protected 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;
+    }
+
+    protected void setMetaFeatureMap(FeatureContainer featureContainer, AdRankItem adRankItem) {
+        Map<String, Map<String, String>> userFeature = featureContainer.getUserFeature();
+        Map<String, Map<String, String>> videoFeature = featureContainer.getVideoFeature();
+        Map<String, Map<String, Map<String, String>>> allAdVerFeature = featureContainer.getAdVerFeature();
+        Map<String, Map<String, Map<String, String>>> allCidFeature = featureContainer.getCidFeature();
+        Map<String, Map<String, Map<String, String>>> allSkuFeature = featureContainer.getSkuFeature();
+        for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
+            if (MapUtils.isNotEmpty(entry.getValue())) {
+                adRankItem.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        for (Map.Entry<String, Map<String, String>> entry : userFeature.entrySet()) {
+            if (MapUtils.isNotEmpty(entry.getValue())) {
+                adRankItem.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(adRankItem.getAdVerId(), new HashMap<>());
+        for (Map.Entry<String, Map<String, String>> entry : adVerFeature.entrySet()) {
+            if (MapUtils.isNotEmpty(entry.getValue())) {
+                adRankItem.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(String.valueOf(adRankItem.getAdId()), new HashMap<>());
+        for (Map.Entry<String, Map<String, String>> entry : cidFeature.entrySet()) {
+            if (MapUtils.isNotEmpty(entry.getValue())) {
+                adRankItem.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(adRankItem.getSkuId()), new HashMap<>());
+        for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
+            if (MapUtils.isNotEmpty(entry.getValue())) {
+                adRankItem.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
+            }
+        }
+        adRankItem.getMetaFeatureMap().put("reqFeature", featureContainer.getReqFeature());
+        adRankItem.getMetaFeatureMap().put("sceneFeature", featureContainer.getSceneFeatureMap());
+    }
+
+
 }

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

@@ -7,10 +7,12 @@ 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.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 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.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
@@ -64,33 +66,13 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
         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, Map<String, Map<String, String>>> allSkuFeature = feature.getSkuFeature();
-        Map<String, String> reqFeature = this.getReqFeature(scoreParam, request);
-
+        FeatureContainer featureContainer = this.extractAndProcessFeatures(scoreParam, request, ts);
 
         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);
-
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(featureContainer.getC1Feature(), 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);
+        Map<String, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(featureContainer.getD2Feature());
         long time1 = System.currentTimeMillis();
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
@@ -120,10 +102,10 @@ public class RankStrategyBy679 extends RankStrategyBasic {
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                    Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                    Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
 
                     Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
@@ -160,19 +142,19 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         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, Map<String, String>> cidFeature = featureContainer.getCidFeature().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);
+                    this.handleE1AndE2Feature(featureContainer.getE1Feature(), featureContainer.getE2Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
             });
             ThreadPoolFactory.defaultPool().submit(() -> {
                 try {
-                    this.handleD3AndB1Feature(d3Feature, title, item.getFeatureMap(), scoreParam);
+                    this.handleD3AndB1Feature(featureContainer.getD3Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
@@ -209,7 +191,7 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         long time4 = System.currentTimeMillis();
         // 打分排序
         // getScorerPipeline
-        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_20241105).scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_20241105).scoring(featureContainer.getSceneFeatureMap(), userFeatureMap, adRankItems);
         long time5 = System.currentTimeMillis();
         // loop
         double cpmCoefficient = weightParam.getOrDefault("cpmCoefficient", 0.9);
@@ -224,47 +206,14 @@ public class RankStrategyBy679 extends RankStrategyBasic {
             item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
             item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
             item.getFeatureMap().putAll(userFeatureMap);
-            item.getFeatureMap().putAll(sceneFeatureMap);
+            item.getFeatureMap().putAll(featureContainer.getSceneFeatureMap());
 
             // 没有转化回传的广告主,使用后台配置的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());
-                }
-            }
-
-            Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(item.getSkuId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-            item.getMetaFeatureMap().put("reqFeature", reqFeature);
-            item.getMetaFeatureMap().put("sceneFeature", sceneFeatureMap);
+            setMetaFeatureMap(featureContainer, item);
         }
 
         log.info("cost={}, feature1={}, feature2={}, feature31={}, feature32={}, feature4={}, getScorerPipeline={}, " +
@@ -277,19 +226,8 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         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) {
+    protected 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<>());
@@ -330,7 +268,7 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
     }
 
-    private void handleB6ToB7Feature(Map<String, Map<String, String>> c1Feature, Map<String, String> cidFeatureMap) {
+    protected 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<>());
 
@@ -363,79 +301,8 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
     }
 
-    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)));
-        featureMap.put("ecpm_all", String.valueOf(NumUtil.div(incomeAll * 1000, viewAll)));
-
-        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) {
+    protected 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"));
@@ -449,45 +316,8 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         }
     }
 
-    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", "ecpm");
-        // 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) {
+    protected void handleE1AndE2Feature(Map<String, String> e1Feature, Map<String, String> e2Feature, String title,
+                                        Map<String, String> featureMap, ScoreParam scoreParam) {
         if (StringUtils.isEmpty(title)) {
             return;
         }
@@ -519,62 +349,6 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         }
     }
 
-    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;
-    }
-
     private void readBucketFile() {
         if (MapUtils.isNotEmpty(bucketsMap)) {
             return;

+ 12 - 379
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy680.java

@@ -5,6 +5,7 @@ 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.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -72,35 +73,14 @@ public class RankStrategyBy680 extends RankStrategyBasic {
 
         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, Map<String, Map<String, String>>> allSkuFeature = feature.getSkuFeature();
-        Map<String, String> reqFeature = this.getReqFeature(scoreParam, request);
-
+        FeatureContainer featureContainer = this.extractAndProcessFeatures(scoreParam, request, ts);
 
         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);
-
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(featureContainer.getC1Feature(), 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);
+        Map<String, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(featureContainer.getD2Feature());
         long time1 = System.currentTimeMillis();
-
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
         Random random = new Random();
@@ -130,10 +110,10 @@ public class RankStrategyBy680 extends RankStrategyBasic {
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                    Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                    Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
 
                     Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
@@ -170,19 +150,19 @@ public class RankStrategyBy680 extends RankStrategyBasic {
         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, Map<String, String>> cidFeature = featureContainer.getCidFeature().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);
+                    this.handleE1AndE2Feature(featureContainer.getE1Feature(), featureContainer.getE2Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
             });
             ThreadPoolFactory.defaultPool().submit(() -> {
                 try {
-                    this.handleD3AndB1Feature(d3Feature, title, item.getFeatureMap(), scoreParam);
+                    this.handleD3AndB1Feature(featureContainer.getD3Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
@@ -216,7 +196,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
         long time4 = System.currentTimeMillis();
         // 打分排序
         // getScorerPipeline
-        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_20240909).scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_20240909).scoring(featureContainer.getSceneFeatureMap(), userFeatureMap, adRankItems);
         long time5 = System.currentTimeMillis();
 
         // calibrate score for negative sampling
@@ -242,7 +222,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
             item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
             item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
             item.getFeatureMap().putAll(userFeatureMap);
-            item.getFeatureMap().putAll(sceneFeatureMap);
+            item.getFeatureMap().putAll(featureContainer.getSceneFeatureMap());
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
@@ -255,40 +235,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
 
         if (CollectionUtils.isNotEmpty(result)) {
             AdRankItem top1Item = result.get(0);
-            for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            for (Map.Entry<String, Map<String, String>> entry : userFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(top1Item.getAdVerId(), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : adVerFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(String.valueOf(top1Item.getAdId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : cidFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(top1Item.getSkuId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-            top1Item.getMetaFeatureMap().put("reqFeature", reqFeature);
-            top1Item.getMetaFeatureMap().put("sceneFeature", sceneFeatureMap);
+            setMetaFeatureMap(featureContainer, top1Item);
         }
         long time6 = System.currentTimeMillis();
         log.info("cost={}, getFeature={}, handleFeature={},  similar={}, bucketFeature={}, getScorerPipeline={}, " +
@@ -299,319 +246,6 @@ public class RankStrategyBy680 extends RankStrategyBasic {
         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("adid"))) {
-        //     String adId = b1Feature.get("adid");
-        //     cidFeatureMap.put("adid_" + adId, idDefaultValue);
-        // }
-        if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
-            String adVerId = b1Feature.get("adverid");
-            cidFeatureMap.put("adverid_" + adVerId, "0.1");
-        }
-        // if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
-        //     String targetingConversion = b1Feature.get("targeting_conversion");
-        //     cidFeatureMap.put("targeting_conversion_" + targetingConversion, idDefaultValue);
-        // }
-        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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    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)));
-        featureMap.put("ecpm_all", String.valueOf(NumUtil.div(incomeAll * 1000, viewAll)));
-
-        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"));
-            double cpc = NumUtil.div(income, click);
-            double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-            featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(ctr));
-            featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
-            featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(ctr * cpc * 1000));
-        }
-    }
-
-    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", "ecpm");
-        // 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 = ExtractorUtils.funcC34567ForTags(tags, title);
-                    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;
-    }
-
     private void readBucketFile() {
         if (MapUtils.isNotEmpty(bucketsMap)) {
             return;
@@ -670,5 +304,4 @@ public class RankStrategyBy680 extends RankStrategyBasic {
 
         return newFeatureMap;
     }
-
 }

+ 12 - 373
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy683.java

@@ -5,6 +5,7 @@ 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.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -73,33 +74,17 @@ public class RankStrategyBy683 extends RankStrategyBasic {
 
         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, Map<String, Map<String, String>>> allSkuFeature = feature.getSkuFeature();
-        Map<String, String> reqFeature = this.getReqFeature(scoreParam, request);
-
+        FeatureContainer featureContainer = this.extractAndProcessFeatures(scoreParam, request, ts);
 
         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);
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(featureContainer.getC1Feature(), 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, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(featureContainer.getD2Feature());
 
-        Map<String, String> sceneFeatureMap = this.handleSceneFeature(ts);
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
@@ -131,10 +116,10 @@ public class RankStrategyBy683 extends RankStrategyBasic {
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                    Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                    Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
 
                     Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
@@ -171,19 +156,19 @@ public class RankStrategyBy683 extends RankStrategyBasic {
         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, Map<String, String>> cidFeature = featureContainer.getCidFeature().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);
+                    this.handleE1AndE2Feature(featureContainer.getE1Feature(), featureContainer.getE2Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
             });
             ThreadPoolFactory.defaultPool().submit(() -> {
                 try {
-                    this.handleD3AndB1Feature(d3Feature, title, item.getFeatureMap(), scoreParam);
+                    this.handleD3AndB1Feature(featureContainer.getD3Feature(), title, item.getFeatureMap(), scoreParam);
                 } finally {
                     cdl2.countDown();
                 }
@@ -217,7 +202,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
         long time4 = System.currentTimeMillis();
         // 打分排序
         // getScorerPipeline
-        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_683).scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_683).scoring(featureContainer.getSceneFeatureMap(), userFeatureMap, adRankItems);
         long time5 = System.currentTimeMillis();
 
         // calibrate score for negative sampling
@@ -243,7 +228,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
             item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
             item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
             item.getFeatureMap().putAll(userFeatureMap);
-            item.getFeatureMap().putAll(sceneFeatureMap);
+            item.getFeatureMap().putAll(featureContainer.getSceneFeatureMap());
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
@@ -256,40 +241,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
 
         if (CollectionUtils.isNotEmpty(result)) {
             AdRankItem top1Item = result.get(0);
-            for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            for (Map.Entry<String, Map<String, String>> entry : userFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(top1Item.getAdVerId(), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : adVerFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(String.valueOf(top1Item.getAdId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : cidFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(top1Item.getSkuId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-            top1Item.getMetaFeatureMap().put("reqFeature", reqFeature);
-            top1Item.getMetaFeatureMap().put("sceneFeature", sceneFeatureMap);
+            setMetaFeatureMap(featureContainer, top1Item);
         }
         long time6 = System.currentTimeMillis();
         log.info("cost={}, getFeature={}, handleFeature={},  similar={}, bucketFeature={}, getScorerPipeline={}, " +
@@ -300,319 +252,6 @@ public class RankStrategyBy683 extends RankStrategyBasic {
         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("adid"))) {
-        //     String adId = b1Feature.get("adid");
-        //     cidFeatureMap.put("adid_" + adId, idDefaultValue);
-        // }
-        if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
-            String adVerId = b1Feature.get("adverid");
-            cidFeatureMap.put("adverid_" + adVerId, "0.1");
-        }
-        // if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
-        //     String targetingConversion = b1Feature.get("targeting_conversion");
-        //     cidFeatureMap.put("targeting_conversion_" + targetingConversion, idDefaultValue);
-        // }
-        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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    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)));
-        featureMap.put("ecpm_all", String.valueOf(NumUtil.div(incomeAll * 1000, viewAll)));
-
-        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"));
-            double cpc = NumUtil.div(income, click);
-            double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-            featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(ctr));
-            featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
-            featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(ctr * cpc * 1000));
-        }
-    }
-
-    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", "ecpm");
-        // 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 = ExtractorUtils.funcC34567ForTags(tags, title);
-                    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;
-    }
-
     private void readBucketFile() {
         if (MapUtils.isNotEmpty(bucketsMap)) {
             return;

+ 21 - 195
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy687.java

@@ -4,6 +4,7 @@ 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.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -50,32 +51,13 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
         long start = System.currentTimeMillis();
         // 特征处理
-        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, Map<String, Map<String, String>>> allSkuFeature = feature.getSkuFeature();
-        Map<String, String> reqFeature = this.getReqFeature(scoreParam, request);
-
+        FeatureContainer featureContainer = this.extractAndProcessFeatures(scoreParam, request, ts);
 
         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);
-
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(featureContainer.getC1Feature(), 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);
+        Map<String, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(featureContainer.getD2Feature());
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
@@ -103,10 +85,10 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
                 String cidStr = dto.getCreativeId().toString();
                 Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
 
                 Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
@@ -135,13 +117,13 @@ public class RankStrategyBy687 extends RankStrategyBasic {
                 ThreadPoolFactory.defaultPool().submit(() -> {
                     try {
                         String cidStr = String.valueOf(item.getAdId());
-                        Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                        Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().getOrDefault(cidStr, new HashMap<>());
                         Map<String, String> b1Feature = cidFeature.getOrDefault("alg_cid_feature_basic_info", new HashMap<>());
                         String title = b1Feature.getOrDefault("cidtitle", "");
                         long time21 = System.currentTimeMillis();
-                        this.handleE1AndE2Feature(e1Feature, e2Feature, title, item.getFeatureMap());
+                        this.handleE1AndE2Feature(featureContainer.getE1Feature(), featureContainer.getE2Feature(), title, item.getFeatureMap());
                         long time22 = System.currentTimeMillis();
-                        this.handleD3AndB1Feature(d3Feature, title, item.getFeatureMap());
+                        this.handleD3AndB1Feature(featureContainer.getD3Feature(), title, item.getFeatureMap());
                         long time23 = System.currentTimeMillis();
                         log.info("cost={} handleE1AndE2Feature={} handleD3AndB1Feature={}", time23 - time21, time22 - time21, time23 - time22);
                     } finally {
@@ -171,10 +153,10 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
                 String cidStr = dto.getCreativeId().toString();
                 Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
 
                 Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
@@ -192,9 +174,9 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
                 String title = b1Feature.getOrDefault("cidtitle", "");
                 long time21 = System.currentTimeMillis();
-                this.handleE1AndE2Feature(e1Feature, e2Feature, title, cidFeatureMap);
+                this.handleE1AndE2Feature(featureContainer.getE1Feature(), featureContainer.getE2Feature(), title, cidFeatureMap);
                 long time22 = System.currentTimeMillis();
-                this.handleD3AndB1Feature(d3Feature, title, cidFeatureMap);
+                this.handleD3AndB1Feature(featureContainer.getD3Feature(), title, cidFeatureMap);
                 long time23 = System.currentTimeMillis();
                 log.info("cost={} other={} handleE1AndE2Feature={} handleD3AndB1Feature={}", time23 - time20,
                         time21 - time20, time22 - time21, time23 - time22);
@@ -220,7 +202,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
         // 打分排序
         List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.XGBOOST_SCORE_CONF_683)
-                .scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+                .scoring(featureContainer.getSceneFeatureMap(), userFeatureMap, adRankItems);
 
         long time3 = System.currentTimeMillis();
         for (AdRankItem item : result) {
@@ -230,47 +212,15 @@ public class RankStrategyBy687 extends RankStrategyBasic {
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
             item.getFeatureMap().putAll(userFeatureMap);
-            item.getFeatureMap().putAll(sceneFeatureMap);
+            item.getFeatureMap().putAll(featureContainer.getSceneFeatureMap());
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
                 item.setScore(item.getCpm() / 1000);
             }
 
-            for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
+            setMetaFeatureMap(featureContainer, item);
 
-            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());
-                }
-            }
-
-            Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(item.getSkuId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-            item.getMetaFeatureMap().put("reqFeature", reqFeature);
-            item.getMetaFeatureMap().put("sceneFeature", sceneFeatureMap);
         }
 
         long time4 = System.currentTimeMillis();
@@ -282,27 +232,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
         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("adid"))) {
-        //     String adId = b1Feature.get("adid");
-        //     cidFeatureMap.put("adid_" + adId, idDefaultValue);
-        // }
-        if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
-            String adVerId = b1Feature.get("adverid");
-            cidFeatureMap.put("adverid_" + adVerId, "0.1");
-        }
-        // if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
-        //     String targetingConversion = b1Feature.get("targeting_conversion");
-        //     cidFeatureMap.put("targeting_conversion_" + targetingConversion, idDefaultValue);
-        // }
-        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) {
+    protected 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<>());
@@ -342,7 +272,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
     }
 
-    private void handleB6ToB7Feature(Map<String, Map<String, String>> c1Feature, Map<String, String> cidFeatureMap) {
+    protected 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<>());
 
@@ -374,7 +304,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
 
     }
 
-    private List<TupleMapEntry<Tuple5>> handleC1Feature(Map<String, String> c1Feature, Map<String, String> featureMap) {
+    protected List<TupleMapEntry<Tuple5>> handleC1Feature(Map<String, String> c1Feature, Map<String, String> featureMap) {
 
         // 用户特征
         List<TupleMapEntry<Tuple5>> midActionList = new ArrayList<>();
@@ -407,52 +337,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
         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) {
+    protected 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"));
@@ -466,7 +351,7 @@ public class RankStrategyBy687 extends RankStrategyBasic {
         }
     }
 
-    private void handleD2Feature(Map<String, Map<String, Double>> vidRankMaps, Map<String, String> featureMap, String cid) {
+    protected void handleD2Feature(Map<String, Map<String, Double>> vidRankMaps, Map<String, String> featureMap, String cid) {
         if (MapUtils.isEmpty(vidRankMaps)) {
             return;
         }
@@ -527,65 +412,6 @@ public class RankStrategyBy687 extends RankStrategyBasic {
         }
     }
 
-    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;
-    }
-
-
     private void readBucketFile() {
         if (MapUtils.isNotEmpty(bucketsMap)) {
             return;

+ 19 - 358
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy688.java

@@ -7,6 +7,7 @@ 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.entity.FeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -81,37 +82,15 @@ public class RankStrategyBy688 extends RankStrategyBasic {
 
         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, Map<String, Map<String, String>>> allSkuFeature = feature.getSkuFeature();
-        log.info("allSkuFeature={}", allSkuFeature);
-        Map<String, String> reqFeature = this.getReqFeature(scoreParam, request);
+        FeatureContainer featureContainer = this.extractAndProcessFeatures(scoreParam, request, ts);
 
         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);
-
+        List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(featureContainer.getC1Feature(), userFeatureMap);
         Map<String, Double> midTimeDiffMap = this.parseC1FeatureListToTimeDiffMap(midActionList, ts);
         Map<String, Double> actionStaticMap = this.parseC1FeatureListToActionStaticMap(midActionList);
+        Map<String, Map<String, Double>> vidRankMaps = this.parseD2FeatureMap(featureContainer.getD2Feature());
 
-        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> g1Feature = userFeature.getOrDefault("mid_return_video_cate", new HashMap<>());
-        Map<String, String> g2Feature = userFeature.getOrDefault("mid_share_video_cate", new HashMap<>());
-
-
+        Map<String, String> reqFeature = featureContainer.getReqFeature();
         userFeatureMap.put("brand", reqFeature.getOrDefault("brand", ""));
         userFeatureMap.put("region", reqFeature.getOrDefault("region", ""));
         userFeatureMap.put("city", reqFeature.getOrDefault("city", ""));
@@ -121,7 +100,11 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         userFeatureMap.put("root_source_scene", reqFeature.getOrDefault("root_source_scene", ""));
         userFeatureMap.put("root_source_channel", reqFeature.getOrDefault("root_source_channel", ""));
 
-
+        Map<String, String> d3Feature = featureContainer.getD3Feature();
+        Map<String, String> e1Feature = featureContainer.getE1Feature();
+        Map<String, String> e2Feature = featureContainer.getE2Feature();
+        Map<String, String> g1Feature = featureContainer.getG1Feature();
+        Map<String, String> g2Feature = featureContainer.getG2Feature();
         userFeatureMap.put("cate1", d3Feature.get("merge_first_level_cate"));
         userFeatureMap.put("cate2", d3Feature.get("merge_second_level_cate"));
         userFeatureMap.put("user_vid_return_tags_2h", e1Feature.getOrDefault("tags_2h", null));
@@ -136,9 +119,6 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         userFeatureMap.put("user_vid_return_cate2_14d", g1Feature.getOrDefault("cate2_14d", null));
         userFeatureMap.put("user_vid_share_cate1_14d", g2Feature.getOrDefault("cate1_14d", null));
         userFeatureMap.put("user_vid_share_cate2_14d", g2Feature.getOrDefault("cate2_14d", null));
-
-
-        Map<String, String> sceneFeatureMap = this.handleSceneFeature(ts);
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
@@ -169,11 +149,11 @@ public class RankStrategyBy688 extends RankStrategyBasic {
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
-                    Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
+                    Map<String, Map<String, String>> cidFeature = featureContainer.getCidFeature().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, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(dto.getSkuId()), new HashMap<>());
+                    Map<String, Map<String, String>> adVerFeature = featureContainer.getAdVerFeature().getOrDefault(dto.getAdVerId(), new HashMap<>());
+                    Map<String, Map<String, String>> skuFeature = featureContainer.getSkuFeature().getOrDefault(String.valueOf(dto.getSkuId()), new HashMap<>());
                     Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
 
                     this.handleB1Feature(b1Feature, cidFeatureMap, cidStr);
@@ -215,7 +195,7 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         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, Map<String, String>> cidFeature = featureContainer.getCidFeature().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(() -> {
@@ -248,7 +228,6 @@ public class RankStrategyBy688 extends RankStrategyBasic {
                 try {
                     Map<String, String> featureMap = adRankItem.getFeatureMap();
                     adRankItem.setFeatureMap(this.featureBucket(featureMap));
-                    log.info("adRankItem featureMap={}", adRankItem.getFeatureMap());
                 } finally {
                     cdl4.countDown();
                 }
@@ -262,7 +241,8 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         long time4 = System.currentTimeMillis();
         // 打分排序
         // getScorerPipeline
-        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.PAI_SCORE_CONF_20250214).scoring(sceneFeatureMap, userFeatureMap, adRankItems);
+        List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.PAI_SCORE_CONF_20250214)
+                .scoring(featureContainer.getSceneFeatureMap(), userFeatureMap, adRankItems);
         long time5 = System.currentTimeMillis();
 
         // calibrate score for negative sampling
@@ -288,7 +268,7 @@ public class RankStrategyBy688 extends RankStrategyBasic {
             item.getScoreMap().put("cpmCoefficient", cpmCoefficient);
             item.getScoreMap().put("scoreCoefficient", scoreCoefficient);
             item.getFeatureMap().putAll(userFeatureMap);
-            item.getFeatureMap().putAll(sceneFeatureMap);
+            item.getFeatureMap().putAll(featureContainer.getSceneFeatureMap());
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
@@ -296,45 +276,11 @@ public class RankStrategyBy688 extends RankStrategyBasic {
             }
         }
 
-
         result.sort(ComparatorUtil.equalsRandomComparator());
 
         if (CollectionUtils.isNotEmpty(result)) {
             AdRankItem top1Item = result.get(0);
-            for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            for (Map.Entry<String, Map<String, String>> entry : userFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(top1Item.getAdVerId(), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : adVerFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(String.valueOf(top1Item.getAdId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : cidFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-
-            Map<String, Map<String, String>> skuFeature = allSkuFeature.getOrDefault(String.valueOf(top1Item.getSkuId()), new HashMap<>());
-            for (Map.Entry<String, Map<String, String>> entry : skuFeature.entrySet()) {
-                if (MapUtils.isNotEmpty(entry.getValue())) {
-                    top1Item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
-                }
-            }
-            top1Item.getMetaFeatureMap().put("reqFeature", reqFeature);
-            top1Item.getMetaFeatureMap().put("sceneFeature", sceneFeatureMap);
+            setMetaFeatureMap(featureContainer, top1Item);
         }
         long time6 = System.currentTimeMillis();
         log.info("cost={}, getFeature={}, handleFeature={},  similar={}, bucketFeature={}, getScorerPipeline={}, " +
@@ -345,105 +291,8 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         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("adid"))) {
-        //     String adId = b1Feature.get("adid");
-        //     cidFeatureMap.put("adid_" + adId, idDefaultValue);
-        // }
-        if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
-            String adVerId = b1Feature.get("adverid");
-            cidFeatureMap.put("adverid_" + adVerId, "0.1");
-        }
-        // if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
-        //     String targetingConversion = b1Feature.get("targeting_conversion");
-        //     cidFeatureMap.put("targeting_conversion_" + targetingConversion, idDefaultValue);
-        // }
-        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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    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 income = Double.parseDouble(feature.getOrDefault("ad_income_" + time, "0"));
-                double cpc = NumUtil.div(income, click);
-                double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-                double ctcvr = NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR);
-                double ecpm = ctr * cpc * 1000;
-                cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(ctr));
-                cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(ctcvr));
-                cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-                cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
-                cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(ecpm));
-
-                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 * ctcvr));
-            }
-        }
-
-    }
-
-    private List<TupleMapEntry<Tuple5>> handleC1Feature(Map<String, String> c1Feature, Map<String, String> featureMap) {
+    protected List<TupleMapEntry<Tuple5>> handleC1Feature(Map<String, String> c1Feature, Map<String, String> featureMap) {
 
         //用户近1年内是否有转化
         if (c1Feature.containsKey("user_has_conver_1y") && c1Feature.get("user_has_conver_1y") != null) {
@@ -492,90 +341,11 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         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"));
-            double cpc = NumUtil.div(income, click);
-            double ctr = NumUtil.divSmoothV2(click, view, CTR_SMOOTH_BETA_FACTOR);
-            featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(ctr));
-            featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.divSmoothV2(conver, view, CTCVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.divSmoothV2(conver, click, CVR_SMOOTH_BETA_FACTOR)));
-            featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
-            featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(ctr * cpc * 1000));
-        }
-    }
-
-    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", "ecpm");
-        // 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 handleH1AndH2Feature(Map<String, Map<String, String>> skuFeature,
                                       Map<String, Map<String, String>> adVerFeature,
                                       Map<String, String> cidFeatureMap) {
         Map<String, String> h1Feature = adVerFeature.getOrDefault("alg_mid_feature_adver_action", new HashMap<>());
         Map<String, String> h2Feature = skuFeature.getOrDefault("alg_mid_feature_sku_action", new HashMap<>());
-        log.info("h1Feature={}", h1Feature);
-        log.info("h2Feature={}", h2Feature);
         List<String> timeList = Arrays.asList("3d", "7d", "30d");
         List<Tuple2<Map<String, String>, String>> featureList = Arrays.asList(
                 new Tuple2<>(h1Feature, "adverid"),
@@ -591,120 +361,11 @@ public class RankStrategyBy688 extends RankStrategyBasic {
                     cidFeatureMap.put("user" + "_" + prefix + "_" + "view" + "_" + time, split[0]);
                     cidFeatureMap.put("user" + "_" + prefix + "_" + "click" + "_" + time, split[1]);
                     cidFeatureMap.put("user" + "_" + prefix + "_" + "conver" + "_" + time, split[2]);
-                    log.info("user" + "_" + prefix + "_" + "view" + "_" + time, split[0]);
-                    log.info("user" + "_" + prefix + "_" + "click" + "_" + time, split[1]);
-                    log.info("user" + "_" + prefix + "_" + "conver" + "_" + time, split[2]);
                 }
             }
         }
-        log.info("handleH1AndH2Feature cidFeatureMap={}", cidFeatureMap);
-
-
-    }
-
-    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 = ExtractorUtils.funcC34567ForTags(tags, title);
-                    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;
     }
 
     private void readBucketFile() {