|  | @@ -32,6 +32,10 @@ public class RankStrategy4RegionMergeModelV562 extends RankStrategy4RegionMergeM
 | 
	
		
			
				|  |  |      @ApolloJsonValue("${rank.score.merge.weightv562:}")
 | 
	
		
			
				|  |  |      private Map<String, Double> mergeWeight;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private FeatureService featureService;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -332,32 +336,102 @@ public class RankStrategy4RegionMergeModelV562 extends RankStrategy4RegionMergeM
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          List<RankItem> items = ScorerUtils.getScorerPipeline("feeds_score_config_20240807.conf")
 | 
	
		
			
				|  |  |                  .scoring(sceneFeatureMap, userFeatureMap, rankItems);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 获取VoV预测模型参数
 | 
	
		
			
				|  |  | +        // 融合权重
 | 
	
		
			
				|  |  | +        double alpha_vov = mergeWeight.getOrDefault("alpha_vov", 1.0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        double vov_thresh = mergeWeight.getOrDefault("vov_thresh", 0.1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        double view_thresh = mergeWeight.getOrDefault("view_thresh", 1535.0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        double level50_vov = mergeWeight.getOrDefault("level50_vov", 0.123);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        double level_95_vov = mergeWeight.getOrDefault("level_95_vov", 0.178);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        double beta_vov = mergeWeight.getOrDefault("beta_vov", 100.0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<Double> weightList = new ArrayList<>(7);
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("d2_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("d1_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("h48_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("h24_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("h3_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("h2_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +        weightList.add(mergeWeight.getOrDefault("h1_ago_vov_w", 0.0));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_rov:");
 | 
	
		
			
				|  |  | -        Map<String, Map<String, String>> vid2VovFeatureMap = this.getVideoRedisFeature(vids, "redis:vid_vov_1d3d:");
 | 
	
		
			
				|  |  | -        double alpha_vov = mergeWeight.getOrDefault("alpha_vov", 2.0);
 | 
	
		
			
				|  |  | +        Map<String, Map<String, String>> vid2VovFeatureMap = this.getVideoRedisFeature(vids, "redis:vid_vovhour4rank:");
 | 
	
		
			
				|  |  |          List<Video> result = new ArrayList<>();
 | 
	
		
			
				|  |  |  //        String hasReturnRovKey = mergeWeight.getOrDefault("hasReturnRovKey", 1.0) < 0.5 ? "rate_1" : "rate_n";
 | 
	
		
			
				|  |  |  //        Double chooseFunction = mergeWeight.getOrDefault("chooseFunction", 0.0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          for (RankItem item : items) {
 | 
	
		
			
				|  |  |              double score = 0.0;
 | 
	
		
			
				|  |  | -            double recommend_rate_1d = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | -                    .getOrDefault("recommend_rate_1d", "0"));
 | 
	
		
			
				|  |  | -            double recommend_exp_per_1d = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | -                    .getOrDefault("recommend_exp_per_1d", "0"));
 | 
	
		
			
				|  |  | -            double vorScore =  recommend_rate_1d * recommend_exp_per_1d;
 | 
	
		
			
				|  |  | -            item.getScoresMap().put("recommend_rate_1d", recommend_rate_1d);
 | 
	
		
			
				|  |  | -            item.getScoresMap().put("recommend_exp_per_1d", recommend_exp_per_1d);
 | 
	
		
			
				|  |  | -            item.getScoresMap().put("vorScore", vorScore);
 | 
	
		
			
				|  |  | -            item.getScoresMap().put("alpha_vov", alpha_vov);
 | 
	
		
			
				|  |  | -            double hasReturnRovScore = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | -                    .getOrDefault("rate_n", "0"));
 | 
	
		
			
				|  |  | -            item.getScoresMap().put("hasReturnRovScore", hasReturnRovScore);
 | 
	
		
			
				|  |  | +            // 获取其他模型输出score
 | 
	
		
			
				|  |  |              double fmRovOrigin = item.getScoreRov();
 | 
	
		
			
				|  |  |              item.getScoresMap().put("fmRovOrigin", fmRovOrigin);
 | 
	
		
			
				|  |  |              double fmRov = restoreScore(fmRovOrigin);
 | 
	
		
			
				|  |  |              item.getScoresMap().put("fmRov", fmRov);
 | 
	
		
			
				|  |  | -            score = fmRov * (1 + hasReturnRovScore) * (1.0 + alpha_vov * recommend_rate_1d);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 获取VoV输入特征
 | 
	
		
			
				|  |  | +            double h1_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h1_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double h2_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h2_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double h3_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h3_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double h24_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h24_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double h48_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h48_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double d1_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("d1_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +            double d2_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("d2_ago_vov", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            double h1_ago_view = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("h1_ago_view", "-2")); // 如果没有时,默认为多少?? 需要考虑
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h1_ago_vov", h1_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h2_ago_vov", h2_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h3_ago_vov", h3_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h24_ago_vov", h24_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h48_ago_vov", h48_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("d1_ago_vov", d1_ago_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("h1_ago_view", h1_ago_view);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("alpha_vov", alpha_vov);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("view_thresh", view_thresh);
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("vov_thresh", vov_thresh);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            List<Double> featureList = new ArrayList<>(7);
 | 
	
		
			
				|  |  | +            featureList.add(d2_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(d1_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(h48_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(h24_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(h3_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(h2_ago_vov);
 | 
	
		
			
				|  |  | +            featureList.add(h1_ago_vov);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // todo 线性加权 预测VoV
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            double vov_p = calculateScore(featureList, weightList,item,  vov_thresh, view_thresh, h1_ago_view,level50_vov,level_95_vov,beta_vov);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            double hasReturnRovScore = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>())
 | 
	
		
			
				|  |  | +                    .getOrDefault("rate_n", "0"));
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("hasReturnRovScore", hasReturnRovScore);
 | 
	
		
			
				|  |  | +            score = fmRov * (1 + hasReturnRovScore)  * (1.0 + alpha_vov * vov_p);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            item.getScoresMap().put("vov_p", vov_p);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              Video video = item.getVideo();
 | 
	
		
			
				|  |  |              video.setScore(score);
 | 
	
	
		
			
				|  | @@ -380,6 +454,55 @@ public class RankStrategy4RegionMergeModelV562 extends RankStrategy4RegionMergeM
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private  double calculateScore(List<Double> featureList, List<Double> weightList,RankItem rankItem,
 | 
	
		
			
				|  |  | +                                        double vov_thresh, double view_thresh, double h1_ago_view,double level50_vov,double level_95_vov,double beta_vov) {
 | 
	
		
			
				|  |  | +        // 检查 h1_ago_view 条件
 | 
	
		
			
				|  |  | +        if (h1_ago_view == -2 || h1_ago_view == -1 || h1_ago_view < view_thresh) {
 | 
	
		
			
				|  |  | +            rankItem.getScoresMap().put("origin_vov_p", 0d);
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // // 检查 featureList 是否全为 -1
 | 
	
		
			
				|  |  | +        // if (featureList.stream().allMatch(f -> f == -1)) {
 | 
	
		
			
				|  |  | +        //     rankItem.getScoresMap().put("origin_vov_p", 0d);
 | 
	
		
			
				|  |  | +        //     return 0;
 | 
	
		
			
				|  |  | +        // }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 计算有效特征的总权重和得分
 | 
	
		
			
				|  |  | +        double score = 0;
 | 
	
		
			
				|  |  | +        List<Integer> validIndices = new ArrayList<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (int i = 0; i < featureList.size(); i++) {
 | 
	
		
			
				|  |  | +            if (featureList.get(i) != -1) {
 | 
	
		
			
				|  |  | +                validIndices.add(i);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 如果没有有效特征,返回 0
 | 
	
		
			
				|  |  | +        if (validIndices.isEmpty()) {
 | 
	
		
			
				|  |  | +            rankItem.getScoresMap().put("origin_vov_p", 0d);
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 计算得分,动态调整权重
 | 
	
		
			
				|  |  | +        for (int index : validIndices) {
 | 
	
		
			
				|  |  | +            double weight = weightList.get(index);
 | 
	
		
			
				|  |  | +            score += featureList.get(index) * weight;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        rankItem.getScoresMap().put("origin_vov_p", score);
 | 
	
		
			
				|  |  | +        // 调整vov
 | 
	
		
			
				|  |  | +        if (score < vov_thresh) {
 | 
	
		
			
				|  |  | +            score = 0;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            double term1 = 1 / (1 + Math.exp(-1*beta_vov * (score - level50_vov)));
 | 
	
		
			
				|  |  | +            double term2 = 1 + Math.exp(-1*beta_vov * (level_95_vov - level50_vov));
 | 
	
		
			
				|  |  | +            score = term1 * term2;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return score;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private void readBucketFile() {
 | 
	
		
			
				|  |  |          InputStream resourceStream = RankStrategy4RegionMergeModelV562.class.getClassLoader().getResourceAsStream("20240609_bucket_274.txt");
 | 
	
		
			
				|  |  |          if (resourceStream != null) {
 |