|
@@ -1,9 +1,12 @@
|
|
|
package com.tzld.piaoquan.ad.engine.service.score;
|
|
|
|
|
|
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
|
|
|
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.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.ObjUtil;
|
|
|
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.dto.AdPlatformCreativeDTO;
|
|
@@ -15,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.xm.Similarity;
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.IOException;
|
|
@@ -27,8 +31,8 @@ import java.util.stream.Collectors;
|
|
|
@Service
|
|
|
public class RankService680 {
|
|
|
|
|
|
- @Value("${id.feature.default.value:0.01}")
|
|
|
- private String idDefaultValue;
|
|
|
+ @ApolloJsonValue("${no.postback.conversion.adverids:[]}")
|
|
|
+ private Set<String> noPostbackConversionAdVerIds;
|
|
|
|
|
|
@Autowired
|
|
|
private FeatureService featureService;
|
|
@@ -43,11 +47,7 @@ public class RankService680 {
|
|
|
|
|
|
|
|
|
// 特征处理
|
|
|
- long start = System.currentTimeMillis();
|
|
|
Feature feature = this.getFeature(scoreParam, request);
|
|
|
- long getFeatureElapsed = System.currentTimeMillis() - start;
|
|
|
-
|
|
|
- long invokeFeatureServiceElapsed = feature.getElapsed();
|
|
|
|
|
|
Map<String, Map<String, String>> userFeature = feature.getUserFeature();
|
|
|
Map<String, Map<String, String>> videoFeature = feature.getVideoFeature();
|
|
@@ -62,12 +62,14 @@ public class RankService680 {
|
|
|
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);
|
|
|
|
|
|
List<AdRankItem> adRankItems = new ArrayList<>(request.getAdIdList().size());
|
|
|
for (AdPlatformCreativeDTO dto : request.getAdIdList()) {
|
|
@@ -79,8 +81,7 @@ public class RankService680 {
|
|
|
adRankItem.setCpa(dto.getCpa());
|
|
|
adRankItem.setId(dto.getAdId());
|
|
|
adRankItem.setCampaignId(dto.getCampaignId());
|
|
|
- adRankItem.getExt().put("getFeatureElapsed", getFeatureElapsed);
|
|
|
- adRankItem.getExt().put("invokeFeatureServiceElapsed", invokeFeatureServiceElapsed);
|
|
|
+ adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
|
|
|
|
|
|
String cidStr = dto.getCreativeId().toString();
|
|
|
Map<String, String> cidFeatureMap = new HashMap<>();
|
|
@@ -91,10 +92,9 @@ public class RankService680 {
|
|
|
|
|
|
Map<String, String> d1Feature = cidFeature.getOrDefault("alg_cid_feature_vid_cf", new HashMap<>());
|
|
|
|
|
|
-
|
|
|
this.handleB1Feature(b1Feature, cidFeatureMap, cidStr);
|
|
|
|
|
|
- this.handleB2ToB5AndB8Feature(cidFeature, adVerFeature, cidFeatureMap);
|
|
|
+ this.handleB2ToB5AndB8ToB9Feature(cidFeature, adVerFeature, cidFeatureMap);
|
|
|
|
|
|
this.handleB6ToB7Feature(cidFeature, cidFeatureMap);
|
|
|
|
|
@@ -107,6 +107,8 @@ public class RankService680 {
|
|
|
String title = b1Feature.getOrDefault("cidtitle", "");
|
|
|
this.handleE1AndE2Feature(e1Feature, e2Feature, title, cidFeatureMap);
|
|
|
|
|
|
+ this.handleD3AndB1Feature(d3Feature, title, cidFeatureMap);
|
|
|
+
|
|
|
adRankItem.setFeatureMap(cidFeatureMap);
|
|
|
|
|
|
adRankItems.add(adRankItem);
|
|
@@ -114,25 +116,27 @@ public class RankService680 {
|
|
|
}
|
|
|
|
|
|
// 分桶
|
|
|
- long featureBucketStart = System.currentTimeMillis();
|
|
|
this.readBucketFile();
|
|
|
userFeatureMap = this.featureBucket(userFeatureMap);
|
|
|
for (AdRankItem adRankItem : adRankItems) {
|
|
|
Map<String, String> featureMap = adRankItem.getFeatureMap();
|
|
|
adRankItem.setFeatureMap(this.featureBucket(featureMap));
|
|
|
- adRankItem.getExt().put("featureBucketElapsed", System.currentTimeMillis() - featureBucketStart);
|
|
|
}
|
|
|
|
|
|
// 打分排序
|
|
|
- long scoreStart = System.currentTimeMillis();
|
|
|
List<AdRankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.LR_ROV_SCORE_20240626)
|
|
|
- .scoring(new HashMap<>(), userFeatureMap, adRankItems);
|
|
|
- long scoreElapsed = System.currentTimeMillis() - scoreStart;
|
|
|
+ .scoring(sceneFeatureMap, userFeatureMap, adRankItems);
|
|
|
for (AdRankItem item : result) {
|
|
|
item.setScore(item.getLrScore() * item.getCpa());
|
|
|
item.getScoreMap().put("cpa", item.getCpa());
|
|
|
+ item.getScoreMap().put("cpm", item.getCpm());
|
|
|
item.getFeatureMap().putAll(userFeatureMap);
|
|
|
- item.getExt().put("scoreElapsed", scoreElapsed);
|
|
|
+ item.getFeatureMap().putAll(sceneFeatureMap);
|
|
|
+
|
|
|
+ // 没有转化回传的广告主,使用后台配置的CPM
|
|
|
+ if (noPostbackConversionAdVerIds.contains(item.getAdVerId())) {
|
|
|
+ item.setScore(item.getCpm() / 1000);
|
|
|
+ }
|
|
|
|
|
|
for (Map.Entry<String, Map<String, String>> entry : videoFeature.entrySet()) {
|
|
|
if (MapUtils.isNotEmpty(entry.getValue())) {
|
|
@@ -159,19 +163,6 @@ public class RankService680 {
|
|
|
item.getMetaFeatureMap().put(entry.getKey(), entry.getValue());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // if (MapUtils.isNotEmpty(videoFeature)) {
|
|
|
- // item.getMetaFeatureMap().putAll(videoFeature);
|
|
|
- // }
|
|
|
- // if (MapUtils.isNotEmpty(userFeature)) {
|
|
|
- // item.getMetaFeatureMap().putAll(userFeature);
|
|
|
- // }
|
|
|
- // if (allAdVerFeature.containsKey(item.getAdVerId())) {
|
|
|
- // item.getMetaFeatureMap().putAll(allAdVerFeature.get(item.getAdVerId()));
|
|
|
- // }
|
|
|
- // if (allCidFeature.containsKey(String.valueOf(item.getAdId()))) {
|
|
|
- // item.getMetaFeatureMap().putAll(allCidFeature.get(String.valueOf(item.getAdId())));
|
|
|
- // }
|
|
|
}
|
|
|
|
|
|
Collections.sort(result);
|
|
@@ -195,14 +186,14 @@ public class RankService680 {
|
|
|
}
|
|
|
|
|
|
private void handleB1Feature(Map<String, String> b1Feature, Map<String, String> cidFeatureMap, String cid) {
|
|
|
- cidFeatureMap.put("cid_" + cid, "0.01");
|
|
|
+ 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.01");
|
|
|
+ cidFeatureMap.put("adverid_" + adVerId, "0.1");
|
|
|
}
|
|
|
// if (StringUtils.isNotBlank(b1Feature.get("targeting_conversion"))) {
|
|
|
// String targetingConversion = b1Feature.get("targeting_conversion");
|
|
@@ -214,20 +205,22 @@ public class RankService680 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void handleB2ToB5AndB8Feature(Map<String, Map<String, String>> c1Feature, Map<String, Map<String, String>> adVerFeature, Map<String, String> cidFeatureMap) {
|
|
|
+ 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("3h", "6h", "12h", "1d", "3d", "7d");
|
|
|
+ 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<>(b8Feature, "b8"),
|
|
|
+ new Tuple2<>(b9Feature, "b9")
|
|
|
);
|
|
|
for (Tuple2<Map<String, String>, String> tuple2 : featureList) {
|
|
|
Map<String, String> feature = tuple2.f1;
|
|
@@ -242,7 +235,7 @@ public class RankService680 {
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(f2));
|
|
|
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)));
|
|
|
+ // cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_click", String.valueOf(click));
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_conver*log(view)", String.valueOf(conver * NumUtil.log(view)));
|
|
@@ -274,7 +267,7 @@ public class RankService680 {
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_ctcvr", String.valueOf(f2));
|
|
|
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)));
|
|
|
+ // cidFeatureMap.put(prefix + "_" + time + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_click", String.valueOf(click));
|
|
|
cidFeatureMap.put(prefix + "_" + time + "_conver*log(view)", String.valueOf(conver * NumUtil.log(view)));
|
|
@@ -312,7 +305,7 @@ public class RankService680 {
|
|
|
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)));
|
|
|
+ // featureMap.put("ecpm_all", String.valueOf(NumUtil.div(incomeAll * 1000, viewAll)));
|
|
|
|
|
|
return midActionList;
|
|
|
}
|
|
@@ -355,8 +348,8 @@ public class RankService680 {
|
|
|
}
|
|
|
if (midActionStatic.containsKey("actionstatic_conver_" + cid) && midActionStatic.containsKey("actionstatic_click_" + cid)) {
|
|
|
double cvr = NumUtil.div(
|
|
|
- midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0),
|
|
|
- midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0)
|
|
|
+ midActionStatic.getOrDefault("actionstatic_conver_" + cid, 0.0),
|
|
|
+ midActionStatic.getOrDefault("actionstatic_click_" + cid, 0.0)
|
|
|
);
|
|
|
featureMap.put("actionstatic_cvr", String.valueOf(cvr));
|
|
|
}
|
|
@@ -372,7 +365,7 @@ public class RankService680 {
|
|
|
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)));
|
|
|
+ // featureMap.put("d1_feature_" + prefix + "_ecpm", String.valueOf(NumUtil.div(income * 1000, view)));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -381,7 +374,8 @@ public class RankService680 {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- List<String> prefixes1 = Arrays.asList("ctr", "ctcvr", "ecpm");
|
|
|
+ // 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) {
|
|
@@ -397,6 +391,15 @@ public class RankService680 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void handleD3AndB1Feature(Map<String, String> d3Feature, String cTitle, Map<String, String> featureMap) {
|
|
|
+ if (MapUtils.isEmpty(d3Feature) || !d3Feature.containsKey("title") || StringUtils.isEmpty(cTitle)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String vTitle = d3Feature.get("title");
|
|
|
+ double 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) {
|
|
|
if (StringUtils.isEmpty(title)) {
|
|
|
return;
|
|
@@ -485,12 +488,19 @@ public class RankService680 {
|
|
|
return vidRankMaps;
|
|
|
}
|
|
|
|
|
|
+ public Map<String, String> handleSceneFeature(long ts) {
|
|
|
+ Map<String, String> sceneFeatureMap = new HashMap<>();
|
|
|
+ sceneFeatureMap.put("hour_" + DateUtils.getHourByTimestamp(ts), "0.1");
|
|
|
+ sceneFeatureMap.put("dayofweek_" + DateUtils.getDayOrWeekByTimestamp(ts), "0.1");
|
|
|
+ return sceneFeatureMap;
|
|
|
+ }
|
|
|
+
|
|
|
private void readBucketFile() {
|
|
|
if (MapUtils.isNotEmpty(bucketsMap)) {
|
|
|
return;
|
|
|
}
|
|
|
synchronized (this) {
|
|
|
- InputStream resourceStream = RankService680.class.getClassLoader().getResourceAsStream("20240704_ad_bucket_351.txt");
|
|
|
+ InputStream resourceStream = RankService680.class.getClassLoader().getResourceAsStream("20240718_ad_bucket_688.txt");
|
|
|
if (resourceStream != null) {
|
|
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream))) {
|
|
|
Map<String, double[]> bucketsMap = new HashMap<>();
|