|
@@ -1,16 +1,21 @@
|
|
|
package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
|
|
|
import com.tzld.piaoquan.ad.engine.service.predict.config.AdOutV1OnlineWeightConfig;
|
|
|
import com.tzld.piaoquan.ad.engine.service.predict.constant.RuleRedisKeyConst;
|
|
|
import com.tzld.piaoquan.ad.engine.service.predict.containner.ThresholdModelContainer;
|
|
|
import com.tzld.piaoquan.ad.engine.service.predict.param.RuleParamHelper;
|
|
|
import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
|
|
|
+@Component
|
|
|
public class ScoreThresholdPredictModel extends ThresholdPredictModel{
|
|
|
|
|
|
@Autowired
|
|
@@ -19,6 +24,26 @@ public class ScoreThresholdPredictModel extends ThresholdPredictModel{
|
|
|
@Autowired
|
|
|
AlgorithmRedisHelper redisHelper;
|
|
|
|
|
|
+// Map<String,Object> configMap=new HashMap<>();
|
|
|
+// @PostConstruct
|
|
|
+// private void initParams(){
|
|
|
+// Timer timer = new Timer();
|
|
|
+// // 半小时更新一次
|
|
|
+// timer.schedule(new TimerTask() {
|
|
|
+// @Override
|
|
|
+// public void run() {
|
|
|
+// loadConfig();
|
|
|
+// }
|
|
|
+// }, 0, 1000*60*30);
|
|
|
+// }
|
|
|
+
|
|
|
+// public void loadConfig(){
|
|
|
+//
|
|
|
+// configMap=new HashMap<>();
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
@Override
|
|
|
String initName() {
|
|
|
return "model";
|
|
@@ -34,18 +59,67 @@ public class ScoreThresholdPredictModel extends ThresholdPredictModel{
|
|
|
String userScore = redisHelper.get(userKeyName);
|
|
|
String itemScore = redisHelper.get(itemKeyName);
|
|
|
|
|
|
- if (userScore == null || itemScore == null) {
|
|
|
+ //加载配置数据
|
|
|
+ String configKeyNamePrefix = RuleRedisKeyConst.KEY_NAME_PREFIX_AD_OUT_MODEL_CONFIG
|
|
|
+ + modelKey + ":" + modelParam.getAbtestId() + ":"
|
|
|
+// + modelParam.getAbTestConfigTag();
|
|
|
+ + modelParam.getAbtestParam().get("abtest_config_tag");
|
|
|
+ String configKey = configKeyNamePrefix + ":config";
|
|
|
+ String configStr = redisHelper.get(configKey);
|
|
|
+ Map<String, Object> configMap = new HashMap<>();
|
|
|
+ String hitStrategy="model";
|
|
|
+ if (configStr != null) {
|
|
|
+ try {
|
|
|
+ configMap= JSONObject.parseObject(configStr);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 处理 JSON 解析异常
|
|
|
+ e.printStackTrace();
|
|
|
+ result = ThresholdModelContainer.
|
|
|
+ getBasicPredictModel()
|
|
|
+ .predict(modelParam);
|
|
|
+ hitStrategy="error";
|
|
|
+ result.put("hit_strategy",hitStrategy);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean useBackup = Boolean.valueOf((String)configMap.getOrDefault("use_backup_key","false"));
|
|
|
+
|
|
|
+
|
|
|
+ //有数据为空且开启兜底策略
|
|
|
+ if (
|
|
|
+ (StringUtils.isBlank(userScore) || StringUtils.isBlank(itemScore))
|
|
|
+ &&useBackup)
|
|
|
+ {
|
|
|
// If offline scores are empty, fall back to baseline logic
|
|
|
result = ThresholdModelContainer.
|
|
|
getBasicPredictModel()
|
|
|
.predict(modelParam);
|
|
|
+ hitStrategy="backup";
|
|
|
+ result.put("hit_strategy",hitStrategy);
|
|
|
return result;
|
|
|
}
|
|
|
- String configKeyPrefix = RuleRedisKeyConst.KEY_NAME_PREFIX_AD_OUT_MODEL_CONFIG
|
|
|
- + modelKey + ":" + modelParam.getAbtestParam().get("abtest_id") + ":"
|
|
|
- + modelParam.getAbtestParam().get("abtest_config_tag");
|
|
|
- String thresholdKey = configKeyPrefix + ":threshold";
|
|
|
- double offlineScore = Double.parseDouble(userScore) + Double.parseDouble(itemScore);
|
|
|
+
|
|
|
+ double offlineScore ;
|
|
|
+ //处理空值逻辑
|
|
|
+ double threshold=(double)configMap.getOrDefault("threshold",0);
|
|
|
+ if(!StringUtils.isBlank(userScore)&&!StringUtils.isBlank(itemScore)){
|
|
|
+
|
|
|
+ }else if(StringUtils.isBlank(userScore)&&StringUtils.isBlank(itemScore)){
|
|
|
+ itemScore="0";
|
|
|
+ threshold=(double)configMap.getOrDefault("item_threshold", 0);
|
|
|
+
|
|
|
+ }else {
|
|
|
+ boolean isUserScoreBlank=StringUtils.isBlank(userScore);
|
|
|
+ userScore
|
|
|
+ }
|
|
|
+ if(!StringUtils.isBlank(itemScore)){
|
|
|
+ userScore="0";
|
|
|
+ threshold=(double)configMap.getOrDefault("user_threshold", 0);
|
|
|
+ result.put("hit_strategy","error");
|
|
|
+ }
|
|
|
+ offlineScore=Double.parseDouble(userScore) + Double.parseDouble(itemScore);
|
|
|
|
|
|
SimpleDateFormat hourFormat = new SimpleDateFormat("HH");
|
|
|
SimpleDateFormat weekDayFormat = new SimpleDateFormat("u");
|
|
@@ -56,14 +130,25 @@ public class ScoreThresholdPredictModel extends ThresholdPredictModel{
|
|
|
onlineFeatures.put("ctx_week", weekDayFormat.format(modelParam.getDate()));
|
|
|
onlineFeatures.put("ctx_hour", hourFormat.format(modelParam.getDate()));
|
|
|
|
|
|
+ //新模型更新权重计算
|
|
|
+ double rankScore = 0.0;
|
|
|
+ if ((Boolean) configMap.getOrDefault("use_rank_score", false)) {
|
|
|
+ String rankScoreKey = "rank:score1:" + modelParam.getVideoId();
|
|
|
+ String rankScoreStr = redisHelper.get(rankScoreKey);
|
|
|
+ if (rankScoreStr != null) {
|
|
|
+ rankScore = Double.parseDouble(rankScoreStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
double onlineScore=getOlineScore(onlineFeatures);
|
|
|
+ double rankScoreBias = (double)configMap.getOrDefault("rank_score_bias", 0.0);
|
|
|
double finalScore =getFinalScore(onlineScore,offlineScore);
|
|
|
-
|
|
|
- String thresholdValue = redisHelper.get(thresholdKey);
|
|
|
- double threshold = (thresholdValue != null) ? Double.parseDouble(thresholdValue) : 0.0;
|
|
|
+ double rankScoreW = (double)configMap.getOrDefault("rank_score_w", 1.0);
|
|
|
+ double finalScoreW = (double)configMap.getOrDefault("final_score_w", 1.0);
|
|
|
+ double mergeScore = finalScoreW * finalScore + rankScoreW * (rankScore + rankScoreBias);
|
|
|
|
|
|
int adPredict;
|
|
|
- if (finalScore < threshold) {
|
|
|
+ if (mergeScore < threshold) {
|
|
|
// If final score is below threshold, show the ad
|
|
|
adPredict = 2;
|
|
|
} else {
|