浏览代码

fix:漏斗 score 三处口径统一 — strategy 用 filter 前预算的 scoresMap 设 Video.rovScore

之前 filter 前 (raw 阶段) 和 filter 后业务赋分用了不同的 n (raw size vs filter 后 size),
导致 step_1_recall 里同一路视频 score 不连续 (filter 通过的与未通过的混在一起).

修复: 让每个 strategy 在 filter 前预算 scoresMap, 之后:
- 传给 FilterParamFactory.create 写 entry.score
- filter 后构造 Video 时也用 scoresMap.getOrDefault(vid, 0.0) 设 rovScore
syncScoresToFunnel 用 Video.rovScore 覆盖 entry.score, 三处值完全一致.

具体改动:
- FilterParamFactory.createWithPositionScore → positionScores(ids) 返回 Map 暴露给 strategy
- 位置反推 10 个 strategy (HeadCate1STR/HeadCate2STR/HeadProvinceCate1/2/ProvinceSTR/
  UserCate1/2/UserDecon/YearShareCate1/2): 改用 positionScores helper, Video.rovScore
  也读这份 map
- cate 加权 2 个 strategy (HeadCate2Rov/HeadCate2AndChannelRov): scoresMap 从 max 改为
  LinkedHashMap.putIfAbsent (保业务原 first 顺序), 输出按 scoresMap insertion order, 简化
  原嵌套 for 为单循环

业务影响: 位置反推类 rovScore 数值变化 (raw size 反推, 可能跳号), 但相对大小关系不变 →
ROV 排序结果不变. cate 加权类完全等价于原行为.
yangxiaohui 1 周之前
父节点
当前提交
361f59fb82
共有 13 个文件被更改,包括 79 次插入126 次删除
  1. 5 4
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/FilterParamFactory.java
  2. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate1STRRecallStrategy.java
  3. 12 31
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2AndChannelRovRecallStrategy.java
  4. 12 30
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2RovRecallStrategy.java
  5. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2STRRecallStrategy.java
  6. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadProvinceCate1RecallStrategy.java
  7. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadProvinceCate2RecallStrategy.java
  8. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ProvinceSTRRecallStrategy.java
  9. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate1RecallStrategy.java
  10. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate2RecallStrategy.java
  11. 5 7
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserDeconstructionKeywordsRecallStrategy.java
  12. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/YearShareCate1RecallStrategy.java
  13. 5 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/YearShareCate2RecallStrategy.java

+ 5 - 4
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/FilterParamFactory.java

@@ -43,15 +43,16 @@ public class FilterParamFactory {
     }
 
     /**
-     * 漏斗版:按位置反推 score (score = ids.size() - i)。
-     * 给 filter 后才赋分 (Video.rovScore = n - i) 的 strategy 用,让 filter 前 entry.score 也有合理值。
+     * 按位置反推生成 scoresMap (score = ids.size() - i),用于无原始召回分的 strategy。
+     * Strategy 应该把这同一份 scoresMap 既传给 FilterParamFactory.create,又用来给 Video.setRovScore,
+     * 保证 filter 前/后口径一致。
      */
-    public static FilterParam createWithPositionScore(RecallParam param, List<Long> ids, String pushFrom) {
+    public static Map<Long, Double> positionScores(List<Long> ids) {
         Map<Long, Double> scoresMap = new HashMap<>(ids.size());
         int n = ids.size();
         for (int i = 0; i < n; i++) {
             scoresMap.put(ids.get(i), (double) (n - i));
         }
-        return create(param, ids, pushFrom, scoresMap);
+        return scoresMap;
     }
 }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate1STRRecallStrategy.java

@@ -84,15 +84,14 @@ public class HeadCate1STRRecallStrategy implements RecallStrategy {
     }
 
     private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
-        FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vidList, pushFrom());
+        Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vidList);
+        FilterParam filterParam = FilterParamFactory.create(param, vidList, pushFrom(), scoresMap);
         FilterResult filterResult = filterService.filter(filterParam);
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-            List<Long> filterIds = filterResult.getVideoIds();
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videosResult.add(video);
             }

+ 12 - 31
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2AndChannelRovRecallStrategy.java

@@ -75,14 +75,14 @@ public class HeadCate2AndChannelRovRecallStrategy implements RecallStrategy {
 
         Map<String, Map<String, Double>> recallVideoMap = this.cate2Recall(new ArrayList<>(mergeCate2Pair.keySet()), channelName);
 
-        // 过滤
-        Map<Long, Double> scoresMap = new HashMap<>();
+        // 预算 scoresMap (按 mergeCate2Pair 顺序,同 vid 取首次出现的 cateScore*videoScore,业务原顺序)
+        Map<Long, Double> scoresMap = new LinkedHashMap<>();
         for (Map.Entry<String, Double> entry : mergeCate2Pair.entrySet()) {
             Double cateScore = entry.getValue();
             Map<String, Double> videoMap = recallVideoMap.getOrDefault(entry.getKey(), new HashMap<>());
             for (Map.Entry<String, Double> v : videoMap.entrySet()) {
                 long vid = Long.parseLong(v.getKey());
-                scoresMap.merge(vid, cateScore * v.getValue(), Math::max);
+                scoresMap.putIfAbsent(vid, cateScore * v.getValue());
             }
         }
         List<Long> allVid = new ArrayList<>(scoresMap.keySet());
@@ -92,34 +92,15 @@ public class HeadCate2AndChannelRovRecallStrategy implements RecallStrategy {
         Set<Long> filterVids = new HashSet<>(filterResult.getVideoIds());
         filterVids.remove(param.getVideoId());
 
-        Set<Long> hit = new HashSet<>();
-        for (Map.Entry<String, Double> entry : mergeCate2Pair.entrySet()) {
-            String cate = entry.getKey();
-            Double cateScore = entry.getValue();
-
-            Map<String, Double> videoMap = recallVideoMap.getOrDefault(cate, new HashMap<>());
-            for (Map.Entry<String, Double> videoEntry : videoMap.entrySet()) {
-                long vid = Long.parseLong(videoEntry.getKey());
-
-                // 过滤之后不存在的视频,过滤掉
-                if (!filterVids.contains(vid)) {
-                    continue;
-                }
-                // 去重
-                if (hit.contains(vid)) {
-                    continue;
-                }
-                hit.add(vid);
-
-                Double videoScore = videoEntry.getValue();
-
-                Video video = new Video();
-                video.setVideoId(vid);
-                video.setRovScore(cateScore * videoScore);
-                video.setPushFrom(PUSH_FROM);
-                videoResult.add(video);
-            }
-
+        // 按 scoresMap 的 insertion order 输出
+        for (Map.Entry<Long, Double> e : scoresMap.entrySet()) {
+            long vid = e.getKey();
+            if (!filterVids.contains(vid)) continue;
+            Video video = new Video();
+            video.setVideoId(vid);
+            video.setRovScore(e.getValue());
+            video.setPushFrom(PUSH_FROM);
+            videoResult.add(video);
         }
 
         videoResult.sort(Comparator.comparingDouble(o -> -o.getRovScore()));

+ 12 - 30
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2RovRecallStrategy.java

@@ -73,14 +73,14 @@ public class HeadCate2RovRecallStrategy implements RecallStrategy {
 
         Map<String, Map<String, Double>> recallVideoMap = this.cate2Recall(new ArrayList<>(mergeCate2Pair.keySet()));
 
-        // 过滤
-        Map<Long, Double> scoresMap = new HashMap<>();
+        // 预算 scoresMap (按 mergeCate2Pair 顺序,同 vid 取首次出现的 cateScore*videoScore,业务原顺序)
+        Map<Long, Double> scoresMap = new LinkedHashMap<>();
         for (Map.Entry<String, Double> entry : mergeCate2Pair.entrySet()) {
             Double cateScore = entry.getValue();
             Map<String, Double> videoMap = recallVideoMap.getOrDefault(entry.getKey(), new HashMap<>());
             for (Map.Entry<String, Double> v : videoMap.entrySet()) {
                 long vid = Long.parseLong(v.getKey());
-                scoresMap.merge(vid, cateScore * v.getValue(), Math::max);
+                scoresMap.putIfAbsent(vid, cateScore * v.getValue());
             }
         }
         List<Long> allVid = new ArrayList<>(scoresMap.keySet());
@@ -90,33 +90,15 @@ public class HeadCate2RovRecallStrategy implements RecallStrategy {
         Set<Long> filterVids = new HashSet<>(filterResult.getVideoIds());
         filterVids.remove(param.getVideoId());
 
-        Set<Long> hit = new HashSet<>();
-        for (Map.Entry<String, Double> entry : mergeCate2Pair.entrySet()) {
-            String cate = entry.getKey();
-            Double cateScore = entry.getValue();
-
-            Map<String, Double> videoMap = recallVideoMap.getOrDefault(cate, new HashMap<>());
-            for (Map.Entry<String, Double> videoEntry : videoMap.entrySet()) {
-                long vid = Long.parseLong(videoEntry.getKey());
-
-                // 过滤之后不存在的视频,过滤掉
-                if (!filterVids.contains(vid)) {
-                    continue;
-                }
-                // 去重
-                if (hit.contains(vid)) {
-                    continue;
-                }
-                hit.add(vid);
-
-                Double videoScore = videoEntry.getValue();
-
-                Video video = new Video();
-                video.setVideoId(vid);
-                video.setRovScore(cateScore * videoScore);
-                video.setPushFrom(PUSH_FROM);
-                videoResult.add(video);
-            }
+        // 按 scoresMap 的 insertion order 输出(= mergeCate2Pair 顺序 + 同 vid 首次出现)
+        for (Map.Entry<Long, Double> e : scoresMap.entrySet()) {
+            long vid = e.getKey();
+            if (!filterVids.contains(vid)) continue;
+            Video video = new Video();
+            video.setVideoId(vid);
+            video.setRovScore(e.getValue());
+            video.setPushFrom(PUSH_FROM);
+            videoResult.add(video);
 
         }
 

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadCate2STRRecallStrategy.java

@@ -84,15 +84,14 @@ public class HeadCate2STRRecallStrategy implements RecallStrategy {
     }
 
     private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
-        FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vidList, pushFrom());
+        Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vidList);
+        FilterParam filterParam = FilterParamFactory.create(param, vidList, pushFrom(), scoresMap);
         FilterResult filterResult = filterService.filter(filterParam);
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-            List<Long> filterIds = filterResult.getVideoIds();
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videosResult.add(video);
             }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadProvinceCate1RecallStrategy.java

@@ -85,15 +85,14 @@ public class HeadProvinceCate1RecallStrategy implements RecallStrategy {
     }
 
     private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
-        FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vidList, pushFrom());
+        Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vidList);
+        FilterParam filterParam = FilterParamFactory.create(param, vidList, pushFrom(), scoresMap);
         FilterResult filterResult = filterService.filter(filterParam);
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-            List<Long> filterIds = filterResult.getVideoIds();
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videosResult.add(video);
             }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/HeadProvinceCate2RecallStrategy.java

@@ -85,15 +85,14 @@ public class HeadProvinceCate2RecallStrategy implements RecallStrategy {
     }
 
     private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
-        FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vidList, pushFrom());
+        Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vidList);
+        FilterParam filterParam = FilterParamFactory.create(param, vidList, pushFrom(), scoresMap);
         FilterResult filterResult = filterService.filter(filterParam);
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-            List<Long> filterIds = filterResult.getVideoIds();
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videosResult.add(video);
             }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ProvinceSTRRecallStrategy.java

@@ -78,15 +78,14 @@ public class ProvinceSTRRecallStrategy implements RecallStrategy {
     }
 
     private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
-        FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vidList, pushFrom());
+        Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vidList);
+        FilterParam filterParam = FilterParamFactory.create(param, vidList, pushFrom(), scoresMap);
         FilterResult filterResult = filterService.filter(filterParam);
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-            List<Long> filterIds = filterResult.getVideoIds();
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videosResult.add(video);
             }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate1RecallStrategy.java

@@ -50,15 +50,14 @@ public class UserCate1RecallStrategy implements RecallStrategy {
                 if (!keys.isEmpty()) {
                     List<String> values = redisTemplate.opsForValue().multiGet(keys);
                     List<Long> ids = recall(param.getVideoId(), values);
-                    FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, ids, pushFrom());
+                    Map<Long, Double> scoresMap = FilterParamFactory.positionScores(ids);
+                    FilterParam filterParam = FilterParamFactory.create(param, ids, pushFrom(), scoresMap);
                     FilterResult filterResult = filterService.filter(filterParam);
                     if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-                        List<Long> filterIds = filterResult.getVideoIds();
-                        int n = filterIds.size();
-                        for (int i = 0; i < n; i++) {
+                        for (Long vid : filterResult.getVideoIds()) {
                             Video video = new Video();
-                            video.setVideoId(filterIds.get(i));
-                            video.setRovScore(n - i);
+                            video.setVideoId(vid);
+                            video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                             video.setPushFrom(pushFrom());
                             videosResult.add(video);
                         }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate2RecallStrategy.java

@@ -50,15 +50,14 @@ public class UserCate2RecallStrategy implements RecallStrategy {
                 if (!keys.isEmpty()) {
                     List<String> values = redisTemplate.opsForValue().multiGet(keys);
                     List<Long> ids = recall(param.getVideoId(), values);
-                    FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, ids, pushFrom());
+                    Map<Long, Double> scoresMap = FilterParamFactory.positionScores(ids);
+                    FilterParam filterParam = FilterParamFactory.create(param, ids, pushFrom(), scoresMap);
                     FilterResult filterResult = filterService.filter(filterParam);
                     if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-                        List<Long> filterIds = filterResult.getVideoIds();
-                        int n = filterIds.size();
-                        for (int i = 0; i < n; i++) {
+                        for (Long vid : filterResult.getVideoIds()) {
                             Video video = new Video();
-                            video.setVideoId(filterIds.get(i));
-                            video.setRovScore(n - i);
+                            video.setVideoId(vid);
+                            video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                             video.setPushFrom(pushFrom());
                             videosResult.add(video);
                         }

+ 5 - 7
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserDeconstructionKeywordsRecallStrategy.java

@@ -58,19 +58,17 @@ public class UserDeconstructionKeywordsRecallStrategy implements RecallStrategy
             }
             List<String> values = redisTemplate.opsForValue().multiGet(keys);
             List<Long> vids = this.recall(param.getVideoId(), values);
-            FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, vids, pushFrom());
+            Map<Long, Double> scoresMap = FilterParamFactory.positionScores(vids);
+            FilterParam filterParam = FilterParamFactory.create(param, vids, pushFrom(), scoresMap);
 
             FilterResult filterResult = filterService.filter(filterParam);
             if (Objects.isNull(filterResult) || CollectionUtils.isEmpty(filterResult.getVideoIds())) {
                 return videos;
             }
-            List<Long> filterIds = filterResult.getVideoIds();
-
-            int n = filterIds.size();
-            for (int i = 0; i < n; i++) {
+            for (Long vid : filterResult.getVideoIds()) {
                 Video video = new Video();
-                video.setVideoId(filterIds.get(i));
-                video.setRovScore(n - i);
+                video.setVideoId(vid);
+                video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                 video.setPushFrom(pushFrom());
                 videos.add(video);
             }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/YearShareCate1RecallStrategy.java

@@ -81,15 +81,14 @@ public class YearShareCate1RecallStrategy implements RecallStrategy {
             List<String> values = redisTemplate.opsForValue().multiGet(keys);
             List<Long> ids = recall(param.getVideoId(), values);
 
-            FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, ids, pushFrom());
+            Map<Long, Double> scoresMap = FilterParamFactory.positionScores(ids);
+            FilterParam filterParam = FilterParamFactory.create(param, ids, pushFrom(), scoresMap);
             FilterResult filterResult = filterService.filter(filterParam);
             if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-                List<Long> filterIds = filterResult.getVideoIds();
-                int n = filterIds.size();
-                for (int i = 0; i < n; i++) {
+                for (Long vid : filterResult.getVideoIds()) {
                     Video video = new Video();
-                    video.setVideoId(filterIds.get(i));
-                    video.setRovScore(n - i);
+                    video.setVideoId(vid);
+                    video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                     video.setPushFrom(pushFrom());
                     videosResult.add(video);
                 }

+ 5 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/YearShareCate2RecallStrategy.java

@@ -80,15 +80,14 @@ public class YearShareCate2RecallStrategy implements RecallStrategy {
             List<String> values = redisTemplate.opsForValue().multiGet(keys);
             List<Long> ids = recall(param.getVideoId(), values);
 
-            FilterParam filterParam = FilterParamFactory.createWithPositionScore(param, ids, pushFrom());
+            Map<Long, Double> scoresMap = FilterParamFactory.positionScores(ids);
+            FilterParam filterParam = FilterParamFactory.create(param, ids, pushFrom(), scoresMap);
             FilterResult filterResult = filterService.filter(filterParam);
             if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
-                List<Long> filterIds = filterResult.getVideoIds();
-                int n = filterIds.size();
-                for (int i = 0; i < n; i++) {
+                for (Long vid : filterResult.getVideoIds()) {
                     Video video = new Video();
-                    video.setVideoId(filterIds.get(i));
-                    video.setRovScore(n - i);
+                    video.setVideoId(vid);
+                    video.setRovScore(scoresMap.getOrDefault(vid, 0.0));
                     video.setPushFrom(pushFrom());
                     videosResult.add(video);
                 }