|
@@ -1,17 +1,411 @@
|
|
|
package com.tzld.piaoquan.ad.engine.service.score.impl;
|
|
|
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.util.ExtractorUtils;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
|
|
|
+import com.tzld.piaoquan.ad.engine.service.feature.Feature;
|
|
|
+import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
|
|
|
import com.tzld.piaoquan.ad.engine.service.score.RankService;
|
|
|
+import com.tzld.piaoquan.ad.engine.service.score.convert.RequestConvert;
|
|
|
+import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformCreativeDTO;
|
|
|
import com.tzld.piaoquan.ad.engine.service.score.param.RankRecommendRequestParam;
|
|
|
import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.MapUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneOffset;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
public class RankService680 implements RankService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FeatureService featureService;
|
|
|
+
|
|
|
@Override
|
|
|
public AdRankItem adItemRank(RankRecommendRequestParam request) {
|
|
|
+
|
|
|
+ long ts = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) / 1000;
|
|
|
+
|
|
|
+ ScoreParam scoreParam = RequestConvert.requestConvert(request);
|
|
|
+ Feature feature = this.getFeature(scoreParam, request);
|
|
|
+ Map<String, Map<String, String>> userFeature = feature.getUserFeature();
|
|
|
+ Map<String, Map<String, String>> videoFeature = feature.getVideoFeature();
|
|
|
+ Map<String, Map<String, Map<String, String>>> allAdVerFeature = feature.getAdVerFeature();
|
|
|
+ Map<String, Map<String, Map<String, String>>> allCidFeature = feature.getCidFeature();
|
|
|
+
|
|
|
+ Map<String, String> userFeatureMap = new HashMap<>();
|
|
|
+ Map<String, String> c1Feature = userFeature.getOrDefault("alg_mid_feature_ad_action", new HashMap<>());
|
|
|
+ List<TupleMapEntry<Tuple5>> midActionList = this.handleC1Feature(c1Feature, userFeatureMap);
|
|
|
+
|
|
|
+ Map<String, Double> midTimeDiffMap = this.parseC1FeatureListToTimeDiffMap(midActionList, ts);
|
|
|
+ Map<String, Double> actionStaticMap = this.parseC1FeatureListToActionStaticMap(midActionList);
|
|
|
+
|
|
|
+ Map<String, String> d1Feature = userFeature.getOrDefault("alg_mid_feature_ad_action", new HashMap<>());
|
|
|
+ this.handleD1Feature(d1Feature, userFeatureMap);
|
|
|
+
|
|
|
+ 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> d2Feature = videoFeature.getOrDefault("alg_cid_feature_vid_cf_rank", new HashMap<>());
|
|
|
+
|
|
|
+ for (AdPlatformCreativeDTO dto : request.getAdIdList()) {
|
|
|
+ String cidStr = dto.getCreativeId().toString();
|
|
|
+ Map<String, String> cidFeatureMap = new HashMap<>();
|
|
|
+ Map<String, Map<String, String>> cidFeature = allCidFeature.getOrDefault(cidStr, new HashMap<>());
|
|
|
+ Map<String, String> b1Feature = cidFeature.getOrDefault("alg_cid_feature_basic_info", new HashMap<>());
|
|
|
+
|
|
|
+ Map<String, Map<String, String>> adVerFeature = allAdVerFeature.getOrDefault(dto.getAdVerId(), new HashMap<>());
|
|
|
+
|
|
|
+ this.handleB1Feature(b1Feature, cidFeatureMap);
|
|
|
+
|
|
|
+ this.handleB2ToB5AndB8Feature(cidFeature, adVerFeature, cidFeatureMap);
|
|
|
+
|
|
|
+ this.handleB6ToB7Feature(cidFeature, cidFeatureMap);
|
|
|
+
|
|
|
+ this.handleC1UIFeature(midTimeDiffMap, actionStaticMap, cidFeatureMap, cidStr);
|
|
|
+
|
|
|
+ this.handleD2Feature(d2Feature, cidFeatureMap, cidStr);
|
|
|
+
|
|
|
+ String title = b1Feature.getOrDefault("cidtitle", "");
|
|
|
+ this.handleE1AndE2Feature(e1Feature, e2Feature, title, cidFeatureMap);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ private Feature getFeature(ScoreParam param, RankRecommendRequestParam request) {
|
|
|
+ List<AdPlatformCreativeDTO> adIdList = request.getAdIdList();
|
|
|
+ List<String> cidList = adIdList.stream()
|
|
|
+ .map(AdPlatformCreativeDTO::getCreativeId)
|
|
|
+ .map(Object::toString)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<String> adVerIdList = adIdList.stream()
|
|
|
+ .map(AdPlatformCreativeDTO::getAdVerId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ return featureService.getFeature(cidList, adVerIdList, param);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleB1Feature(Map<String, String> b1Feature, Map<String, String> cidFeatureMap) {
|
|
|
+ if (StringUtils.isNotBlank(b1Feature.get("adid"))) {
|
|
|
+ String adId = b1Feature.get("adid");
|
|
|
+ cidFeatureMap.put("adid_" + adId, "1");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(b1Feature.get("adverid"))) {
|
|
|
+ String adVerId = b1Feature.get("adverid");
|
|
|
+ cidFeatureMap.put("adverid_" + adVerId, "1");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
|
|
|
+ String targetingConversion = b1Feature.get("targeting_conversion");
|
|
|
+ cidFeatureMap.put("targeting_conversion_" + targetingConversion, "1");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(b1Feature.get("cpa"))) {
|
|
|
+ String cpa = b1Feature.get("cpa");
|
|
|
+ cidFeatureMap.put("cpa", cpa);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleB2ToB5AndB8Feature(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<>());
|
|
|
+
|
|
|
+ List<String> timeList = Arrays.asList("3h", "6h", "12h", "1d", "3d", "7d");
|
|
|
+ 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")
|
|
|
+ );
|
|
|
+ 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"));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(NumUtil.div(click, view)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(NumUtil.div(conver, view)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.div(conver, click)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ 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"));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ctr", String.valueOf(NumUtil.div(click, view)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(NumUtil.div(conver, view)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_cvr", String.valueOf(NumUtil.div(conver, click)));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_conver", String.valueOf(conver));
|
|
|
+ cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ })
|
|
|
+ .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_" + cid, String.valueOf(midTimeDiffMap.getOrDefault("timediff_view_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midTimeDiffMap.containsKey("timediff_click_" + cid)) {
|
|
|
+ featureMap.put("timediff_click_" + cid, String.valueOf(midTimeDiffMap.getOrDefault("timediff_click_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midTimeDiffMap.containsKey("timediff_conver_" + cid)) {
|
|
|
+ featureMap.put("timediff_conver_" + cid, String.valueOf(midTimeDiffMap.getOrDefault("timediff_conver_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midActionStatic.containsKey("actionstatic_view_" + cid)) {
|
|
|
+ featureMap.put("actionstatic_view_" + cid, String.valueOf(midActionStatic.getOrDefault("actionstatic_view_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midActionStatic.containsKey("actionstatic_click_" + cid)) {
|
|
|
+ featureMap.put("actionstatic_click_" + cid, String.valueOf(midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midActionStatic.containsKey("actionstatic_conver_" + cid)) {
|
|
|
+ featureMap.put("actionstatic_conver_" + cid, String.valueOf(midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0)));
|
|
|
+ }
|
|
|
+ if (midActionStatic.containsKey("actionstatic_income_" + cid)) {
|
|
|
+ featureMap.put("actionstatic_income_" + cid, 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("timediff_conver_" + cid)) {
|
|
|
+ double ctcvr = NumUtil.div(
|
|
|
+ midActionStatic.getOrDefault("timediff_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_click_" + cid, 0.0),
|
|
|
+ midActionStatic.getOrDefault("timediff_conver_" + cid, 0.0)
|
|
|
+ );
|
|
|
+ featureMap.put("actionstatic_cvr", String.valueOf(cvr));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleD1Feature(Map<String, String> d1Feature, Map<String, String> featureMap) {
|
|
|
+ for (String prefix : Arrays.asList("3h", "6h", "12h", "1d", "3d", "7d")) {
|
|
|
+ double view = Double.parseDouble(d1Feature.getOrDefault("ad_view_" + prefix, "0"));
|
|
|
+ double click = Double.parseDouble(d1Feature.getOrDefault("ad_click_" + prefix, "0"));
|
|
|
+ double conver = Double.parseDouble(d1Feature.getOrDefault("ad_conversion_" + prefix, "0"));
|
|
|
+ double income = Double.parseDouble(d1Feature.getOrDefault("ad_income_" + prefix, "0"));
|
|
|
+ featureMap.put("d1_feature_" + prefix + "_ctr", String.valueOf(NumUtil.div(click, view)));
|
|
|
+ featureMap.put("d1_feature_" + prefix + "_ctcvr", String.valueOf(NumUtil.div(conver, view)));
|
|
|
+ featureMap.put("d1_feature_" + prefix + "_cvr", String.valueOf(NumUtil.div(conver, click)));
|
|
|
+ featureMap.put("d1_feature_" + prefix + "_conver", String.valueOf(conver));
|
|
|
+ featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleD2Feature(Map<String, String> d2Feature, Map<String, String> featureMap, String cid) {
|
|
|
+ if (MapUtils.isEmpty(d2Feature)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> prefixes1 = Arrays.asList("ctr", "ctcvr", "ecpm");
|
|
|
+ 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 handleE1AndE2Feature(Map<String, String> e1Feature, Map<String, String> e2Feature, String title, Map<String, String> featureMap) {
|
|
|
+ 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);
|
|
|
+ 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;
|
|
|
+ long tsHistory = Long.parseLong(entry.value.f1);
|
|
|
+ long click = Long.parseLong(entry.value.f2);
|
|
|
+ long conver = Long.parseLong(entry.value.f3);
|
|
|
+ long d = (ts - tsHistory) / 3600 / 21;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class Tuple5 {
|
|
|
+ public String f1;
|
|
|
+ public String f2;
|
|
|
+ public String f3;
|
|
|
+ public String f4;
|
|
|
+ public String f5;
|
|
|
+
|
|
|
+ public Tuple5(String f1, String f2, String f3, String f4, String f5) {
|
|
|
+ this.f1 = f1;
|
|
|
+ this.f2 = f2;
|
|
|
+ this.f3 = f3;
|
|
|
+ this.f4 = f4;
|
|
|
+ this.f5 = f5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class TupleMapEntry<T> {
|
|
|
+ public String key;
|
|
|
+ public T value;
|
|
|
+
|
|
|
+ public TupleMapEntry(String key, T value) {
|
|
|
+ this.key = key;
|
|
|
+ this.value = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class Tuple2<F1, F2> {
|
|
|
+ public F1 f1;
|
|
|
+
|
|
|
+ public F2 f2;
|
|
|
+
|
|
|
+ public Tuple2(F1 first, F2 name) {
|
|
|
+ this.f1 = first;
|
|
|
+ this.f2 = name;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
}
|