|
|
@@ -8,6 +8,9 @@ import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.enums.CrowdLayerEnum;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.enums.FilterTypeEnum;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.enums.RedisPrefixEnum;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.helper.CreativeKFinalDataHelper;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.helper.LayerAgentFlowControlDataHelper;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.helper.LayerCustomerFlowControlDataHelper;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.redis.AdRedisHelper;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
|
|
|
@@ -15,6 +18,8 @@ import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.util.ObjUtil;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.util.RootSessionIdExpConfig;
|
|
|
+import com.tzld.piaoquan.ad.engine.commons.util.RootSessionIdTailUtil;
|
|
|
import com.tzld.piaoquan.ad.engine.service.entity.*;
|
|
|
import com.tzld.piaoquan.ad.engine.service.feature.Feature;
|
|
|
import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
|
|
|
@@ -47,6 +52,21 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
@ApolloJsonValue("${h5.score.suppress:{}}")
|
|
|
private Map<String, Double> h5ScoreSuppress;
|
|
|
|
|
|
+ @ApolloJsonValue("${rerank.strategy.flow.ctl.customer:{}}")
|
|
|
+ private Map<String, Double> flowCtlCustomerParams;
|
|
|
+
|
|
|
+ @ApolloJsonValue("${rerank.strategy.flow.ctl.agent:{}}")
|
|
|
+ private Map<String, Double> flowCtlAgentParams;
|
|
|
+
|
|
|
+ @ApolloJsonValue("${rerank.root.session.id.tail.config:[]}")
|
|
|
+ private List<RootSessionIdExpConfig> rerankRootSessionIdConfig;
|
|
|
+
|
|
|
+ @ApolloJsonValue("${h5.score.suppress.customer.white:[]}")
|
|
|
+ private Set<Long> customerIdWhiteSet;
|
|
|
+
|
|
|
+ @Value("${rank.strategy.default.cxr:0.000001}")
|
|
|
+ protected Double defaultCxr;
|
|
|
+
|
|
|
@Value("${guarantee.exp:742}")
|
|
|
protected String guaranteeExp;
|
|
|
|
|
|
@@ -407,6 +427,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
String clazzL4 = userLayer.getOrDefault("class_l4", "近期未出现");
|
|
|
map.put("layer_l4", layerL4);
|
|
|
map.put("clazz_l4", clazzL4);
|
|
|
+ map.put("rootSessionId", rootSessionId);
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
@@ -1118,6 +1139,7 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
reqFeature.put("landingPageType", String.valueOf(adPlatformCreativeDTO.getLandingPageType()));
|
|
|
reqFeature.put("category_name", adPlatformCreativeDTO.getCategoryName());
|
|
|
reqFeature.put("material_md5", adPlatformCreativeDTO.getMaterialMd5());
|
|
|
+ reqFeature.put("agentId", adPlatformCreativeDTO.getAgentId() != null ? String.valueOf(adPlatformCreativeDTO.getAgentId()) : "");
|
|
|
reqFeature.put("ad_profession_id", adPlatformCreativeDTO.getAdProfessionId() != null ? String.valueOf(adPlatformCreativeDTO.getAdProfessionId()) : "");
|
|
|
reqFeature.put("ad_profession_name", adPlatformCreativeDTO.getAdProfessionName() != null ? adPlatformCreativeDTO.getAdProfessionName() : "");
|
|
|
reqFeature.put("ad_category_name", adPlatformCreativeDTO.getAdCategoryName());
|
|
|
@@ -1204,6 +1226,14 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
if (org.springframework.util.CollectionUtils.isEmpty(h5ScoreSuppress) || Objects.isNull(item)) {
|
|
|
return 1.0;
|
|
|
}
|
|
|
+
|
|
|
+ Long customerId = item.getCustomerId();
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(customerIdWhiteSet) && Objects.nonNull(customerId) && customerIdWhiteSet.contains(customerId)) {
|
|
|
+ log.info("getH5SuppressWeight 客户命中白名单, customerId:{}", customerId);
|
|
|
+ return 1.0;
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
Integer landingPageType = item.getLandingPageType();
|
|
|
String profession = item.getProfession();
|
|
|
@@ -1219,6 +1249,16 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
return 1.0;
|
|
|
}
|
|
|
|
|
|
+ protected double getDefaultCxr(double cxr) {
|
|
|
+ try {
|
|
|
+ if (null != defaultCxr) {
|
|
|
+ return Math.max(cxr, defaultCxr);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("cxr", e);
|
|
|
+ }
|
|
|
+ return cxr;
|
|
|
+ }
|
|
|
|
|
|
protected boolean landingH5Page(AdRankItem item) {
|
|
|
if (Objects.isNull(item)) {
|
|
|
@@ -1332,4 +1372,125 @@ public abstract class RankStrategyBasic implements RankStrategy {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // rerank
|
|
|
+ protected void calRerankWeight(ScoreParam scoreParam, String layer, List<AdRankItem> items) {
|
|
|
+ try {
|
|
|
+ List<RootSessionIdExpConfig> expConfigs = RootSessionIdTailUtil.getRootSessionIdTailConfig(scoreParam, RootSessionIdTailUtil.reRankTailN, rerankRootSessionIdConfig);
|
|
|
+ if (expConfigs.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Set<String> hit = new HashSet<>();
|
|
|
+ for (RootSessionIdExpConfig expConfig : expConfigs) {
|
|
|
+ if (null != expConfig && null != expConfig.getConfig()) {
|
|
|
+ String rerankStrategy = expConfig.getConfig().get("rerank");
|
|
|
+ if (null == rerankStrategy || hit.contains(rerankStrategy)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ hit.add(rerankStrategy);
|
|
|
+ switch (rerankStrategy) {
|
|
|
+ case "flowCtlC":
|
|
|
+ calFlowControlWeight(rerankStrategy, layer, items, flowCtlCustomerParams);
|
|
|
+ break;
|
|
|
+ case "flowCtlA":
|
|
|
+ calFlowControlWeight(rerankStrategy, layer, items, flowCtlAgentParams);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ calCreativeKFinalWeight("kFinal",items);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("cal rerank weight error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 控制流量
|
|
|
+ protected void calFlowControlWeight(String flowCtlType, String layer, List<AdRankItem> items, Map<String, Double> flowControlParams) {
|
|
|
+ try {
|
|
|
+ if (org.springframework.util.CollectionUtils.isEmpty(flowControlParams)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ double cpmPow = flowControlParams.getOrDefault("cpmPow", 0.3);
|
|
|
+ double lowerCpmWeight = flowControlParams.getOrDefault("lowerCpmWeight", 1.0);
|
|
|
+ double upperCpmWeight = flowControlParams.getOrDefault("upperCpmWeight", 1.2);
|
|
|
+ double flowPow = flowControlParams.getOrDefault("flowPow", 1.2);
|
|
|
+ double lowerFlowWeight = flowControlParams.getOrDefault("lowerFlowWeight", 0.77);
|
|
|
+ double upperFlowWeight = flowControlParams.getOrDefault("upperFlowWeight", 1.0);
|
|
|
+
|
|
|
+ double hitViewRate = flowControlParams.getOrDefault("hitViewRate", 0.05);
|
|
|
+ double plusViewRate = flowControlParams.getOrDefault("plusViewRate", 20.0);
|
|
|
+ double viewRatePow = flowControlParams.getOrDefault("viewRatePow", 0.2);
|
|
|
+ double viewRateScale = flowControlParams.getOrDefault("viewRateScale", 0.5491);
|
|
|
+ if ("flowCtlC".equals(flowCtlType)) {
|
|
|
+ for (AdRankItem item : items) {
|
|
|
+ String profession = item.getProfession();
|
|
|
+ String customerId = String.valueOf(item.getCustomerId());
|
|
|
+ Pair<Double, Double> pair = LayerCustomerFlowControlDataHelper.getWeight(layer, profession, customerId);
|
|
|
+ double flowWeight = getFlowControlWeight(pair,
|
|
|
+ cpmPow, lowerCpmWeight, upperCpmWeight,
|
|
|
+ flowPow, lowerFlowWeight, upperFlowWeight,
|
|
|
+ hitViewRate, plusViewRate, viewRatePow, viewRateScale);
|
|
|
+ item.getScoreMap().put(flowCtlType, flowWeight);
|
|
|
+ }
|
|
|
+ } else if ("flowCtlA".equals(flowCtlType)) {
|
|
|
+ for (AdRankItem item : items) {
|
|
|
+ String profession = item.getProfession();
|
|
|
+ String agentId = String.valueOf(item.getAgentId());
|
|
|
+ Pair<Double, Double> pair = LayerAgentFlowControlDataHelper.getWeight(layer, profession, agentId);
|
|
|
+ double flowWeight = getFlowControlWeight(pair,
|
|
|
+ cpmPow, lowerCpmWeight, upperCpmWeight,
|
|
|
+ flowPow, lowerFlowWeight, upperFlowWeight,
|
|
|
+ hitViewRate, plusViewRate, viewRatePow, viewRateScale);
|
|
|
+ item.getScoreMap().put(flowCtlType, flowWeight);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("cal flow control weight error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 加V打压系数
|
|
|
+ protected void calCreativeKFinalWeight(String flowCtlType, List<AdRankItem> items) {
|
|
|
+ try {
|
|
|
+ for (AdRankItem item : items) {
|
|
|
+ Double kFinal = CreativeKFinalDataHelper.getKFinal(item.getCreativeCode());
|
|
|
+ if(kFinal != null){
|
|
|
+ item.getScoreMap().put(flowCtlType, kFinal);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("calCreativeKFinalWeight weight error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private double getFlowControlWeight(Pair<Double, Double> pair,
|
|
|
+ double cpmPow, double lowerCpmWeight, double upperCpmWeight,
|
|
|
+ double flowPow, double lowerFlowWeight, double upperFlowWeight,
|
|
|
+ double hitViewRate, double plusViewRate, double viewRatePow, double viewRateScale) {
|
|
|
+ try {
|
|
|
+ if (null != pair) {
|
|
|
+ double cpmWeight = 1;
|
|
|
+ double flowWeight = 1;
|
|
|
+ double cpmDiff = pair.getLeft();
|
|
|
+ double viewRate = pair.getRight();
|
|
|
+ if (cpmDiff > 0) {
|
|
|
+ cpmWeight = Math.pow(cpmDiff, cpmPow);
|
|
|
+ cpmWeight = Math.min(Math.max(lowerCpmWeight, cpmWeight), upperCpmWeight);
|
|
|
+ }
|
|
|
+ if (viewRate > hitViewRate) {
|
|
|
+ flowWeight = 1 / Math.pow(viewRate * 100 + plusViewRate, viewRatePow) / viewRateScale;
|
|
|
+ flowWeight = Math.pow(flowWeight, flowPow);
|
|
|
+ flowWeight = Math.min(Math.max(lowerFlowWeight, flowWeight), upperFlowWeight);
|
|
|
+ }
|
|
|
+ return cpmWeight * flowWeight;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("flowWeight error", e);
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
}
|