17 Commits 5a525f4b87 ... 15315533d3

Auteur SHA1 Bericht Datum
  supeng 15315533d3 未获取到mid/uid时,推荐过滤风险视频 1 week geleden
  jiachanghui b2e5e99943 Merge branch 'feature/ros_fusion' of algorithm/recommend-server into master 2 weken geleden
  jch 83caebd3df ros fusion 2 weken geleden
  jiachanghui 5b8e24c1ca Merge branch 'feature/ros_fusion' of algorithm/recommend-server into master 2 weken geleden
  jch a7b954d706 ros fusion 2 weken geleden
  jiachanghui c676a3df2a Merge branch 'feature/1st_return' of algorithm/recommend-server into master 3 weken geleden
  jch a90c99248b Merge branch 'master' into feature/1st_return 3 weken geleden
  jch beeb94bdaa 扩展1层回流 1 maand geleden
  jiachanghui e0d410fb78 Merge branch 'feature/ros_add_channel_layer' of algorithm/recommend-server into master 3 weken geleden
  jch 33219aab68 ros扩展渠道分层特征 4 weken geleden
  jiachanghui fb93f6d4fa Merge branch 'feature/add_priori_province_recall' of algorithm/recommend-server into master 1 maand geleden
  jch e99fd32729 先验str/ros/rovn召回 1 maand geleden
  zhaohaipeng f590b07654 Merge branch 'feature_20250818_zhaohaipeng_str_plus_coefficient' of algorithm/recommend-server into master 1 maand geleden
  jiachanghui 962053b32e Merge branch 'feature/rank_add_channnel_layer' of algorithm/recommend-server into master 1 maand geleden
  jch a742260464 添加外部渠道分层特征 1 maand geleden
  zhaohaipeng 3a8f405eb8 feat:添加str+校准 1 maand geleden
  supeng 48123425ec Merge branch 'feature_20250814_supeng_risk_video_filter' of algorithm/recommend-server into master 1 maand geleden
23 gewijzigde bestanden met toevoegingen van 1495 en 635 verwijderingen
  1. 121 188
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/FeatureService.java
  2. 18 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java
  3. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java
  4. 6 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/bo/UserShareReturnProfile.java
  5. 43 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelBasic.java
  6. 5 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV564.java
  7. 316 203
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV565.java
  8. 29 6
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV566.java
  9. 31 40
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV567.java
  10. 25 13
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV568.java
  11. 69 9
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/tansform/FeatureV6.java
  12. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java
  13. 9 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java
  14. 112 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRedisRecallStrategy.java
  15. 119 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ChannelLayerHeadRovnRecallStrategy.java
  16. 110 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ChannelLayerRovnRecallStrategy.java
  17. 102 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceRosRecallStrategy.java
  18. 2 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceRovnRecallStrategy.java
  19. 102 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceStrRecallStrategy.java
  20. 53 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Return1Cate2RosRecallStrategy.java
  21. 53 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Return1Cate2StrRecallStrategy.java
  22. 59 78
      recommend-server-service/src/main/resources/feeds_score_config_fm_xgb_20250729.conf
  23. 109 89
      recommend-server-service/src/main/resources/feeds_score_config_fm_xgb_20250808.conf

+ 121 - 188
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/FeatureService.java

@@ -7,7 +7,9 @@ import com.tzld.piaoquan.recommend.feature.model.feature.FeatureKeyProto;
 import com.tzld.piaoquan.recommend.server.model.MachineInfo;
 import com.tzld.piaoquan.recommend.server.remote.FeatureV2RemoteService;
 import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
+import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
+import com.tzld.piaoquan.recommend.server.util.FeatureUtils;
 import com.tzld.piaoquan.recommend.server.util.JSONUtils;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
@@ -31,107 +33,6 @@ public class FeatureService {
     private static final Set<String> hotSceneSet = new HashSet<>(Arrays.asList("1008", "1007", "1058", "1074", "1010"));
     private static final Set<String> hotSceneTypeSet = new HashSet<>(Arrays.asList("1008", "1007"));
 
-    /**
-     * @return k1:视频、k2:表、k3:特征、v:特征值
-     */
-    public Feature getFeature(String mid, List<String> vidList, String appType,
-                              String province, String headVid) {
-
-
-        List<FeatureKeyProto> protos = new ArrayList<>();
-
-        for (String vid : vidList) {
-            // TODO 补充其他特征
-            // vid
-            // protos.add(genWithVid("alg_vid_feature_all_exp", vid));
-            protos.add(genWithVid("alg_vid_feature_all_exp_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_all_share", vid));
-            protos.add(genWithVid("alg_vid_feature_all_return", vid));
-            // protos.add(genWithVid("alg_vid_feature_exp2share", vid));
-            protos.add(genWithVid("alg_vid_feature_exp2share_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_share2return", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_noflow_exp", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_exp_v2", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_noflow_root_share", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_root_share_v2", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_noflow_root_return", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_root_return_v2", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_flow_exp", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_exp_v2", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_flow_root_share", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_root_share_v2", vid));
-            // protos.add(genWithVid("alg_vid_feature_feed_flow_root_return", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_root_return_v2", vid));
-
-            protos.add(genWithVid("alg_vid_feature_basic_info", vid));
-            // vid + apptype
-
-            // vid + province
-            // protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_exp", vid, province));
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_exp_v2", vid, province));
-            // protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_share", vid, province));
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_share_v2", vid, province));
-            // protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_return", vid, province));
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_return_v2", vid, province));
-
-            // vid + headvid
-            protos.add(genWithVidAndHeadVid("alg_recsys_feature_cf_i2i_new", vid, headVid));
-            //protos.add(genWithVidAndHeadVid("alg_recsys_feature_cf_i2i_new_v2", vid, headVid));
-        }
-
-        // 头部视频的基础信息
-        protos.add(genWithVid("alg_vid_feature_basic_info", headVid));
-
-        // user
-        protos.add(genWithMid("alg_mid_feature_play", mid));
-        protos.add(genWithMid("alg_mid_feature_share_and_return", mid));
-        protos.add(genWithMid("alg_mid_feature_play_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_return_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_share_tags", mid));
-        // protos.add(genWithMid("alg_mid_feature_feed_exp_share_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_feed_exp_share_tags_v2", mid));
-        // protos.add(genWithMid("alg_mid_feature_feed_exp_return_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_feed_exp_return_tags_v2", mid));
-        protos.add(genWithMid("alg_mid_feature_sharecf", mid));
-        protos.add(genWithMid("alg_mid_feature_returncf", mid));
-
-
-        Map<String, String> result = remoteService.getFeature(protos);
-
-        Feature feature = new Feature();
-
-        result.entrySet().forEach(e -> {
-
-            String[] uk = StringUtils.split(e.getKey(), ":");
-            String prefix = uk[0];
-            String table = uk[1];
-            Map<String, String> colMap = JSONUtils.fromJson(e.getValue(), new TypeToken<Map<String, String>>() {
-            }, Collections.emptyMap());
-            String featureStr = colMap.get("feature");
-
-            switch (prefix) {
-                case "v":
-                    String vid = uk[2];
-                    Map<String, Map<String, String>> tableFeatureMap = feature.getVideoFeature().getOrDefault(vid, new HashMap<>());
-                    tableFeatureMap.put(table, JSONUtils.fromJson(featureStr, new TypeToken<Map<String, String>>() {
-                    }, Collections.emptyMap()));
-                    feature.getVideoFeature().put(vid, tableFeatureMap);
-                    break;
-                case "u":
-                    feature.getUserFeature().put(table, JSONUtils.fromJson(featureStr, new TypeToken<Map<String, String>>() {
-                    }, Collections.emptyMap()));
-                    break;
-                default:
-                    break;
-            }
-
-        });
-
-
-        return feature;
-    }
-
-
     public Map<String, Map<String, Map<String, String>>> getVideoBaseInfo(String headVid, List<String> vidList) {
         List<FeatureKeyProto> protos = new ArrayList<>();
         if (null != headVid && !headVid.isEmpty()) {
@@ -144,86 +45,9 @@ public class FeatureService {
         return feature.getVideoFeature();
     }
 
-    public Feature getNewFeature(String province, String mid, String sceneType, String headVid,
-                                 Map<String, Map<String, Map<String, String>>> videoBaseInfoMap, List<String> vidList) {
-        List<FeatureKeyProto> protos = new ArrayList<>();
-        String i2iSceneType = "other";
-        if (hotSceneSet.contains(sceneType)) {
-            i2iSceneType = sceneType;
-        }
-        for (String vid : vidList) {
-            // ********************* old vid ******************
-            protos.add(genWithVid("alg_vid_feature_all_exp_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_all_share", vid));
-            protos.add(genWithVid("alg_vid_feature_all_return", vid));
-            protos.add(genWithVid("alg_vid_feature_exp2share_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_share2return", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_exp_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_root_share_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_noflow_root_return_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_exp_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_root_share_v2", vid));
-            protos.add(genWithVid("alg_vid_feature_feed_flow_root_return_v2", vid));
-
-            // vid + province
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_exp_v2", vid, province));
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_share_v2", vid, province));
-            protos.add(genWithVidAndProvince("alg_vid_feature_feed_province_root_return_v2", vid, province));
-
-            // headvid + vid
-            // protos.add(genWithKeyMap("alg_recsys_feature_cf_i2i_new_v2", vid, ImmutableMap.of("vid_a", headVid, "vid_b", vid)));
-
-            // ********************* new vid ******************
-            protos.add(genWithKeyMap("alg_vid_feature_day", vid, ImmutableMap.of("vid", vid)));
-            protos.add(genWithKeyMap("alg_sence_type_feature", vid, ImmutableMap.of("sence_type", sceneType, "videoid", vid)));
-            protos.add(genWithKeyMap("alg_videoid_feature", vid, ImmutableMap.of("videoid", vid)));
-            // protos.add(genWithKeyMap("alg_recsys_feature_cf_i2i_scene_rov", vid, ImmutableMap.of("sence_type", i2iSceneType, "vid_a", headVid, "vid_b", vid)));
-            // protos.add(genWithKeyMap("alg_recsys_feature_cf_i2i_scene_ros", vid, ImmutableMap.of("sence_type", i2iSceneType, "vid_a", headVid, "vid_b", vid)));
-            // protos.add(genWithKeyMap("alg_recsys_feature_weak_cf_i2i_scene_rov", vid, ImmutableMap.of("sence_type", i2iSceneType, "vid_a", headVid, "vid_b", vid)));
-            // protos.add(genWithKeyMap("alg_recsys_feature_weak_cf_i2i_scene_ros", vid, ImmutableMap.of("sence_type", i2iSceneType, "vid_a", headVid, "vid_b", vid)));
-            if (null != videoBaseInfoMap && videoBaseInfoMap.containsKey(vid)) {
-                Map<String, Map<String, String>> videoInfo = videoBaseInfoMap.get(vid);
-                if (null != videoInfo && videoInfo.containsKey("alg_vid_feature_basic_info")) {
-                    Map<String, String> baseInfo = videoInfo.get("alg_vid_feature_basic_info");
-                    if (null != baseInfo) {
-                        String cate1 = baseInfo.get("cate1_list");
-                        if (null != cate1 && !cate1.isEmpty()) {
-                            protos.add(genWithKeyMap("alg_cate1_feature", vid, ImmutableMap.of("cate1", cate1)));
-                            protos.add(genWithKeyMap("alg_cate1_feature_day", vid, ImmutableMap.of("cate1", cate1)));
-                        }
-                        String cate2 = baseInfo.get("cate2");
-                        if (null != cate2 && !cate2.isEmpty()) {
-                            protos.add(genWithKeyMap("alg_cate2_feature", vid, ImmutableMap.of("cate2", cate2)));
-                            protos.add(genWithKeyMap("alg_cate2_feature_day", vid, ImmutableMap.of("cate2", cate2)));
-                        }
-                        String vidSource = baseInfo.get("vid_source");
-                        if (null != vidSource && !vidSource.isEmpty()) {
-                            protos.add(genWithKeyMap("alg_vid_source_feature", vid, ImmutableMap.of("vid_source", vidSource)));
-                            protos.add(genWithKeyMap("alg_video_source_feature_day", vid, ImmutableMap.of("video_source", vidSource)));
-                        }
-                        String videoUnionid = baseInfo.get("title_time_w_h_unionid");
-                        if (null != videoUnionid && !videoUnionid.isEmpty()) {
-                            protos.add(genWithKeyMap("alg_video_unionid_feature_day", vid, ImmutableMap.of("video_unionid", videoUnionid)));
-                        }
-                    }
-                }
-            }
-        }
-
-        // user
-        protos.add(genWithMid("alg_mid_feature_play", mid));
-        protos.add(genWithMid("alg_mid_feature_share_and_return", mid));
-        protos.add(genWithMid("alg_mid_feature_play_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_return_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_share_tags", mid));
-        protos.add(genWithMid("alg_mid_feature_feed_exp_share_tags_v2", mid));
-        protos.add(genWithMid("alg_mid_feature_feed_exp_return_tags_v2", mid));
-        protos.add(genWithMid("alg_mid_feature_sharecf", mid));
-        protos.add(genWithMid("alg_mid_feature_returncf", mid));
-
-        return getFeatureByProto(protos);
-    }
-
+    /**
+     * @return k1:视频、k2:表、k3:特征、v:特征值
+     */
     public Feature getFeatureV3(RankParam param, Map<String, Map<String, Map<String, String>>> videoBaseInfoMap, List<String> vidList) {
         String mid = param.getMid();
         String mergeMid = getMergeMid(param.getUid(), mid);
@@ -324,6 +148,89 @@ public class FeatureService {
         return getFeatureByProto(protos);
     }
 
+    /**
+     * @return k1:视频、k2:表、k3:特征、v:特征值
+     */
+    public Feature getFeatureV4(RankParam param, Map<String, String> headInfo, Map<String, Map<String, Map<String, String>>> videoBaseInfoMap, List<String> vidList) {
+        String mid = param.getMid();
+        String mergeMid = getMergeMid(param.getUid(), mid);
+        String headVid = String.valueOf(param.getHeadVid());
+        String province = param.getProvince().replaceAll("省$", "");
+        String apptype = param.getAppType() + "";
+        String orgHotScene = String.valueOf(param.getHotSceneType());
+        String brand = "";
+        if (null != param.getMachineInfo()) {
+            MachineInfo machineInfo = param.getMachineInfo();
+            if (null != machineInfo.getBrand()) {
+                brand = machineInfo.getBrand();
+            }
+        }
+        String hotSceneType = orgHotScene;
+        if (!hotSceneTypeSet.contains(hotSceneType)) {
+            hotSceneType = "other";
+        }
+        String senceType = orgHotScene;
+        if (!hotSceneSet.contains(senceType)) {
+            senceType = "other";
+        }
+        String userChannel = "-1";
+        if (null != param.getChannelName() && !param.getChannelName().isEmpty()) {
+            userChannel = param.getChannelName();
+        }
+        String userLayer = "非0层";
+        if (FeatureUtils.firstLevel(param.getUserShareDepth())) {
+            userLayer = "0层";
+        }
+        String unionid = "-1";
+        if (null != headInfo) {
+            unionid = headInfo.getOrDefault("title_time_w_h_unionid", unionid);
+        }
+
+        List<FeatureKeyProto> protos = new ArrayList<>();
+        // vid
+        for (String vid : vidList) {
+            protos.add(genWithKeyMap("alg_recsys_feature_video_clean_stat", vid, ImmutableMap.of("vid", vid)));
+            protos.add(genWithKeyMap("alg_vid_global_feature_20250212", vid, ImmutableMap.of("vid", vid)));
+            protos.add(genWithKeyMap("alg_vid_recommend_exp_feature_20250212", vid, ImmutableMap.of("vid", vid)));
+            protos.add(genWithKeyMap("alg_vid_recommend_flowpool_exp_feature_20250212", vid, ImmutableMap.of("vid", vid)));
+            protos.add(genWithKeyMap("alg_vid_apptype_recommend_exp_feature_20250212", vid, ImmutableMap.of("vid", vid, "apptype", apptype)));
+            protos.add(genWithKeyMap("alg_vid_province_recommend_exp_feature_20250212", vid, ImmutableMap.of("vid", vid, "province", province)));
+            protos.add(genWithKeyMap("alg_vid_brand_recommend_exp_feature_20250212", vid, ImmutableMap.of("vid", vid, "brand", brand)));
+            protos.add(genWithKeyMap("alg_vid_hotsencetype_recommend_exp_feature_20250212", vid, ImmutableMap.of("vid", vid, "hotsencetype", hotSceneType)));
+
+            protos.add(genWithKeyMap("scene_type_vid_cf_feature_20250212", vid, ImmutableMap.of("sence_type", senceType, "vid_a", headVid, "vid_b", vid)));
+            protos.add(genWithKeyMap("vid_click_cf_feature_20250212", vid, ImmutableMap.of("vid_a", headVid, "vid_b", vid)));
+            protos.add(genWithKeyMap("alg_recsys_feature_cf_i2i_v2", vid, ImmutableMap.of("vid_a", headVid, "vid_b", vid)));
+            protos.add(genWithKeyMap("alg_recsys_feature_video_recommend_channel_layer", vid, ImmutableMap.of("channel", userChannel, "layer", userLayer, "vid", vid)));
+            protos.add(genWithKeyMap("alg_recsys_feature_video_recommend_channel_layer_head", vid, ImmutableMap.of("channel", userChannel, "layer", userLayer, "unionid", unionid, "vid", vid)));
+            if (null != videoBaseInfoMap) {
+                Map<String, Map<String, String>> videoInfo = videoBaseInfoMap.getOrDefault(vid, new HashMap<>());
+                Map<String, String> baseInfo = videoInfo.getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
+                String merge_cate1 = baseInfo.getOrDefault("merge_first_level_cate", "unknown").trim();
+                protos.add(genWithKeyMap("alg_merge_cate1_recommend_exp_feature_20250212", vid, ImmutableMap.of("merge_cate1", merge_cate1)));
+
+                String merge_cate2 = baseInfo.getOrDefault("merge_second_level_cate", "unknown").trim();
+                protos.add(genWithKeyMap("alg_merge_cate2_recommend_exp_feature_20250212", vid, ImmutableMap.of("merge_cate2", merge_cate2)));
+
+                String channel = baseInfo.getOrDefault("channel", "unknown").trim();
+                protos.add(genWithKeyMap("alg_channel_recommend_exp_feature_20250212", vid, ImmutableMap.of("channel", channel)));
+
+                String festive = baseInfo.getOrDefault("festive_label2", "unknown").trim();
+                protos.add(genWithKeyMap("alg_festive_recommend_exp_feature_20250212", vid, ImmutableMap.of("festive", festive)));
+
+                String videoUnionid = baseInfo.getOrDefault("title_time_w_h_unionid", "unknown");
+                protos.add(genWithKeyMap("alg_video_unionid_recommend_exp_feature_20250212", vid, ImmutableMap.of("video_unionid", videoUnionid)));
+            }
+        }
+        // user
+        protos.add(genWithMid("alg_mid_feature_return_tags", mid));
+        protos.add(genWithMid("alg_mid_feature_share_tags", mid));
+        protos.add(genWithMid("mid_global_feature_20250212", mid));
+        protos.add(genWithMid("alg_recsys_feature_user_share_return_stat", mergeMid));
+
+        return getFeatureByProto(protos);
+    }
+
     public Feature getFeatureByNewLabel(String appType, String hotSceneType, String province, String brand, String mid, String headVideoId, List<String> vidList, Map<String, Map<String, Map<String, String>>> videoBaseInfoMap) {
 
         List<FeatureKeyProto> protos = new ArrayList<>();
@@ -389,17 +296,43 @@ public class FeatureService {
         return null;
     }
 
-    public Map<String, String> getUserInfo(String table, String id) {
+    public Map<String, Map<String, String>> getBehaviorVideos(String headVid, UserShareReturnProfile userProfile) {
+        Map<String, Map<String, String>> behaviorVideos = new HashMap<>();
         try {
-            Feature feature = getFeatureByProto(Collections.singletonList(genWithMid(table, id)));
-            Map<String, Map<String, String>> userFeature = feature.getUserFeature();
-            if (null != userFeature) {
-                return userFeature.get(table);
+            Set<String> vidSet = new HashSet<>();
+            if (null != headVid && !headVid.isEmpty()) {
+                vidSet.add(headVid);
+            }
+            if (null != userProfile) {
+                for (List<UserSRBO> list : Arrays.asList(userProfile.getM_s_s(), userProfile.getM_r_s(), userProfile.getL_s_s(), userProfile.getL_r_s(), userProfile.getL_r1_s())) {
+                    if (null != list) {
+                        for (UserSRBO u : list) {
+                            if (null != u) {
+                                vidSet.add(u.getId() + "");
+                            }
+                        }
+                    }
+                }
+            }
+            if (!vidSet.isEmpty()) {
+                Map<String, Map<String, Map<String, String>>> videoMap = getVideoBaseInfo("", new ArrayList<>(vidSet));
+                if (null != videoMap && !videoMap.isEmpty()) {
+                    for (Map.Entry<String, Map<String, Map<String, String>>> entry : videoMap.entrySet()) {
+                        String vid = entry.getKey();
+                        Map<String, Map<String, String>> map = entry.getValue();
+                        if (null != map && map.containsKey("alg_vid_feature_basic_info")) {
+                            Map<String, String> info = map.get("alg_vid_feature_basic_info");
+                            if (null != info && !info.isEmpty()) {
+                                behaviorVideos.put(vid, info);
+                            }
+                        }
+                    }
+                }
             }
         } catch (Exception e) {
-            log.error("get user info error! value=[{}]", id, e);
+            log.error("get user behavior video info error! value=[{}]", headVid, e);
         }
-        return null;
+        return behaviorVideos;
     }
 
     public Map<String, String> getHeadVideoInfo(String headVid) {

+ 18 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -1,6 +1,5 @@
 package com.tzld.piaoquan.recommend.server.service;
 
-import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.google.common.base.Stopwatch;
 import com.google.common.base.Strings;
@@ -86,6 +85,8 @@ public class RecommendService {
     private Set<Long> riskScenes;
     @ApolloJsonValue("${creative.info.feature.channel.name:[]}")
     private Set<String> creativeInfoFeatureChannelNameSet;
+    @ApolloJsonValue("${none.user.risk.exclude.apptype:[]}")
+    private Set<Integer> noneUserRiskExcludeAppTypes;
 
     public static final String channelGroupPrefix = "alg_recsys_user_channel_group";
 
@@ -362,9 +363,15 @@ public class RecommendService {
 
         // 风险过滤
         if (riskVideoFilterSwitch) {
+            //0 4产品之外,hotsencetype 1089进入,没有mid和uid时,推荐返回过滤掉风险视频
+            boolean isNoneUserRisk = (Objects.isNull(noneUserRiskExcludeAppTypes) || !noneUserRiskExcludeAppTypes.contains(param.getAppType()))
+                    && Objects.equals(1089L,request.getHotSceneType())
+                    && (Objects.isNull(param.getUid()) || Objects.equals("0", param.getUid().trim()) || Objects.equals("null", param.getUid().trim()))
+                    && (Objects.isNull(param.getMid()) || Objects.equals("", param.getMid().trim()));
             boolean riskUser = riskScenes.contains(request.getHotSceneType())
                     || riskUserCache.getUnchecked(RedisKeyConstants.Recommend.riskUserUid).contains(param.getUid())
-                    || riskUserCache.getUnchecked(RedisKeyConstants.Recommend.riskUserMid).contains(param.getMid());
+                    || riskUserCache.getUnchecked(RedisKeyConstants.Recommend.riskUserMid).contains(param.getMid())
+                    || isNoneUserRisk;
             param.setRiskUser(riskUser);
         }
 
@@ -407,7 +414,13 @@ public class RecommendService {
         Stopwatch stopwatch = Stopwatch.createStarted();
         String vid = String.valueOf(param.getVideoId());
         UserShareReturnProfile userProfile = featureService.getUserProfile(param.getUid(), param.getMid());
-        Map<String, String> headVideoInfo = featureService.getHeadVideoInfo(vid);
+        Map<String, Map<String, String>> behaviorVideos = featureService.getBehaviorVideos(vid, userProfile);
+        Map<String, String> headVideoInfo;
+        if (null != behaviorVideos && behaviorVideos.containsKey(vid)) {
+            headVideoInfo = behaviorVideos.get(vid);
+        } else {
+            headVideoInfo = new HashMap<>();
+        }
         // long infoTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
         // timerLogMapTL.get().put("infoTime", infoTime);
         stopwatch.reset().start();
@@ -416,6 +429,7 @@ public class RecommendService {
         recallParam.setUserProfile(userProfile);
         recallParam.setHeadInfo(headVideoInfo);
         recallParam.setUserRTShareList(param.getUserRTShareList());
+        recallParam.setBehaviorVideos(behaviorVideos);
         RecallResult recallResult = recallService.recall(recallParam);
 
         long recallTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
@@ -427,6 +441,7 @@ public class RecommendService {
         rankParam.setUserProfile(userProfile);
         rankParam.setHeadInfo(headVideoInfo);
         rankParam.setUserRTShareList(param.getUserRTShareList());
+        rankParam.setBehaviorVideos(behaviorVideos);
         RankResult rankResult = rankRouter.rank(rankParam);
 
         long rankTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java

@@ -47,4 +47,5 @@ public class RankParam {
     private Long requestVideoId;
     private String currentPageSource;
     private Map<String, String> creativeInfoFeature;
+    private Map<String, Map<String, String>> behaviorVideos;
 }

+ 6 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/bo/UserShareReturnProfile.java

@@ -18,7 +18,8 @@ public class UserShareReturnProfile {
     private List<UserSRBO> m_s_s;    // max_share_seq(最大分享序列)
     private List<UserSRBO> m_r_s;   // max_return_seq(最大回流序列)
     private List<UserSRBO> l_s_s;    // last_share_seq(最近分享序列)
-    private List<UserSRBO> l_r_s;   // last_return_seq(最近回流序列)
+    private List<UserSRBO> l_r_s;   // last_return_seq(最近n层回流序列)
+    private List<UserSRBO> l_r1_s;   // last_return_seq(最近1层回流序列)
     private Map<String, VideoAttrSRBO> c1_s;   // cate1_seq(merge_first_level_cate序列-回流率)
     private Map<String, VideoAttrSRBO> c2_s;   // cate2_seq(merge_second_level_cate序列-回流率)
     private Map<String, VideoAttrSRBO> l1_s;   // label1_seq(festive_label1序列-回流率)
@@ -40,6 +41,10 @@ public class UserShareReturnProfile {
         this.l_r_s = JSON.parseArray(data, UserSRBO.class);
     }
 
+    public void setL_r1_s(String data) {
+        this.l_r1_s = JSON.parseArray(data, UserSRBO.class);
+    }
+
     public void setC1_s(String data) {
         this.c1_s = parseVideoAttrSR(data);
     }

+ 43 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelBasic.java

@@ -1,5 +1,7 @@
 package com.tzld.piaoquan.recommend.server.service.rank.strategy;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.google.common.reflect.TypeToken;
 import com.tzld.piaoquan.recommend.server.common.base.RankItem;
@@ -18,6 +20,7 @@ import com.tzld.piaoquan.recommend.server.util.JSONUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.RandomUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
@@ -48,6 +51,11 @@ public abstract class RankStrategy4RegionMergeModelBasic extends RankService {
     @ApolloJsonValue("${RankReduceByFestiveConfig:{}}")
     private Map<String, String> rankReduceByFestiveConfig = new HashMap<>();
 
+    @ApolloJsonValue("${str.plus.calibration.merge.cate2:[]}")
+    private Set<String> strPlusCalibrationMergeCate2;
+
+    public static final String STR_PLUS_CALIBRATION_ATTRIBUTE_KEY_PREFIX = "alg_rec_model_calibration_str:";
+
     String CLASS_NAME = this.getClass().getSimpleName();
 
     public void duplicate(Set<Long> setVideo, List<Video> videos) {
@@ -399,6 +407,41 @@ public abstract class RankStrategy4RegionMergeModelBasic extends RankService {
         return regionMap;
     }
 
+    /**
+     * 计算MergeCate2的str+校准系数
+     */
+    protected double calcStrPlusCalibrationCoefficientByMergeCate2(String mergeCate2) {
+        if (CollectionUtils.isEmpty(strPlusCalibrationMergeCate2) || StringUtils.isEmpty(mergeCate2)) {
+            return 1d;
+        }
+
+        if (!strPlusCalibrationMergeCate2.contains(mergeCate2)) {
+            return 1d;
+        }
+
+        try {
+
+            String key = STR_PLUS_CALIBRATION_ATTRIBUTE_KEY_PREFIX + mergeCate2;
+            String value = redisTemplate.opsForValue().get(key);
+            if (StringUtils.isEmpty(value)) {
+                return 1d;
+            }
+
+            JSONObject valueJson = JSON.parseObject(value);
+            double rStrPlus = valueJson.getDoubleValue("r_str_plus");
+            double pStrPlus = valueJson.getDoubleValue("p_str_plus");
+            double coefficient = rStrPlus / pStrPlus;
+            if (coefficient <= 0d) {
+                return 1d;
+            }
+            return coefficient;
+        } catch (Exception e) {
+            log.error("calcStrPlusCalibrationCoefficientByMergeCate2 error mergeCate2: {} \n", mergeCate2, e);
+        }
+
+        return 1d;
+    }
+
     private boolean isInsertDouHotFlowPoolVideo() {
         double rand = RandomUtils.nextDouble(0, 1);
         return rand <= newFlowPoolSelectRate;

+ 5 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV564.java

@@ -70,7 +70,11 @@ public class RankStrategy4RegionMergeModelV564 extends RankStrategy4RegionMergeM
         //-------------------city rovn------------------
         RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
         //-------------------priori province rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 5.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------

+ 316 - 203
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV565.java

@@ -1,16 +1,20 @@
 package com.tzld.piaoquan.recommend.server.service.rank.strategy;
 
+import com.alibaba.fastjson.JSON;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.tzld.piaoquan.recommend.server.common.ThreadPoolFactory;
 import com.tzld.piaoquan.recommend.server.common.base.RankItem;
+import com.tzld.piaoquan.recommend.server.model.MachineInfo;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.service.FeatureService;
 import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
+import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
+import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
 import com.tzld.piaoquan.recommend.server.service.rank.extractor.ExtractVideoMergeCate;
+import com.tzld.piaoquan.recommend.server.service.rank.tansform.FeatureV6;
 import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
 import com.tzld.piaoquan.recommend.server.service.score.ScorerUtils;
-import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
-import com.tzld.piaoquan.recommend.server.util.ExtractFeature20250218;
-import com.tzld.piaoquan.recommend.server.util.FeatureBucketUtils;
+import com.tzld.piaoquan.recommend.server.util.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -18,241 +22,149 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
-import java.util.stream.Collectors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
 @Service
 @Slf4j
 public class RankStrategy4RegionMergeModelV565 extends RankStrategy4RegionMergeModelBasic {
     @ApolloJsonValue("${rank.score.merge.weightv565:}")
     private Map<String, Double> mergeWeight;
-
     @Autowired
     private FeatureService featureService;
 
     @Override
     public List<Video> mergeAndRankRovRecall(RankParam param) {
-
-        long startTime = System.currentTimeMillis();
-
         Map<String, Double> mergeWeight = this.mergeWeight != null ? this.mergeWeight : new HashMap<>(0);
+
         //-------------------融-------------------
         //-------------------合-------------------
         //-------------------逻-------------------
         //-------------------辑-------------------
 
-        List<Video> oldRovs = new ArrayList<>();
-        oldRovs.addAll(extractAndSort(param, RegionHRecallStrategy.PUSH_FORM));
-        oldRovs.addAll(extractAndSort(param, RegionHDupRecallStrategy.PUSH_FORM));
-        oldRovs.addAll(extractAndSort(param, Region24HRecallStrategy.PUSH_FORM));
-        oldRovs.addAll(extractAndSort(param, RegionRelative24HRecallStrategy.PUSH_FORM));
-        oldRovs.addAll(extractAndSort(param, RegionRelative24HDupRecallStrategy.PUSH_FORM));
-        removeDuplicate(oldRovs);
-        int sizeReturn = param.getSize();
-        List<Video> v0 = oldRovs.size() <= sizeReturn
-                ? oldRovs
-                : oldRovs.subList(0, sizeReturn);
+        long currentMs = System.currentTimeMillis();
         Set<Long> setVideo = new HashSet<>();
-        this.duplicate(setVideo, v0);
-        setVideo.addAll(v0.stream().map(Video::getVideoId).collect(Collectors.toSet()));
-        List<Video> rovRecallRank = new ArrayList<>(v0);
+        setVideo.add(param.getHeadVid());
+        List<Video> rovRecallRank = new ArrayList<>();
+        // -------------------5路特殊旧召回------------------
+        RecallUtils.extractOldSpecialRecall(param, setVideo, rovRecallRank);
         //-------------------return相似召回------------------
-        List<Video> v6 = extractAndSort(param, ReturnVideoRecallStrategy.PUSH_FORM);
-        v6 = v6.stream().filter(r -> !setVideo.contains(r.getVideoId())).collect(Collectors.toList());
-        v6 = v6.subList(0, Math.min(mergeWeight.getOrDefault("v6", 5.0).intValue(), v6.size()));
-        rovRecallRank.addAll(v6);
-        setVideo.addAll(v6.stream().map(Video::getVideoId).collect(Collectors.toSet()));
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("v6", 5.0).intValue(), param, ReturnVideoRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
         //-------------------新地域召回------------------
-        List<Video> v1 = extractAndSort(param, RegionRealtimeRecallStrategyV1.PUSH_FORM);
-        v1 = v1.stream().filter(r -> !setVideo.contains(r.getVideoId())).collect(Collectors.toList());
-        v1 = v1.subList(0, Math.min(mergeWeight.getOrDefault("v1", 5.0).intValue(), v1.size()));
-        rovRecallRank.addAll(v1);
-        setVideo.addAll(v1.stream().map(Video::getVideoId).collect(Collectors.toSet()));
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("v1", 5.0).intValue(), param, RegionRealtimeRecallStrategyV1.PUSH_FORM, setVideo, rovRecallRank);
         //-------------------scene cf rovn------------------
-        List<Video> sceneCFRovn = extractAndSort(param, SceneCFRovnRecallStrategy.PUSH_FORM);
-        sceneCFRovn = sceneCFRovn.stream().filter(r -> !setVideo.contains(r.getVideoId())).collect(Collectors.toList());
-        sceneCFRovn = sceneCFRovn.subList(0, Math.min(mergeWeight.getOrDefault("sceneCFRovn", 5.0).intValue(), sceneCFRovn.size()));
-        rovRecallRank.addAll(sceneCFRovn);
-        setVideo.addAll(sceneCFRovn.stream().map(Video::getVideoId).collect(Collectors.toSet()));
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("sceneCFRovn", 5.0).intValue(), param, SceneCFRovnRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
         //-------------------scene cf rosn------------------
-        List<Video> sceneCFRosn = extractAndSort(param, SceneCFRosnRecallStrategy.PUSH_FORM);
-        sceneCFRosn = sceneCFRosn.stream().filter(r -> !setVideo.contains(r.getVideoId())).collect(Collectors.toList());
-        sceneCFRosn = sceneCFRosn.subList(0, Math.min(mergeWeight.getOrDefault("sceneCFRosn", 5.0).intValue(), sceneCFRosn.size()));
-        rovRecallRank.addAll(sceneCFRosn);
-        setVideo.addAll(sceneCFRosn.stream().map(Video::getVideoId).collect(Collectors.toSet()));
-
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("sceneCFRosn", 5.0).intValue(), param, SceneCFRosnRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------user cate1------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("cate1RecallN", 5.0).intValue(), param, UserCate1RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------user cate2------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("cate2RecallN", 5.0).intValue(), param, UserCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------head province cate1------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate1RecallN", 3.0).intValue(), param, HeadProvinceCate1RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------head province cate2------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2RecallN", 3.0).intValue(), param, HeadProvinceCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        //-------------------head cate2 of rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2Rov", 5.0).intValue(), param, HeadCate2RovRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------city rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------
         //-------------------逻-------------------
         //-------------------辑-------------------
+        Map<String, String> rtFeatureDumpsMap = dumpsRtFeature(param.getUserRTShareList());
 
-        // 1 批量获取特征  省份参数要对齐  headvid  要传递过来!
-        List<String> vids = CommonCollectionUtils.toListDistinct(rovRecallRank, v -> String.valueOf(v.getVideoId()));
-
+        // 1. 批量获取特征  省份参数要对齐  headvid  要传递过来!
         // k1:视频、k2:表、k3:特征、v:特征值
-        String provinceCn = param.getProvince().replaceAll("省$", "");
+        List<String> vids = CommonCollectionUtils.toListDistinct(rovRecallRank, v -> String.valueOf(v.getVideoId()));
         String headVid = String.valueOf(param.getHeadVid());
-        String sceneType = String.valueOf(param.getHotSceneType());
         Map<String, Map<String, Map<String, String>>> videoBaseInfoMap = featureService.getVideoBaseInfo(headVid, vids);
-        String appType = String.valueOf(param.getAppType());
-        String brand = "";
-        if (Objects.nonNull(param.getMachineInfo())) {
-            brand = param.getMachineInfo().getBrand();
-        }
-
-        long ts = System.currentTimeMillis() / 1000;
-
-        FeatureService.Feature feature = featureService.getFeatureByNewLabel(appType, sceneType, provinceCn, brand, param.getMid(), headVid, vids, videoBaseInfoMap);
+        FeatureService.Feature feature = featureService.getFeatureV3(param, videoBaseInfoMap, vids);
         Map<String, Map<String, String>> featureOriginUser = feature.getUserFeature();
         Map<String, Map<String, Map<String, String>>> featureOriginVideo = feature.getVideoFeature();
         Map<String, String> headVideoInfo = videoBaseInfoMap.getOrDefault(headVid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
 
-        // 2 特征处理
-        Map<String, Double> userFeatureMapDouble = new HashMap<>();
-
-        Map<String, String> c1 = featureOriginUser.getOrDefault("mid_global_feature_20250212", new HashMap<>());
-        Map<String, String> c4 = featureOriginUser.getOrDefault("mid_u2u_friend_index_feature_20250212", new HashMap<>());
-        Map<String, String> c5 = featureOriginUser.getOrDefault("alg_mid_feature_return_tags", new HashMap<>());
-        Map<String, String> c6 = featureOriginUser.getOrDefault("alg_mid_feature_share_tags", new HashMap<>());
-        Map<String, String> c7 = featureOriginUser.getOrDefault("alg_mid_feature_sharecf", new HashMap<>());
-        Map<String, String> c8 = featureOriginUser.getOrDefault("alg_mid_feature_returncf", new HashMap<>());
-
-        ExtractFeature20250218.handleC1(c1, userFeatureMapDouble);
-        ExtractFeature20250218.handleC4(c4, userFeatureMapDouble);
-        Map<String, Map<String, String[]>> c78FeatureMap = ExtractFeature20250218.handleC7ToC8(c7, c8);
+        // 2. 用户信息预处理
+        Map<String, Map<String, String[]>> newC7Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_sharecf", new HashMap<>()));
+        Map<String, Map<String, String[]>> newC8Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_returncf", new HashMap<>()));
+        UserShareReturnProfile userProfile = parseUserProfile(featureOriginUser);
+        Map<String, Map<String, String>> userBehaviorVideoMap = getUserBehaviorVideoMap(userProfile);
 
+        // 3. 特征处理
         List<RankItem> rankItems = CommonCollectionUtils.toList(rovRecallRank, RankItem::new);
-        for (RankItem item : rankItems) {
-
-            String vidStr = String.valueOf(item.getVideoId());
-
-            Map<String, Double> featureMap = new HashMap<>();
-            Map<String, String> v1Feature = videoBaseInfoMap.getOrDefault(vidStr, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
-            Map<String, Map<String, String>> videoFeatureMap = featureOriginVideo.getOrDefault(vidStr, new HashMap<>());
-            Map<String, String> b1 = videoFeatureMap.getOrDefault("alg_vid_global_feature_20250212", new HashMap<>());
-            Map<String, String> b2 = videoFeatureMap.getOrDefault("alg_vid_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b3 = videoFeatureMap.getOrDefault("alg_vid_recommend_flowpool_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b4 = videoFeatureMap.getOrDefault("alg_vid_apptype_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b5 = videoFeatureMap.getOrDefault("alg_vid_province_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b6 = videoFeatureMap.getOrDefault("alg_vid_brand_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b7 = videoFeatureMap.getOrDefault("alg_vid_hotsencetype_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b8 = videoFeatureMap.getOrDefault("alg_merge_cate1_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b9 = videoFeatureMap.getOrDefault("alg_merge_cate2_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b10 = videoFeatureMap.getOrDefault("alg_channel_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b11 = videoFeatureMap.getOrDefault("alg_festive_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b12 = videoFeatureMap.getOrDefault("alg_vid_long_period_recommend_exp_feature_20250212", new HashMap<>());
-            Map<String, String> b13 = videoFeatureMap.getOrDefault("alg_video_unionid_recommend_exp_feature_20250212", new HashMap<>());
-
-            Map<String, String> c2 = videoFeatureMap.getOrDefault("mid_merge_cate1_feature_20250212", new HashMap<>());
-            Map<String, String> c3 = videoFeatureMap.getOrDefault("mid_merge_cate2_feature_20250212", new HashMap<>());
-
-            Map<String, String> d1 = videoFeatureMap.getOrDefault("scene_type_vid_cf_feature_20250212", new HashMap<>());
-            Map<String, String> d2 = videoFeatureMap.getOrDefault("vid_click_cf_feature_20250212", new HashMap<>());
-            Map<String, String> d3 = videoFeatureMap.getOrDefault("alg_recsys_feature_cf_i2i_v2", new HashMap<>());
-
-            Map<String, Map<String, String>> b2ToB11AndB13Map = new HashMap<>();
-            b2ToB11AndB13Map.put("b2", b2);
-            b2ToB11AndB13Map.put("b3", b3);
-            b2ToB11AndB13Map.put("b4", b4);
-            b2ToB11AndB13Map.put("b5", b5);
-            b2ToB11AndB13Map.put("b6", b6);
-            b2ToB11AndB13Map.put("b7", b7);
-            b2ToB11AndB13Map.put("b8", b8);
-            b2ToB11AndB13Map.put("b9", b9);
-            b2ToB11AndB13Map.put("b10", b10);
-            b2ToB11AndB13Map.put("b11", b11);
-            b2ToB11AndB13Map.put("b13", b13);
-
-            ExtractFeature20250218.handleB1(b1, featureMap);
-            ExtractFeature20250218.handleB12(b12, featureMap);
-            ExtractFeature20250218.handleB2ToB11AndB13(b2ToB11AndB13Map, featureMap);
-            ExtractFeature20250218.handleC2ToC3(c2, c3, featureMap);
-            ExtractFeature20250218.useC7ToC8(c78FeatureMap, vidStr, featureMap);
-            ExtractFeature20250218.handleC5ToC6(c5, c6, v1Feature, featureMap);
-            ExtractFeature20250218.handleD1(d1, featureMap);
-            ExtractFeature20250218.handleD2(d2, featureMap);
-            ExtractFeature20250218.handleD3(d3, featureMap);
-            ExtractFeature20250218.handleVideoBasicFeature(v1Feature, ts, featureMap);
-            ExtractFeature20250218.handleVideoSimilarity(v1Feature, headVideoInfo, featureMap);
-
-            item.featureMapDouble = featureMap;
-        }
-
-        // 3 连续值特征分桶
-        Map<String, Float> userFeatureMap = FeatureBucketUtils.bucketFeatureV2("20250218_bucket_322.txt", userFeatureMapDouble);
-        for (RankItem item : rankItems) {
-            Map<String, Double> featureMapDouble = item.featureMapDouble;
-            item.featureMap = FeatureBucketUtils.bucketFeatureV2("20250218_bucket_322.txt", featureMapDouble);
-        }
+        Map<String, Float> userFeatureMap = getUserFeature(currentMs, param, headVideoInfo, userProfile, featureOriginUser);
+        batchGetVideoFeature(currentMs, userProfile, headVideoInfo, videoBaseInfoMap,
+                newC7Map, newC8Map, featureOriginUser, userBehaviorVideoMap, featureOriginVideo, rankItems);
 
-
-        // 4.1 排序模型计算 - str
+        // 4. 排序模型计算
         Map<String, Float> sceneFeatureMap = new HashMap<>(0);
-        List<RankItem> items = ScorerUtils.getScorerPipeline("feeds_score_config_xgb_str_20250228.conf").scoring(sceneFeatureMap, userFeatureMap, rankItems);
-        // 4.2 排序模型计算 - ros
-        this.addRosScore(rankItems, userFeatureMapDouble, sceneFeatureMap);
-
-        // 5 排序公式特征
-        double xgbRovNegRate = mergeWeight.getOrDefault("xgbRovNegRate", 0.05);
-
-        double calcVorMode = mergeWeight.getOrDefault("calcVorMode", 3d);
-        double calcRosMode = mergeWeight.getOrDefault("calcRosMode", 0d);
-        double calcStrMode = mergeWeight.getOrDefault("calcStrMode", 3d);
-
-
-        double rosAdd = mergeWeight.getOrDefault("ros_add", 0d);
-        double vorAdd = mergeWeight.getOrDefault("vor_add", 0d);
+        List<RankItem> items = ScorerUtils.getScorerPipeline("feeds_score_config_fm_xgb_20250317.conf").scoring(sceneFeatureMap, userFeatureMap, userFeatureMap, rankItems);
+
+        // 5. 排序公式特征
+        double xgbRovNegRate = mergeWeight.getOrDefault("xgbRovNegRate", 0.059);
+        double xgbNorPowerWeight = mergeWeight.getOrDefault("xgbNorPowerWeight", 1.22);
+        double xgbNorPowerExp = mergeWeight.getOrDefault("xgbNorPowerExp", 1.15);
+        Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_vor:");
+
+        // 获取权重
+        Map<String, Double> cate2Coefficient = new HashMap<>();
+        double cate2CoefficientFunc = mergeWeight.getOrDefault("cate2CoefficientFunc", 0d);
+        if (cate2CoefficientFunc == 1d) {
+            String headVidStr = String.valueOf(param.getHeadVid());
+            String mergeCate2 = this.findVideoMergeCate2(videoBaseInfoMap, headVidStr);
+            Double length = mergeWeight.getOrDefault("cate2CoefficientLength", 10000d);
+            Map<String, Double> simCateScore = this.findSimCateScore(mergeCate2, length.intValue());
+            cate2Coefficient.putAll(simCateScore);
+        }
+        Double cate2CoefficientDenominator = mergeWeight.getOrDefault("cate2CoefficientDenominator", 1d);
+        Map<String, String> regionMap = getUserRegion(param);
 
-        Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_vor_4share:");
         List<Video> result = new ArrayList<>();
         for (RankItem item : items) {
+            String vidMergeCate2 = this.findVideoMergeCate2(videoBaseInfoMap, String.valueOf(item.getVideoId()));
+
+            double strPlusCalibrationCoefficient = this.calcStrPlusCalibrationCoefficientByMergeCate2(vidMergeCate2);
+
             double score;
             double fmRovOrigin = item.getScoreRov();
             item.getScoresMap().put("fmRovOrigin", fmRovOrigin);
-            double fmRov = restoreScore(fmRovOrigin, xgbRovNegRate);
-            fmRov = this.handleStr(fmRov, calcStrMode, item, mergeWeight);
+            double fmRovCoefficientBefore = restoreScore(fmRovOrigin, xgbRovNegRate);
+            item.getScoresMap().put("fmRovCoefficientBefore", fmRovCoefficientBefore);
 
+            double fmRov = fmRovCoefficientBefore * strPlusCalibrationCoefficient;
             item.getScoresMap().put("fmRov", fmRov);
-            item.getScoresMap().put("xgbRovNegRate", xgbRovNegRate);
-            item.getScoresMap().put("calcStrMode", calcStrMode);
-
-            Map<String, String> vidFeatureMap = vid2MapFeature.getOrDefault(String.valueOf(item.getVideoId()), new HashMap<>());
-
-
-            double originScoreRos = item.getScoreRos();
-            double ros = this.handleRos(originScoreRos, calcRosMode, item, mergeWeight);
-
-            item.getScoresMap().put("RosXGBScore", originScoreRos);
-            item.getScoresMap().put("hasReturnRovScore", ros);
-            item.getScoresMap().put("calcRosMode", calcRosMode);
-
-
-            double vor24h = Double.parseDouble(vidFeatureMap.getOrDefault("vor_24h", "0"));
-            double vor = this.handleVor(vor24h, calcVorMode, item, mergeWeight);
-
-            item.getScoresMap().put("originVor", vor24h);
+            item.getScoresMap().put("strPlusCalibrationCoefficient", strPlusCalibrationCoefficient);
+            double hasReturnRovScore = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>()).getOrDefault("rov", "0"));
+            item.getScoresMap().put("hasReturnRovScore", hasReturnRovScore);
+            double norXGBScore = item.getScoresMap().getOrDefault("NorXGBScore", 0d);
+            double newNorXGBScore = norPowerCalibration(xgbNorPowerWeight, xgbNorPowerExp, norXGBScore);
+            double vor = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>()).getOrDefault("vor", "0"));
             item.getScoresMap().put("vor", vor);
-            item.getScoresMap().put("calcVorMode", calcVorMode);
 
+            Double scoreCoefficient = cate2Coefficient.getOrDefault(vidMergeCate2, 0d);
+            item.getScoresMap().put("scoreCoefficient", scoreCoefficient);
+            item.getScoresMap().put("cate2CoefficientDenominator", cate2CoefficientDenominator);
 
-            item.getScoresMap().put("rosAdd", rosAdd);
-            item.getScoresMap().put("vorAdd", vorAdd);
-            score = fmRov * (rosAdd + ros) * (vorAdd + vor);
+            score = fmRov * (0.1 + newNorXGBScore) * (0.1 + vor) * (1 + scoreCoefficient / cate2CoefficientDenominator);
 
             Video video = item.getVideo();
             video.setScore(score);
             video.setSortScore(score);
             video.setScoresMap(item.getScoresMap());
+            // video.setAllFeatureMap(item.getAllFeatureMap());
 
-            String mergeCate2 = ExtractVideoMergeCate.parseMergeCate2(String.valueOf(item.getVideoId()), featureOriginVideo);
+            String mergeCate2 = ExtractVideoMergeCate.parseMergeCate2(String.valueOf(item.getVideoId()), videoBaseInfoMap);
             if (StringUtils.isNotBlank(mergeCate2)) {
                 video.getMergeCateList().add(mergeCate2);
             }
 
-            Map<String, String> allFeatureMap = new HashMap<>();
-            item.getFeatureMapDouble().forEach((key, value) -> allFeatureMap.put(key, String.valueOf(value)));
-            video.setAllFeatureMap(allFeatureMap);
-
             if (MapUtils.isNotEmpty(feature.getVideoFeature()) && MapUtils.isNotEmpty(feature.getVideoFeature().get(item.getVideoId() + ""))) {
                 video.getMetaFeatureMap().putAll(feature.getVideoFeature().get(item.getVideoId() + ""));
             }
@@ -265,45 +177,246 @@ public class RankStrategy4RegionMergeModelV565 extends RankStrategy4RegionMergeM
             if (MapUtils.isNotEmpty(feature.getUserFeature())) {
                 video.getMetaFeatureMap().putAll(feature.getUserFeature());
             }
-
+            if (null != rtFeatureDumpsMap && !rtFeatureDumpsMap.isEmpty()) {
+                video.getMetaFeatureMap().put("rt", rtFeatureDumpsMap);
+            }
+            if (MapUtils.isNotEmpty(param.getCreativeInfoFeature())) {
+                video.getMetaFeatureMap().put("creativeInfo", param.getCreativeInfoFeature());
+            }
+            if (MapUtils.isNotEmpty(regionMap)) {
+                video.getMetaFeatureMap().put("region", regionMap);
+            }
             result.add(video);
         }
         ExtractVideoMergeCate.addOtherParam(result, videoBaseInfoMap);
         result.sort(Comparator.comparingDouble(o -> -o.getSortScore()));
+        return result;
+    }
 
-        log.info("565 run time: {}", (System.currentTimeMillis() - startTime));
+    private UserShareReturnProfile parseUserProfile(Map<String, Map<String, String>> userOriginInfo) {
+        if (null != userOriginInfo) {
+            Map<String, String> c9 = userOriginInfo.get("alg_recsys_feature_user_share_return_stat");
+            if (null != c9 && !c9.isEmpty()) {
+                String c9Str = JSONUtils.toJson(c9);
+                if (!c9Str.isEmpty()) {
+                    try {
+                        return JSON.parseObject(c9Str, UserShareReturnProfile.class);
+                    } catch (Exception e) {
+                        log.error("parseObject user profile error! value=[{}]", c9Str, e);
+                    }
+                }
+            }
+        }
+        return null;
+    }
 
-        return result;
+    private Map<String, Map<String, String>> getUserBehaviorVideoMap(UserShareReturnProfile userProfile) {
+        Set<String> vidSet = new HashSet<>();
+        if (null != userProfile) {
+            for (List<UserSRBO> list : Arrays.asList(userProfile.getM_s_s(), userProfile.getM_r_s(), userProfile.getL_s_s(), userProfile.getL_r_s())) {
+                if (null != list) {
+                    for (UserSRBO u : list) {
+                        if (null != u) {
+                            vidSet.add(u.getId() + "");
+                        }
+                    }
+                }
+            }
+        }
+
+        Map<String, Map<String, String>> historyVideoMap = new HashMap<>();
+        if (!vidSet.isEmpty()) {
+            Map<String, Map<String, Map<String, String>>> videoMap = featureService.getVideoBaseInfo("", new ArrayList<>(vidSet));
+            if (null != videoMap && !videoMap.isEmpty()) {
+                for (Map.Entry<String, Map<String, Map<String, String>>> entry : videoMap.entrySet()) {
+                    String vid = entry.getKey();
+                    Map<String, Map<String, String>> map = entry.getValue();
+                    if (null != map && map.containsKey("alg_vid_feature_basic_info")) {
+                        historyVideoMap.put(vid, map.get("alg_vid_feature_basic_info"));
+                    }
+                }
+            }
+        }
+        return historyVideoMap;
+    }
+
+    private Map<String, Float> getUserFeature(long currentMs, RankParam param, Map<String, String> headInfo, UserShareReturnProfile userProfile, Map<String, Map<String, String>> userOriginInfo) {
+        Map<String, Double> featMap = new HashMap<>();
+        // context feature
+        String appType = String.valueOf(param.getAppType());
+        String hotSceneType = String.valueOf(param.getHotSceneType());
+        FeatureV6.getContextFeature(currentMs, appType, hotSceneType, featMap);
+
+        // head video feature
+        FeatureV6.getVideoBaseFeature("h", currentMs, headInfo, featMap);
+
+        // user feature
+        Map<String, String> baseInfo = getUserBaseInfo(param);
+        FeatureV6.getUserFeature(userOriginInfo, featMap);
+        FeatureV6.getUserProfileFeature(userProfile, baseInfo, featMap);
+
+        return FeatureBucketUtils.noBucketFeature(featMap);
+    }
+
+    private Map<String, Float> getVideoFeature(long currentMs, String vid,
+                                               UserShareReturnProfile userProfile,
+                                               Map<String, String> headInfo, Map<String, String> rankInfo,
+                                               Map<String, Map<String, String[]>> c7Map,
+                                               Map<String, Map<String, String[]>> c8Map,
+                                               Map<String, Map<String, String>> userOriginInfo,
+                                               Map<String, Map<String, String>> historyVideoMap,
+                                               Map<String, Map<String, Map<String, String>>> videoOriginInfo) {
+        Map<String, Double> featMap = new HashMap<>();
+        // user & video feature
+        FeatureV6.getUserTagsCrossVideoFeature("c5", rankInfo, userOriginInfo.get("alg_mid_feature_return_tags"), featMap);
+        FeatureV6.getUserTagsCrossVideoFeature("c6", rankInfo, userOriginInfo.get("alg_mid_feature_share_tags"), featMap);
+        FeatureV6.getUserCFFeature("c7", vid, c7Map, featMap);
+        FeatureV6.getUserCFFeature("c8", vid, c8Map, featMap);
+
+        // rank video feature
+        FeatureV6.getVideoBaseFeature("r", currentMs, rankInfo, featMap);
+        FeatureV6.getVideoFeature(vid, videoOriginInfo, featMap);
+
+        // head&rank cross feature
+        FeatureV6.getHeadRankVideoCrossFeature(headInfo, rankInfo, featMap);
+
+        // user profile & rank cross
+        FeatureV6.getProfileVideoCrossFeature(currentMs, userProfile, rankInfo, historyVideoMap, featMap);
+
+        return FeatureBucketUtils.noBucketFeature(featMap);
     }
 
-    /**
-     * ros模型打分
-     */
-    private void addRosScore(List<RankItem> rankItems, Map<String, Double> userFeatureMapDouble, Map<String, Float> sceneFeatureMap) {
-        List<RankItem> rosRankItems = new ArrayList<>(rankItems.size());
-        for (RankItem rankItem : rankItems) {
-            RankItem rosRankItem = new RankItem(rankItem.getVideo());
-            // 复用了str的二分类xgboost score,所以和str保持一致
-            rosRankItem.featureMap = FeatureBucketUtils.bucketFeatureV2("20250306_ros_bucket_229.txt", rankItem.featureMapDouble);
-            rosRankItems.add(rosRankItem);
+    private void batchGetVideoFeature(long currentMs,
+                                      UserShareReturnProfile userProfile,
+                                      Map<String, String> headInfo,
+                                      Map<String, Map<String, Map<String, String>>> videoBaseInfoMap,
+                                      Map<String, Map<String, String[]>> c7Map,
+                                      Map<String, Map<String, String[]>> c8Map,
+                                      Map<String, Map<String, String>> userOriginInfo,
+                                      Map<String, Map<String, String>> historyVideoMap,
+                                      Map<String, Map<String, Map<String, String>>> videoOriginInfo,
+                                      List<RankItem> rankItems) {
+        if (null != rankItems && !rankItems.isEmpty()) {
+            List<Future<Integer>> futures = new ArrayList<>();
+            for (RankItem item : rankItems) {
+                String vid = item.getVideoId() + "";
+                Map<String, String> rankInfo = videoBaseInfoMap.getOrDefault(vid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
+                Future<Integer> future = ThreadPoolFactory.defaultPool().submit(() -> {
+                    item.featureMap = getVideoFeature(currentMs, vid, userProfile, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
+                    item.norFeatureMap = item.featureMap;
+                    return 1;
+                });
+                futures.add(future);
+            }
+
+            try {
+                for (Future<Integer> future : futures) {
+                    future.get(1000, TimeUnit.MILLISECONDS);
+                }
+            } catch (Exception e) {
+                log.error("get feature error", e);
+            }
+            // 超时后取消
+            for (Future<Integer> future : futures) {
+                try {
+                    if (!future.isDone()) {
+                        future.cancel(true);
+                    }
+                } catch (Exception e) {
+                    log.error("cancel feature error", e);
+                }
+            }
         }
-        Map<String, Float> userFeatureMap = FeatureBucketUtils.bucketFeatureV2("20250306_ros_bucket_229.txt", userFeatureMapDouble);
-        ScorerUtils.getScorerPipeline("feeds_score_config_xgb_ros_binary_20250319.conf").scoring(sceneFeatureMap, userFeatureMap, rosRankItems);
+    }
 
-        // 将ros分数补充到之前的列表中
-        Map<Long, RankItem> vidRosMap = new HashMap<>(rosRankItems.size());
-        for (RankItem rosRankItem : rosRankItems) {
-            vidRosMap.put(rosRankItem.getVideoId(), rosRankItem);
+    private Map<String, String> getUserBaseInfo(RankParam param) {
+        Map<String, String> baseInfo = new HashMap<>();
+        String province = param.getProvince();
+        if (null != province && !province.isEmpty()) {
+            baseInfo.put("province", province.replaceAll("省$", ""));
         }
 
-        for (RankItem rankItem : rankItems) {
-            if (vidRosMap.containsKey(rankItem.getVideoId())) {
-                RankItem rosRankItem = vidRosMap.get(rankItem.getVideoId());
+        String city = param.getCity();
+        if (null != city && !city.isEmpty()) {
+            baseInfo.put("city", city.replaceAll("市$", ""));
+        }
 
-                // 复用了rov的xgboost model类,所以取scoreRov的值
-                rankItem.setScoreRos(rosRankItem.getScoreRov());
-                rankItem.getScoresMap().put("RosXGBScore", rosRankItem.getScoreRov());
+        MachineInfo machineInfo = param.getMachineInfo();
+        if (null != machineInfo) {
+            String model = machineInfo.getModel();
+            if (null != model && !model.isEmpty()) {
+                baseInfo.put("model", model);
+            }
+            String brand = machineInfo.getBrand();
+            if (null != brand && !brand.isEmpty()) {
+                baseInfo.put("brand", brand);
+            }
+            String system = machineInfo.getSystem();
+            if (null != system && !system.isEmpty()) {
+                baseInfo.put("system", system);
             }
         }
+        String userChannel = param.getChannelName();
+        if (null != userChannel && !userChannel.isEmpty()) {
+            baseInfo.put("user_channel", userChannel);
+        }
+        if (FeatureUtils.firstLevel(param.getUserShareDepth())) {
+            baseInfo.put("user_level", "1st");
+        }
+        return baseInfo;
+    }
+
+    private double norPowerCalibration(double weight, double exp, double score) {
+        double newScore = weight * Math.pow(score, exp);
+        if (newScore > 100) {
+            newScore = 100;
+        } else if (newScore < score) {
+            newScore = score;
+        }
+        return newScore;
+    }
+
+    private Map<String, Double> findSimCateScore(String headCate2, int length) {
+        if (StringUtils.isBlank(headCate2)) {
+            return new HashMap<>();
+        }
+
+        String redisKey = String.format("alg_recsys_good_cate_pair_list:%s", headCate2);
+        String cate2Value = redisTemplate.opsForValue().get(redisKey);
+        if (StringUtils.isEmpty(cate2Value)) {
+            return new HashMap<>();
+        }
+
+        return this.parsePair(cate2Value, length);
+    }
+
+    private Map<String, Double> parsePair(String value, int length) {
+        if (StringUtils.isBlank(value)) {
+            return new HashMap<>();
+        }
+
+        String[] split = value.split("\t");
+        if (split.length != 2) {
+            return new HashMap<>();
+        }
+
+        String[] valueList = split[0].trim().split(",");
+        String[] scoreList = split[1].trim().split(",");
+        if (valueList.length != scoreList.length) {
+            return new HashMap<>();
+        }
+
+        int minLength = Math.min(length, valueList.length);
+        Map<String, Double> resultMap = new HashMap<>();
+        for (int i = 0; i < minLength; i++) {
+            resultMap.put(valueList[i].trim(), Double.parseDouble(scoreList[i].trim()));
+        }
+
+        return resultMap;
+    }
+
+    private String findVideoMergeCate2(Map<String, Map<String, Map<String, String>>> featureOriginVideo, String vid) {
+        Map<String, String> videoInfo = featureOriginVideo.getOrDefault(vid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
+        return videoInfo.get("merge_second_level_cate");
     }
 }

+ 29 - 6
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV566.java

@@ -45,6 +45,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
 
         long currentMs = System.currentTimeMillis();
         Set<Long> setVideo = new HashSet<>();
+        setVideo.add(param.getHeadVid());
         List<Video> rovRecallRank = new ArrayList<>();
         // -------------------5路特殊旧召回------------------
         RecallUtils.extractOldSpecialRecall(param, setVideo, rovRecallRank);
@@ -68,6 +69,16 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2Rov", 5.0).intValue(), param, HeadCate2RovRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
         //-------------------city rovn------------------
         RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------channel layer rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("channelLayerRov", 5.0).intValue(), param, ChannelLayerRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------channel layer head rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("channelLayerHeadRov", 5.0).intValue(), param, ChannelLayerHeadRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------
@@ -80,21 +91,22 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         List<String> vids = CommonCollectionUtils.toListDistinct(rovRecallRank, v -> String.valueOf(v.getVideoId()));
         String headVid = String.valueOf(param.getHeadVid());
         Map<String, Map<String, Map<String, String>>> videoBaseInfoMap = featureService.getVideoBaseInfo(headVid, vids);
-        FeatureService.Feature feature = featureService.getFeatureV3(param, videoBaseInfoMap, vids);
+        Map<String, String> headVideoInfo = videoBaseInfoMap.getOrDefault(headVid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
+        FeatureService.Feature feature = featureService.getFeatureV4(param, headVideoInfo, videoBaseInfoMap, vids);
         Map<String, Map<String, String>> featureOriginUser = feature.getUserFeature();
         Map<String, Map<String, Map<String, String>>> featureOriginVideo = feature.getVideoFeature();
-        Map<String, String> headVideoInfo = videoBaseInfoMap.getOrDefault(headVid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
 
         // 2. 用户信息预处理
         Map<String, Map<String, String[]>> newC7Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_sharecf", new HashMap<>()));
         Map<String, Map<String, String[]>> newC8Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_returncf", new HashMap<>()));
         UserShareReturnProfile userProfile = parseUserProfile(featureOriginUser);
         Map<String, Map<String, String>> userBehaviorVideoMap = getUserBehaviorVideoMap(userProfile);
+        Map<String, String> creativeInfo = param.getCreativeInfoFeature();
 
         // 3. 特征处理
         List<RankItem> rankItems = CommonCollectionUtils.toList(rovRecallRank, RankItem::new);
-        Map<String, Float> userFeatureMap = getUserFeature(currentMs, param, headVideoInfo, userProfile, featureOriginUser);
-        batchGetVideoFeature(currentMs, userProfile, headVideoInfo, videoBaseInfoMap,
+        Map<String, Float> userFeatureMap = getUserFeature(currentMs, param, creativeInfo, headVideoInfo, userProfile, featureOriginUser);
+        batchGetVideoFeature(currentMs, userProfile, creativeInfo, headVideoInfo, videoBaseInfoMap,
                 newC7Map, newC8Map, featureOriginUser, userBehaviorVideoMap, featureOriginVideo, rankItems);
 
         // 4. 排序模型计算
@@ -118,6 +130,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
             cate2Coefficient.putAll(simCateScore);
         }
         Double cate2CoefficientDenominator = mergeWeight.getOrDefault("cate2CoefficientDenominator", 1d);
+        Map<String, String> regionMap = getUserRegion(param);
 
         List<Video> result = new ArrayList<>();
         for (RankItem item : items) {
@@ -166,6 +179,12 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
             if (null != rtFeatureDumpsMap && !rtFeatureDumpsMap.isEmpty()) {
                 video.getMetaFeatureMap().put("rt", rtFeatureDumpsMap);
             }
+            if (MapUtils.isNotEmpty(param.getCreativeInfoFeature())) {
+                video.getMetaFeatureMap().put("creativeInfo", param.getCreativeInfoFeature());
+            }
+            if (MapUtils.isNotEmpty(regionMap)) {
+                video.getMetaFeatureMap().put("region", regionMap);
+            }
             result.add(video);
         }
         ExtractVideoMergeCate.addOtherParam(result, videoBaseInfoMap);
@@ -220,12 +239,13 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         return historyVideoMap;
     }
 
-    private Map<String, Float> getUserFeature(long currentMs, RankParam param, Map<String, String> headInfo, UserShareReturnProfile userProfile, Map<String, Map<String, String>> userOriginInfo) {
+    private Map<String, Float> getUserFeature(long currentMs, RankParam param, Map<String, String> creativeInfo, Map<String, String> headInfo, UserShareReturnProfile userProfile, Map<String, Map<String, String>> userOriginInfo) {
         Map<String, Double> featMap = new HashMap<>();
         // context feature
         String appType = String.valueOf(param.getAppType());
         String hotSceneType = String.valueOf(param.getHotSceneType());
         FeatureV6.getContextFeature(currentMs, appType, hotSceneType, featMap);
+        FeatureV6.getCreativeBaseFeature("e1", creativeInfo, featMap);
 
         // head video feature
         FeatureV6.getVideoBaseFeature("h", currentMs, headInfo, featMap);
@@ -240,6 +260,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
 
     private Map<String, Float> getVideoFeature(long currentMs, String vid,
                                                UserShareReturnProfile userProfile,
+                                               Map<String, String> creativeInfo,
                                                Map<String, String> headInfo, Map<String, String> rankInfo,
                                                Map<String, Map<String, String[]>> c7Map,
                                                Map<String, Map<String, String[]>> c8Map,
@@ -259,6 +280,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
 
         // head&rank cross feature
         FeatureV6.getHeadRankVideoCrossFeature(headInfo, rankInfo, featMap);
+        FeatureV6.getCreativeCrossFeature("e1", creativeInfo, rankInfo, featMap);
 
         // user profile & rank cross
         FeatureV6.getProfileVideoCrossFeature(currentMs, userProfile, rankInfo, historyVideoMap, featMap);
@@ -268,6 +290,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
 
     private void batchGetVideoFeature(long currentMs,
                                       UserShareReturnProfile userProfile,
+                                      Map<String, String> creativeInfo,
                                       Map<String, String> headInfo,
                                       Map<String, Map<String, Map<String, String>>> videoBaseInfoMap,
                                       Map<String, Map<String, String[]>> c7Map,
@@ -282,7 +305,7 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
                 String vid = item.getVideoId() + "";
                 Map<String, String> rankInfo = videoBaseInfoMap.getOrDefault(vid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
                 Future<Integer> future = ThreadPoolFactory.defaultPool().submit(() -> {
-                    item.featureMap = getVideoFeature(currentMs, vid, userProfile, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
+                    item.featureMap = getVideoFeature(currentMs, vid, userProfile, creativeInfo, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
                     item.norFeatureMap = item.featureMap;
                     return 1;
                 });

+ 31 - 40
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV567.java

@@ -8,7 +8,6 @@ import com.tzld.piaoquan.recommend.server.model.MachineInfo;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.service.FeatureService;
 import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
-import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
 import com.tzld.piaoquan.recommend.server.service.rank.extractor.ExtractVideoMergeCate;
 import com.tzld.piaoquan.recommend.server.service.rank.tansform.FeatureV6;
@@ -45,6 +44,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
 
         long currentMs = System.currentTimeMillis();
         Set<Long> setVideo = new HashSet<>();
+        setVideo.add(param.getHeadVid());
         List<Video> rovRecallRank = new ArrayList<>();
         // -------------------5路特殊旧召回------------------
         RecallUtils.extractOldSpecialRecall(param, setVideo, rovRecallRank);
@@ -68,6 +68,16 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
         RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2Rov", 5.0).intValue(), param, HeadCate2RovRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
         //-------------------city rovn------------------
         RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------return1 cate2 ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("return1Cate2Ros", 5.0).intValue(), param, Return1Cate2RosRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        //-------------------return1 cate2 str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("return1Cate2Str", 5.0).intValue(), param, Return1Cate2StrRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------
@@ -77,24 +87,24 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
 
         // 1. 批量获取特征  省份参数要对齐  headvid  要传递过来!
         // k1:视频、k2:表、k3:特征、v:特征值
+        Map<String, String> headVideoInfo = param.getHeadInfo();
         List<String> vids = CommonCollectionUtils.toListDistinct(rovRecallRank, v -> String.valueOf(v.getVideoId()));
-        String headVid = String.valueOf(param.getHeadVid());
-        Map<String, Map<String, Map<String, String>>> videoBaseInfoMap = featureService.getVideoBaseInfo(headVid, vids);
-        FeatureService.Feature feature = featureService.getFeatureV3(param, videoBaseInfoMap, vids);
+        Map<String, Map<String, Map<String, String>>> videoBaseInfoMap = featureService.getVideoBaseInfo("", vids);
+        FeatureService.Feature feature = featureService.getFeatureV4(param, headVideoInfo, videoBaseInfoMap, vids);
         Map<String, Map<String, String>> featureOriginUser = feature.getUserFeature();
         Map<String, Map<String, Map<String, String>>> featureOriginVideo = feature.getVideoFeature();
-        Map<String, String> headVideoInfo = videoBaseInfoMap.getOrDefault(headVid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
 
         // 2. 用户信息预处理
         Map<String, Map<String, String[]>> newC7Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_sharecf", new HashMap<>()));
         Map<String, Map<String, String[]>> newC8Map = FeatureV6.parseUCFScore(featureOriginUser.getOrDefault("alg_mid_feature_returncf", new HashMap<>()));
         UserShareReturnProfile userProfile = parseUserProfile(featureOriginUser);
-        Map<String, Map<String, String>> userBehaviorVideoMap = getUserBehaviorVideoMap(userProfile);
+        Map<String, Map<String, String>> userBehaviorVideoMap = param.getBehaviorVideos();
+        Map<String, String> creativeInfo = param.getCreativeInfoFeature();
 
         // 3. 特征处理
         List<RankItem> rankItems = CommonCollectionUtils.toList(rovRecallRank, RankItem::new);
-        Map<String, Float> userFeatureMap = getUserFeature(currentMs, param, headVideoInfo, userProfile, featureOriginUser);
-        batchGetVideoFeature(currentMs, userProfile, headVideoInfo, videoBaseInfoMap,
+        Map<String, Float> userFeatureMap = getUserFeature(currentMs, param, creativeInfo, headVideoInfo, userProfile, featureOriginUser);
+        batchGetVideoFeature(currentMs, userProfile, creativeInfo, headVideoInfo, videoBaseInfoMap,
                 newC7Map, newC8Map, featureOriginUser, userBehaviorVideoMap, featureOriginVideo, rankItems);
 
         // 4. 排序模型计算
@@ -118,6 +128,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
             cate2Coefficient.putAll(simCateScore);
         }
         Double cate2CoefficientDenominator = mergeWeight.getOrDefault("cate2CoefficientDenominator", 1d);
+        Map<String, String> regionMap = getUserRegion(param);
 
         List<Video> result = new ArrayList<>();
         for (RankItem item : items) {
@@ -166,6 +177,12 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
             if (null != rtFeatureDumpsMap && !rtFeatureDumpsMap.isEmpty()) {
                 video.getMetaFeatureMap().put("rt", rtFeatureDumpsMap);
             }
+            if (MapUtils.isNotEmpty(param.getCreativeInfoFeature())) {
+                video.getMetaFeatureMap().put("creativeInfo", param.getCreativeInfoFeature());
+            }
+            if (MapUtils.isNotEmpty(regionMap)) {
+                video.getMetaFeatureMap().put("region", regionMap);
+            }
             result.add(video);
         }
         ExtractVideoMergeCate.addOtherParam(result, videoBaseInfoMap);
@@ -190,42 +207,13 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
         return null;
     }
 
-    private Map<String, Map<String, String>> getUserBehaviorVideoMap(UserShareReturnProfile userProfile) {
-        Set<String> vidSet = new HashSet<>();
-        if (null != userProfile) {
-            for (List<UserSRBO> list : Arrays.asList(userProfile.getM_s_s(), userProfile.getM_r_s(), userProfile.getL_s_s(), userProfile.getL_r_s())) {
-                if (null != list) {
-                    for (UserSRBO u : list) {
-                        if (null != u) {
-                            vidSet.add(u.getId() + "");
-                        }
-                    }
-                }
-            }
-        }
-
-        Map<String, Map<String, String>> historyVideoMap = new HashMap<>();
-        if (!vidSet.isEmpty()) {
-            Map<String, Map<String, Map<String, String>>> videoMap = featureService.getVideoBaseInfo("", new ArrayList<>(vidSet));
-            if (null != videoMap && !videoMap.isEmpty()) {
-                for (Map.Entry<String, Map<String, Map<String, String>>> entry : videoMap.entrySet()) {
-                    String vid = entry.getKey();
-                    Map<String, Map<String, String>> map = entry.getValue();
-                    if (null != map && map.containsKey("alg_vid_feature_basic_info")) {
-                        historyVideoMap.put(vid, map.get("alg_vid_feature_basic_info"));
-                    }
-                }
-            }
-        }
-        return historyVideoMap;
-    }
-
-    private Map<String, Float> getUserFeature(long currentMs, RankParam param, Map<String, String> headInfo, UserShareReturnProfile userProfile, Map<String, Map<String, String>> userOriginInfo) {
+    private Map<String, Float> getUserFeature(long currentMs, RankParam param, Map<String, String> creativeInfo, Map<String, String> headInfo, UserShareReturnProfile userProfile, Map<String, Map<String, String>> userOriginInfo) {
         Map<String, Double> featMap = new HashMap<>();
         // context feature
         String appType = String.valueOf(param.getAppType());
         String hotSceneType = String.valueOf(param.getHotSceneType());
         FeatureV6.getContextFeature(currentMs, appType, hotSceneType, featMap);
+        FeatureV6.getCreativeBaseFeature("e1", creativeInfo, featMap);
 
         // head video feature
         FeatureV6.getVideoBaseFeature("h", currentMs, headInfo, featMap);
@@ -240,6 +228,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
 
     private Map<String, Float> getVideoFeature(long currentMs, String vid,
                                                UserShareReturnProfile userProfile,
+                                               Map<String, String> creativeInfo,
                                                Map<String, String> headInfo, Map<String, String> rankInfo,
                                                Map<String, Map<String, String[]>> c7Map,
                                                Map<String, Map<String, String[]>> c8Map,
@@ -259,6 +248,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
 
         // head&rank cross feature
         FeatureV6.getHeadRankVideoCrossFeature(headInfo, rankInfo, featMap);
+        FeatureV6.getCreativeCrossFeature("e1", creativeInfo, rankInfo, featMap);
 
         // user profile & rank cross
         FeatureV6.getProfileVideoCrossFeature(currentMs, userProfile, rankInfo, historyVideoMap, featMap);
@@ -268,6 +258,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
 
     private void batchGetVideoFeature(long currentMs,
                                       UserShareReturnProfile userProfile,
+                                      Map<String, String> creativeInfo,
                                       Map<String, String> headInfo,
                                       Map<String, Map<String, Map<String, String>>> videoBaseInfoMap,
                                       Map<String, Map<String, String[]>> c7Map,
@@ -282,7 +273,7 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
                 String vid = item.getVideoId() + "";
                 Map<String, String> rankInfo = videoBaseInfoMap.getOrDefault(vid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
                 Future<Integer> future = ThreadPoolFactory.defaultPool().submit(() -> {
-                    item.featureMap = getVideoFeature(currentMs, vid, userProfile, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
+                    item.featureMap = getVideoFeature(currentMs, vid, userProfile, creativeInfo, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
                     item.norFeatureMap = item.featureMap;
                     return 1;
                 });

+ 25 - 13
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV568.java

@@ -45,6 +45,7 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
 
         long currentMs = System.currentTimeMillis();
         Set<Long> setVideo = new HashSet<>();
+        setVideo.add(param.getHeadVid());
         List<Video> rovRecallRank = new ArrayList<>();
         // -------------------5路特殊旧召回------------------
         RecallUtils.extractOldSpecialRecall(param, setVideo, rovRecallRank);
@@ -68,8 +69,12 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2Rov", 5.0).intValue(), param, HeadCate2RovRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
         //-------------------city rovn------------------
         RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        // -------------------premium rov------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("preRovN", 10.0).intValue(), param, PremiumROVRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province rovn------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province str------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //-------------------priori province ros------------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------
@@ -107,6 +112,8 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         double xgbRovNegRate = mergeWeight.getOrDefault("xgbRovNegRate", 0.059);
         double xgbNorPowerWeight = mergeWeight.getOrDefault("xgbNorPowerWeight", 1.22);
         double xgbNorPowerExp = mergeWeight.getOrDefault("xgbNorPowerExp", 1.15);
+        double modelNorWeight = mergeWeight.getOrDefault("modelNorWeight", 0.5);
+        double statNorWeight = mergeWeight.getOrDefault("statNorWeight", 0.5);
         Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_vor:");
 
         // 获取权重
@@ -120,9 +127,7 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             cate2Coefficient.putAll(simCateScore);
         }
         Double cate2CoefficientDenominator = mergeWeight.getOrDefault("cate2CoefficientDenominator", 1d);
-
-        Map<String, Double> preVideosWeightMap = getPremiumVideosWeight();
-        double premiumVideosCoefficient = mergeWeight.getOrDefault("premiumVideosCoefficient", 0.3);
+        Map<String, String> regionMap = getUserRegion(param);
 
         List<Video> result = new ArrayList<>();
         for (RankItem item : items) {
@@ -135,6 +140,7 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             item.getScoresMap().put("hasReturnRovScore", hasReturnRovScore);
             double norXGBScore = item.getScoresMap().getOrDefault("NorXGBScore", 0d);
             double newNorXGBScore = norPowerCalibration(xgbNorPowerWeight, xgbNorPowerExp, norXGBScore);
+            newNorXGBScore = norFusion(modelNorWeight, newNorXGBScore, statNorWeight, hasReturnRovScore);
             double vor = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>()).getOrDefault("vor", "0"));
             item.getScoresMap().put("vor", vor);
 
@@ -144,11 +150,6 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             item.getScoresMap().put("cate2CoefficientDenominator", cate2CoefficientDenominator);
 
             score = fmRov * (0.1 + newNorXGBScore) * (0.1 + vor) * (1 + scoreCoefficient / cate2CoefficientDenominator);
-            if (preVideosWeightMap.containsKey(item.getVideoId() + "")) {
-                double preWeight = 1.0 + premiumVideosCoefficient * preVideosWeightMap.get(item.getVideoId() + "");
-                score = score * preWeight;
-                item.getScoresMap().put("preWeight", preWeight);
-            }
 
             Video video = item.getVideo();
             video.setScore(score);
@@ -176,6 +177,12 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             if (null != rtFeatureDumpsMap && !rtFeatureDumpsMap.isEmpty()) {
                 video.getMetaFeatureMap().put("rt", rtFeatureDumpsMap);
             }
+            if (MapUtils.isNotEmpty(param.getCreativeInfoFeature())) {
+                video.getMetaFeatureMap().put("creativeInfo", param.getCreativeInfoFeature());
+            }
+            if (MapUtils.isNotEmpty(regionMap)) {
+                video.getMetaFeatureMap().put("region", regionMap);
+            }
             result.add(video);
         }
         ExtractVideoMergeCate.addOtherParam(result, videoBaseInfoMap);
@@ -410,8 +417,13 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         return videoInfo.get("merge_second_level_cate");
     }
 
-    private Map<String, Double> getPremiumVideosWeight() {
-        String redisValue = redisTemplate.opsForValue().get(PremiumROVRecallStrategy.redisKey);
-        return this.parsePair(redisValue, 100);
+    private double norFusion(double modelWeight, double modelScore, double statWeight, double statScore) {
+        if (modelScore < 1E-8) {
+            return statScore;
+        } else if (statScore < 1E-8) {
+            return modelScore;
+        } else {
+            return modelWeight * modelScore + statWeight * statScore;
+        }
     }
 }

+ 69 - 9
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/tansform/FeatureV6.java

@@ -6,6 +6,7 @@ import com.tzld.piaoquan.recommend.server.service.rank.bo.VideoAttrSRBO;
 import com.tzld.piaoquan.recommend.server.service.rank.extractor.ExtractorUtils;
 import com.tzld.piaoquan.recommend.server.util.FeatureUtils;
 import com.tzld.piaoquan.recommend.server.util.SimilarityUtils;
+import com.tzld.piaoquan.recommend.similarity.word2vec.Segment;
 
 import java.util.*;
 
@@ -20,24 +21,33 @@ public class FeatureV6 {
     private static final List<String> b1Periods = Arrays.asList("1h", "3h", "6h", "24h", "72h", "168h");
     private static final List<String> b2Periods = Arrays.asList("1h", "3h", "6h", "24h");
     private static final List<String> b3Periods = Arrays.asList("1h", "3h", "6h", "24h", "72h");
-    private static final List<String> b4Periods = Arrays.asList("1h", "3h", "6h", "12h");
+    private static final List<String> b4Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h", "72h");
     private static final List<String> b5Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h", "72h");
     private static final List<String> b6Periods = Arrays.asList("1h", "24h");
     private static final List<String> b7Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h", "72h");
-    private static final List<String> b8Periods = Arrays.asList("1h", "3h", "24h");
-    private static final List<String> b9Periods = Arrays.asList("1h", "3h", "24h");
+    private static final List<String> b8Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h");
+    private static final List<String> b9Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h");
     private static final List<String> b10Periods = Arrays.asList("1h", "12h");
     private static final List<String> b11Periods = Arrays.asList("1h", "12h");
-    private static final List<String> b13Periods = Arrays.asList("1h", "3h", "24h", "72h");
+    private static final List<String> b13Periods = Arrays.asList("1h", "3h", "6h", "12h", "24h", "72h");
+    private static final List<String> b14Periods = Arrays.asList("1h", "2h", "3h", "6h", "12h");
+    private static final List<String> b15Periods = Arrays.asList("1h", "2h", "3h", "6h", "12h");
     private static final List<String> videoCateAttrs = Arrays.asList(FeatureUtils.cate1Attr, FeatureUtils.cate2Attr, FeatureUtils.festive1Attr,
             FeatureUtils.channelAttr, FeatureUtils.sourceAttr, FeatureUtils.uidAttr, FeatureUtils.mergeCate1Attr, FeatureUtils.mergeCate2Attr);
     private static final List<String> videoSimAttrs = Arrays.asList("title", "cate2", "cate2_list", "keywords");
     private static final List<String> reqVideoSimAttrs = Arrays.asList("title", "keywords", "merge_first_level_cate", "merge_second_level_cate");
+    private static final List<String> creativeSimAttrs = Arrays.asList("title");
     private static final List<String> hVideoSimAttrs = Arrays.asList("title");
     private static final List<String> cfList = Arrays.asList("share", "return");
     private static final List<String> userAttrList = Arrays.asList("province", "city", "model", "brand", "system", "user_channel", "user_level");
     private static final Set<String> appSet = new HashSet<>(Arrays.asList("0", "2", "4"));
     private static final Set<String> hotSceneSet = new HashSet<>(Arrays.asList("1008", "1007", "1058", "1074", "1010"));
+    private static final Map<String, String> histotyVideoAttrMAP = new HashMap<>();
+
+    static {
+        histotyVideoAttrMAP.put("merge_first_level_cate", "cate1");
+        histotyVideoAttrMAP.put("merge_second_level_cate", "cate2");
+    }
 
     public static void getContextFeature(long currentMs, String appType, String hotSceneType, Map<String, Double> featureMap) {
         Calendar calendar = Calendar.getInstance();
@@ -167,6 +177,8 @@ public class FeatureV6 {
         oneTypeStatFeature("b10", "return_n_uv", b10Periods, videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("alg_channel_recommend_exp_feature_20250212"), featMap);
         oneTypeStatFeature("b11", "return_n_uv", b11Periods, videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("alg_festive_recommend_exp_feature_20250212"), featMap);
         oneTypeStatFeature("b13", "return_n_uv", b13Periods, videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("alg_video_unionid_recommend_exp_feature_20250212"), featMap);
+        oneTypeStatFeature("b14", b14Periods, videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("alg_recsys_feature_video_recommend_channel_layer"), featMap);
+        oneTypeStatFeature("b15", b15Periods, videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("alg_recsys_feature_video_recommend_channel_layer_head"), featMap);
 
         // head video cf
         headVideoCFD1Feature("d1", videoOriginInfo.getOrDefault(vid, new HashMap<>()).get("scene_type_vid_cf_feature_20250212"), featMap);
@@ -216,14 +228,44 @@ public class FeatureV6 {
         getTwoVideoCrossFeature("sim", reqVideoSimAttrs, headInfo, rankInfo, featMap);
     }
 
+    public static void getCreativeBaseFeature(String prefix, Map<String, String> creativeInfo, Map<String, Double> featMap) {
+        if (null == creativeInfo || creativeInfo.isEmpty()) {
+            return;
+        }
+        if (creativeInfo.containsKey("ghId")) {
+            String ghId = creativeInfo.get("ghId");
+            if (null != ghId && !ghId.isEmpty()) {
+                String key = String.format("%s@gid@%s", prefix, ghId);
+                featMap.put(key, 1.0);
+            }
+        }
+        if (creativeInfo.containsKey("name")) {
+            String name = creativeInfo.get("name");
+            if (null != name && !name.isEmpty()) {
+                List<String> words = Segment.getWords(name);
+                for (String word : words) {
+                    if (null != word && word.length() > 1) {
+                        String key = String.format("%s@name@%s", prefix, word);
+                        featMap.put(key, 1.0);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void getCreativeCrossFeature(String prefix, Map<String, String> creativeInfo, Map<String, String> rankInfo, Map<String, Double> featMap) {
+        getTwoVideoCrossFeature(prefix, creativeSimAttrs, creativeInfo, rankInfo, featMap);
+    }
+
     public static void getProfileVideoCrossFeature(long currentMs, UserShareReturnProfile profile, Map<String, String> rankVideo, Map<String, Map<String, String>> hVideoMap, Map<String, Double> featMap) {
         if (null == profile) {
             return;
         }
-        getRSCrossFeature("c9_mss", currentMs, seqMaxN, profile.getM_s_s(), rankVideo, hVideoMap, featMap);
-        getRSCrossFeature("c9_mrs", currentMs, seqMaxN, profile.getM_r_s(), rankVideo, hVideoMap, featMap);
-        getRSCrossFeature("c9_lss", currentMs, seqLastN, profile.getL_s_s(), rankVideo, hVideoMap, featMap);
-        getRSCrossFeature("c9_lrs", currentMs, seqLastN, profile.getL_r_s(), rankVideo, hVideoMap, featMap);
+        getRSCrossFeature(false, "c9_mss", currentMs, seqMaxN, profile.getM_s_s(), rankVideo, hVideoMap, featMap);
+        getRSCrossFeature(false, "c9_mrs", currentMs, seqMaxN, profile.getM_r_s(), rankVideo, hVideoMap, featMap);
+        getRSCrossFeature(true, "c9_lss", currentMs, seqLastN, profile.getL_s_s(), rankVideo, hVideoMap, featMap);
+        getRSCrossFeature(false, "c9_lrs", currentMs, seqLastN, profile.getL_r_s(), rankVideo, hVideoMap, featMap);
+        getRSCrossFeature(true, "c9_lr1s", currentMs, seqLastN, profile.getL_r1_s(), rankVideo, hVideoMap, featMap);
 
         if (null == rankVideo || rankVideo.isEmpty()) {
             return;
@@ -234,7 +276,7 @@ public class FeatureV6 {
         getVideoAttrSRCrossFeature("c9_l2s", rankVideo.getOrDefault("festive_label2", ""), profile.getL2_s(), featMap);
     }
 
-    private static void getRSCrossFeature(String prefix, long currentMs, int maxN, List<UserSRBO> list, Map<String, String> rankVideo, Map<String, Map<String, String>> hVideoMap, Map<String, Double> featMap) {
+    private static void getRSCrossFeature(boolean flag, String prefix, long currentMs, int maxN, List<UserSRBO> list, Map<String, String> rankVideo, Map<String, Map<String, String>> hVideoMap, Map<String, Double> featMap) {
         if (null != list && !list.isEmpty()) {
             for (int i = 0; i < list.size() && i < maxN; i++) {
                 UserSRBO u = list.get(i);
@@ -265,6 +307,9 @@ public class FeatureV6 {
                         if (null != hVideoMap && hVideoMap.containsKey(vid)) {
                             Map<String, String> hVideo = hVideoMap.get(vid);
                             getTwoVideoCrossFeature(baseKey, hVideoSimAttrs, hVideo, rankVideo, featMap);
+                            if (flag) {
+                                getHistoryVideoCateFeature(baseKey, hVideo, featMap);
+                            }
                         }
                     }
                 }
@@ -515,4 +560,19 @@ public class FeatureV6 {
         }
         return map.isEmpty() ? 0 : Double.parseDouble(map.getOrDefault(name, "0.0"));
     }
+
+    private static void getHistoryVideoCateFeature(String prefix, Map<String, String> videoInfo, Map<String, Double> featMap) {
+        if (null == videoInfo || videoInfo.isEmpty()) {
+            return;
+        }
+        for (Map.Entry<String, String> entry : histotyVideoAttrMAP.entrySet()) {
+            String attr = entry.getKey();
+            String attrVal = videoInfo.getOrDefault(attr, "");
+            attrVal = attrVal.trim();
+            if (!attrVal.isEmpty() && !attrVal.equals("unknown")) {
+                String key = String.format("%s@%s@%s", prefix, entry.getValue(), attrVal);
+                featMap.put(key, 1.0);
+            }
+        }
+    }
 }

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java

@@ -47,4 +47,5 @@ public class RecallParam {
     private Long requestVideoId;
     private String currentPageSource;
     private Map<String, String> creativeInfoFeature;
+    private Map<String, Map<String, String>> behaviorVideos;
 }

+ 9 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java

@@ -119,9 +119,16 @@ public class RecallService implements ApplicationContextAware {
         strategies.add(strategyMap.get(HeadCate2RovRecallStrategy.class.getSimpleName()));
         strategies.add(strategyMap.get(CityRovnRecallStrategy.class.getSimpleName()));
         strategies.add(strategyMap.get(PrioriProvinceRovnRecallStrategy.class.getSimpleName()));
+        strategies.add(strategyMap.get(PrioriProvinceStrRecallStrategy.class.getSimpleName()));
+        strategies.add(strategyMap.get(PrioriProvinceRosRecallStrategy.class.getSimpleName()));
         Set<String> abExpCodes = param.getAbExpCodes();
-        if (CollectionUtils.isNotEmpty(abExpCodes) && abExpCodes.contains("568")) {
-            strategies.add(strategyMap.get(PremiumROVRecallStrategy.class.getSimpleName()));
+        if (CollectionUtils.isNotEmpty(abExpCodes) && abExpCodes.contains("566")) {
+            strategies.add(strategyMap.get(ChannelLayerRovnRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(ChannelLayerHeadRovnRecallStrategy.class.getSimpleName()));
+        }
+        if (CollectionUtils.isNotEmpty(abExpCodes) && abExpCodes.contains("567")) {
+            strategies.add(strategyMap.get(Return1Cate2RosRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(Return1Cate2StrRecallStrategy.class.getSimpleName()));
         }
 
         // 命中用户黑名单不走流量池

+ 112 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRedisRecallStrategy.java

@@ -0,0 +1,112 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+public abstract class AbstractRedisRecallStrategy implements RecallStrategy {
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            List<String> keys = getRedisKeys(param);
+            if (null != keys && !keys.isEmpty()) {
+                List<String> values = redisTemplate.opsForValue().multiGet(keys);
+                if (null != values && !values.isEmpty()) {
+                    Pair<List<Long>, Map<Long, Double>> pair = parseVidAndScore(param.getVideoId(), values);
+                    fillVideoResult(param, pair, videosResult);
+                }
+            }
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", pushFrom(), e);
+        }
+        return videosResult;
+    }
+
+    private Pair<List<Long>, Map<Long, Double>> parseVidAndScore(Long headVid, List<String> values) {
+        int topN = getTopN();
+        Map<Long, Double> scoresMap = new HashMap<>();
+        if (null != values && !values.isEmpty()) {
+            for (String value : values) {
+                if (null != value && !value.isEmpty()) {
+                    String[] cells = value.split("\t");
+                    if (2 == cells.length) {
+                        List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                        List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
+                        if (!ids.isEmpty() && ids.size() == scores.size()) {
+                            for (int i = 0; i < ids.size(); ++i) {
+                                long vid = ids.get(i);
+                                double score = scores.get(i);
+                                if (vid == headVid) {
+                                    continue;
+                                }
+                                double oldScore = scoresMap.getOrDefault(vid, 0.0);
+                                scoresMap.put(vid, Math.max(oldScore, score));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        List<Long> idsList = new ArrayList<>();
+        if (!scoresMap.isEmpty()) {
+            List<Pair<Long, Double>> list = new ArrayList<>();
+            for (Map.Entry<Long, Double> entry : scoresMap.entrySet()) {
+                list.add(MutablePair.of(entry.getKey(), entry.getValue()));
+            }
+            list.sort(Comparator.comparingDouble(o -> -o.getRight()));
+            for (Pair<Long, Double> pair : list) {
+                idsList.add(pair.getLeft());
+                if (idsList.size() >= topN) {
+                    break;
+                }
+            }
+        }
+        return new MutablePair<>(idsList, scoresMap);
+    }
+
+    private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
+        if (null != pair) {
+            List<Long> ids = pair.getLeft();
+            Map<Long, Double> scoresMap = pair.getRight();
+            if (null != ids && null != scoresMap && !ids.isEmpty()) {
+                FilterParam filterParam = FilterParamFactory.create(param, ids);
+                FilterResult filterResult = filterService.filter(filterParam);
+                if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+                    filterResult.getVideoIds().forEach(vid -> {
+                        Video video = new Video();
+                        video.setVideoId(vid);
+                        video.setRovScore(scoresMap.getOrDefault(vid, 0D));
+                        video.setPushFrom(pushFrom());
+                        videosResult.add(video);
+                    });
+                }
+            }
+        }
+    }
+
+    abstract List<String> getRedisKeys(RecallParam param);
+
+    abstract int getTopN();
+}

+ 119 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ChannelLayerHeadRovnRecallStrategy.java

@@ -0,0 +1,119 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import com.tzld.piaoquan.recommend.server.util.FeatureUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class ChannelLayerHeadRovnRecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    public static final String PUSH_FROM = "channel_layer_head_rovn";
+    public static final String redisKeyPrefix = "channel_layer_head_rovn_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            String userChannel = param.getChannelName();
+            if (null == userChannel || userChannel.isEmpty()) {
+                return videosResult;
+            }
+            String userLayer = "非0层";
+            if (FeatureUtils.firstLevel(param.getUserShareDepth())) {
+                userLayer = "0层";
+            }
+            Map<String, String> headInfo = param.getHeadInfo();
+            if (MapUtils.isEmpty(headInfo)) {
+                return videosResult;
+            }
+            String unionid = headInfo.getOrDefault("title_time_w_h_unionid", "");
+            if (unionid.isEmpty()) {
+                return videosResult;
+            }
+            String redisKey = String.format("%s:%s:%s:%s", redisKeyPrefix, userChannel, userLayer, unionid);
+            String redisValue = redisTemplate.opsForValue().get(redisKey);
+            if (null == redisValue || redisValue.isEmpty()) {
+                return videosResult;
+            }
+            Pair<List<Long>, Map<Long, Double>> pair = parsePair(redisValue, param.getVideoId(), 50);
+            fillVideoResult(param, pair, videosResult);
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private Pair<List<Long>, Map<Long, Double>> parsePair(String data, long headVid, int size) {
+        List<Long> idsList = new ArrayList<>();
+        Map<Long, Double> scoresMap = new HashMap<>();
+        if (!StringUtils.isBlank(data)) {
+            String[] cells = data.split("\t");
+            if (2 == cells.length) {
+                List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty() && ids.size() == scores.size()) {
+                    int minSize = Math.min(size, ids.size());
+                    for (int i = 0; i < minSize; ++i) {
+                        long id = ids.get(i);
+                        double score = scores.get(i);
+                        if (headVid != id && !scoresMap.containsKey(id)) {
+                            idsList.add(id);
+                            scoresMap.put(id, score);
+                        }
+                    }
+                }
+            }
+        }
+        return new MutablePair<>(idsList, scoresMap);
+    }
+
+    private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
+        if (null != pair) {
+            List<Long> ids = pair.getLeft();
+            Map<Long, Double> scoresMap = pair.getRight();
+            if (null != ids && null != scoresMap && !ids.isEmpty()) {
+                FilterParam filterParam = FilterParamFactory.create(param, ids);
+                FilterResult filterResult = filterService.filter(filterParam);
+                if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+                    filterResult.getVideoIds().forEach(vid -> {
+                        Video video = new Video();
+                        video.setVideoId(vid);
+                        video.setRovScore(scoresMap.getOrDefault(vid, 0D));
+                        video.setPushFrom(pushFrom());
+                        videosResult.add(video);
+                    });
+                }
+            }
+        }
+    }
+}

+ 110 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ChannelLayerRovnRecallStrategy.java

@@ -0,0 +1,110 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import com.tzld.piaoquan.recommend.server.util.FeatureUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class ChannelLayerRovnRecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    public static final String PUSH_FROM = "channel_layer_rovn";
+    public static final String redisKeyPrefix = "channel_layer_rovn_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            String userChannel = param.getChannelName();
+            if (null == userChannel || userChannel.isEmpty()) {
+                return videosResult;
+            }
+            String userLayer = "非0层";
+            if (FeatureUtils.firstLevel(param.getUserShareDepth())) {
+                userLayer = "0层";
+            }
+            String redisKey = String.format("%s:%s:%s", redisKeyPrefix, userChannel, userLayer);
+            String redisValue = redisTemplate.opsForValue().get(redisKey);
+            if (null == redisValue || redisValue.isEmpty()) {
+                return videosResult;
+            }
+            Pair<List<Long>, Map<Long, Double>> pair = parsePair(redisValue, param.getVideoId(), 50);
+            fillVideoResult(param, pair, videosResult);
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private Pair<List<Long>, Map<Long, Double>> parsePair(String data, long headVid, int size) {
+        List<Long> idsList = new ArrayList<>();
+        Map<Long, Double> scoresMap = new HashMap<>();
+        if (!StringUtils.isBlank(data)) {
+            String[] cells = data.split("\t");
+            if (2 == cells.length) {
+                List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty() && ids.size() == scores.size()) {
+                    int minSize = Math.min(size, ids.size());
+                    for (int i = 0; i < minSize; ++i) {
+                        long id = ids.get(i);
+                        double score = scores.get(i);
+                        if (headVid != id && !scoresMap.containsKey(id)) {
+                            idsList.add(id);
+                            scoresMap.put(id, score);
+                        }
+                    }
+                }
+            }
+        }
+        return new MutablePair<>(idsList, scoresMap);
+    }
+
+    private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
+        if (null != pair) {
+            List<Long> ids = pair.getLeft();
+            Map<Long, Double> scoresMap = pair.getRight();
+            if (null != ids && null != scoresMap && !ids.isEmpty()) {
+                FilterParam filterParam = FilterParamFactory.create(param, ids);
+                FilterResult filterResult = filterService.filter(filterParam);
+                if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+                    filterResult.getVideoIds().forEach(vid -> {
+                        Video video = new Video();
+                        video.setVideoId(vid);
+                        video.setRovScore(scoresMap.getOrDefault(vid, 0D));
+                        video.setPushFrom(pushFrom());
+                        videosResult.add(video);
+                    });
+                }
+            }
+        }
+    }
+}

+ 102 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceRosRecallStrategy.java

@@ -0,0 +1,102 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class PrioriProvinceRosRecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    public static final String PUSH_FROM = "priori_province_ros";
+    public static final String redisKeyPrefix = "priori_province_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            String province = param.getProvince().replaceAll("省$", "");
+            String redisKey = String.format("%s:%s:%s", redisKeyPrefix, province, "ros");
+            String redisValue = redisTemplate.opsForValue().get(redisKey);
+            if (null == redisValue || redisValue.isEmpty()) {
+                return videosResult;
+            }
+            Pair<List<Long>, Map<Long, Double>> pair = parsePair(redisValue, param.getVideoId(), 50);
+            fillVideoResult(param, pair, videosResult);
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private Pair<List<Long>, Map<Long, Double>> parsePair(String data, long headVid, int size) {
+        List<Long> idsList = new ArrayList<>();
+        Map<Long, Double> scoresMap = new HashMap<>();
+        if (!StringUtils.isBlank(data)) {
+            String[] cells = data.split("\t");
+            if (2 == cells.length) {
+                List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty() && ids.size() == scores.size()) {
+                    int minSize = Math.min(size, ids.size());
+                    for (int i = 0; i < minSize; ++i) {
+                        long id = ids.get(i);
+                        double score = scores.get(i);
+                        if (headVid != id && !scoresMap.containsKey(id)) {
+                            idsList.add(id);
+                            scoresMap.put(id, score);
+                        }
+                    }
+                }
+            }
+        }
+        return new MutablePair<>(idsList, scoresMap);
+    }
+
+    private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
+        if (null != pair) {
+            List<Long> ids = pair.getLeft();
+            Map<Long, Double> scoresMap = pair.getRight();
+            if (null != ids && null != scoresMap && !ids.isEmpty()) {
+                FilterParam filterParam = FilterParamFactory.create(param, ids);
+                FilterResult filterResult = filterService.filter(filterParam);
+                if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+                    filterResult.getVideoIds().forEach(vid -> {
+                        Video video = new Video();
+                        video.setVideoId(vid);
+                        video.setRovScore(scoresMap.getOrDefault(vid, 0D));
+                        video.setPushFrom(pushFrom());
+                        videosResult.add(video);
+                    });
+                }
+            }
+        }
+    }
+}

+ 2 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceRovnRecallStrategy.java

@@ -31,7 +31,7 @@ public class PrioriProvinceRovnRecallStrategy implements RecallStrategy {
     public RedisTemplate<String, String> redisTemplate;
 
     public static final String PUSH_FROM = "priori_province_rovn";
-    public static final String redisKeyPrefix = "priori_province_rovn_recall";
+    public static final String redisKeyPrefix = "priori_province_recall";
 
     @Override
     public String pushFrom() {
@@ -43,7 +43,7 @@ public class PrioriProvinceRovnRecallStrategy implements RecallStrategy {
         List<Video> videosResult = new ArrayList<>();
         try {
             String province = param.getProvince().replaceAll("省$", "");
-            String redisKey = String.format("%s:%s", redisKeyPrefix, province);
+            String redisKey = String.format("%s:%s:%s", redisKeyPrefix, province, "rovn");
             String redisValue = redisTemplate.opsForValue().get(redisKey);
             if (null == redisValue || redisValue.isEmpty()) {
                 return videosResult;

+ 102 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PrioriProvinceStrRecallStrategy.java

@@ -0,0 +1,102 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class PrioriProvinceStrRecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    public static final String PUSH_FROM = "priori_province_str";
+    public static final String redisKeyPrefix = "priori_province_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            String province = param.getProvince().replaceAll("省$", "");
+            String redisKey = String.format("%s:%s:%s", redisKeyPrefix, province, "str");
+            String redisValue = redisTemplate.opsForValue().get(redisKey);
+            if (null == redisValue || redisValue.isEmpty()) {
+                return videosResult;
+            }
+            Pair<List<Long>, Map<Long, Double>> pair = parsePair(redisValue, param.getVideoId(), 50);
+            fillVideoResult(param, pair, videosResult);
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private Pair<List<Long>, Map<Long, Double>> parsePair(String data, long headVid, int size) {
+        List<Long> idsList = new ArrayList<>();
+        Map<Long, Double> scoresMap = new HashMap<>();
+        if (!StringUtils.isBlank(data)) {
+            String[] cells = data.split("\t");
+            if (2 == cells.length) {
+                List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty() && ids.size() == scores.size()) {
+                    int minSize = Math.min(size, ids.size());
+                    for (int i = 0; i < minSize; ++i) {
+                        long id = ids.get(i);
+                        double score = scores.get(i);
+                        if (headVid != id && !scoresMap.containsKey(id)) {
+                            idsList.add(id);
+                            scoresMap.put(id, score);
+                        }
+                    }
+                }
+            }
+        }
+        return new MutablePair<>(idsList, scoresMap);
+    }
+
+    private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
+        if (null != pair) {
+            List<Long> ids = pair.getLeft();
+            Map<Long, Double> scoresMap = pair.getRight();
+            if (null != ids && null != scoresMap && !ids.isEmpty()) {
+                FilterParam filterParam = FilterParamFactory.create(param, ids);
+                FilterResult filterResult = filterService.filter(filterParam);
+                if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+                    filterResult.getVideoIds().forEach(vid -> {
+                        Video video = new Video();
+                        video.setVideoId(vid);
+                        video.setRovScore(scoresMap.getOrDefault(vid, 0D));
+                        video.setPushFrom(pushFrom());
+                        videosResult.add(video);
+                    });
+                }
+            }
+        }
+    }
+}

+ 53 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Return1Cate2RosRecallStrategy.java

@@ -0,0 +1,53 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class Return1Cate2RosRecallStrategy extends AbstractRedisRecallStrategy {
+    private static final int keysN = 2;
+    private static final int topN = 80;
+    public static final String PUSH_FORM = "return_1_cate2_ros";
+    private static final String redisKeyPrefix = "return_1_cate2_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FORM;
+    }
+
+    @Override
+    protected List<String> getRedisKeys(RecallParam param) {
+        List<String> keys = new ArrayList<>();
+        if (null != param && null != param.getBehaviorVideos() && null != param.getUserProfile()) {
+            Map<String, Map<String, String>> behaviorVideos = param.getBehaviorVideos();
+            List<UserSRBO> l_r1_s = param.getUserProfile().getL_r1_s();
+            if (null != l_r1_s) {
+                for (UserSRBO u : l_r1_s) {
+                    if (null != u) {
+                        String vid = String.valueOf(u.getId());
+                        if (behaviorVideos.containsKey(vid)) {
+                            String cate2 = behaviorVideos.get(vid).getOrDefault("merge_second_level_cate", "");
+                            if (null != cate2 && !cate2.isEmpty()) {
+                                keys.add(String.format("%s:%s:%s", redisKeyPrefix, cate2, "ros"));
+                                if (keys.size() >= keysN) {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return keys;
+    }
+
+    @Override
+    protected int getTopN() {
+        return topN;
+    }
+}

+ 53 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Return1Cate2StrRecallStrategy.java

@@ -0,0 +1,53 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class Return1Cate2StrRecallStrategy extends AbstractRedisRecallStrategy {
+    private static final int keysN = 2;
+    private static final int topN = 80;
+    public static final String PUSH_FORM = "return_1_cate2_str";
+    private static final String redisKeyPrefix = "return_1_cate2_recall";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FORM;
+    }
+
+    @Override
+    protected List<String> getRedisKeys(RecallParam param) {
+        List<String> keys = new ArrayList<>();
+        if (null != param && null != param.getBehaviorVideos() && null != param.getUserProfile()) {
+            Map<String, Map<String, String>> behaviorVideos = param.getBehaviorVideos();
+            List<UserSRBO> l_r1_s = param.getUserProfile().getL_r1_s();
+            if (null != l_r1_s) {
+                for (UserSRBO u : l_r1_s) {
+                    if (null != u) {
+                        String vid = String.valueOf(u.getId());
+                        if (behaviorVideos.containsKey(vid)) {
+                            String cate2 = behaviorVideos.get(vid).getOrDefault("merge_second_level_cate", "");
+                            if (null != cate2 && !cate2.isEmpty()) {
+                                keys.add(String.format("%s:%s:%s", redisKeyPrefix, cate2, "str"));
+                                if (keys.size() >= keysN) {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return keys;
+    }
+
+    @Override
+    protected int getTopN() {
+        return topN;
+    }
+}

+ 59 - 78
recommend-server-service/src/main/resources/feeds_score_config_fm_xgb_20250729.conf

@@ -7,10 +7,11 @@ scorer-config = {
   nor-score-config = {
     scorer-name = "com.tzld.piaoquan.recommend.server.service.score.NorXGBRegressionScorer"
     scorer-priority = 97
-    model-path = "zhangbo/model_xgb_for_recsys_v1_ros.tar.gz"
+    model-path = "zhangbo/model_xgb_for_recsys_v7_nor.tar.gz"
     param = {
-      localDir = "xgboost/recsys_v1_ros"
+      localDir = "xgboost/recsys_v7_nor"
       features = [
+      "b0_12h@return_1_uv",
       "b0_12h@ros1_#",
       "b0_12h@ros_#",
       "b0_12h@ros_minus1_#",
@@ -20,6 +21,7 @@ scorer-config = {
       "b0_12h@ros_one",
       "b0_12h@rovn1_#",
       "b0_12h@rovn_#",
+      "b0_1h@return_1_uv",
       "b0_1h@ros1_#",
       "b0_1h@ros_#",
       "b0_1h@ros_minus1_#",
@@ -29,6 +31,7 @@ scorer-config = {
       "b0_1h@ros_one",
       "b0_1h@rovn1_#",
       "b0_1h@rovn_#",
+      "b0_3h@return_1_uv",
       "b0_3h@ros1_#",
       "b0_3h@ros_#",
       "b0_3h@ros_minus1_#",
@@ -38,6 +41,7 @@ scorer-config = {
       "b0_3h@ros_one",
       "b0_3h@rovn1_#",
       "b0_3h@rovn_#",
+      "b0_6h@return_1_uv",
       "b0_6h@ros1_#",
       "b0_6h@ros_#",
       "b0_6h@ros_minus1_#",
@@ -69,80 +73,79 @@ scorer-config = {
       "b11_12h@str",
       "b11_12h@str_plus",
       "b13_1h@exp",
+      "b13_1h@is_share",
       "b13_1h@ros_#",
       "b13_1h@ros_minus_#",
       "b13_1h@ros_n_#",
       "b13_1h@ros_one",
       "b13_1h@rovn_#",
+      "b13_1h@share_cnt",
       "b13_1h@str",
       "b13_1h@str_plus",
       "b13_24h@exp",
+      "b13_24h@is_share",
       "b13_24h@ros_#",
       "b13_24h@ros_minus_#",
       "b13_24h@ros_n_#",
       "b13_24h@ros_one",
       "b13_24h@rovn_#",
+      "b13_24h@share_cnt",
       "b13_24h@str",
       "b13_24h@str_plus",
       "b13_3h@exp",
+      "b13_3h@is_share",
       "b13_3h@ros_#",
       "b13_3h@ros_minus_#",
       "b13_3h@ros_n_#",
       "b13_3h@ros_one",
       "b13_3h@rovn_#",
+      "b13_3h@share_cnt",
       "b13_3h@str",
       "b13_3h@str_plus",
       "b13_72h@exp",
+      "b13_72h@is_share",
       "b13_72h@ros_#",
       "b13_72h@ros_minus_#",
       "b13_72h@ros_n_#",
       "b13_72h@ros_one",
       "b13_72h@rovn_#",
+      "b13_72h@share_cnt",
       "b13_72h@str",
       "b13_72h@str_plus",
-      "b1_1h@exp",
       "b1_1h@ros_#",
       "b1_1h@ros_minus_#",
       "b1_1h@ros_n_#",
       "b1_1h@ros_one",
       "b1_1h@rovn_#",
-      "b1_24h@exp",
       "b1_24h@ros_#",
       "b1_24h@ros_minus_#",
       "b1_24h@ros_n_#",
       "b1_24h@ros_one",
       "b1_24h@rovn_#",
-      "b1_3h@exp",
       "b1_3h@ros_#",
       "b1_3h@ros_minus_#",
       "b1_3h@ros_n_#",
       "b1_3h@ros_one",
       "b1_3h@rovn_#",
-      "b1_72h@exp",
       "b1_72h@ros_#",
       "b1_72h@ros_minus_#",
       "b1_72h@ros_n_#",
       "b1_72h@ros_one",
       "b1_72h@rovn_#",
-      "b2_24h@exp",
+      "b2_24h@return_n_uv",
       "b2_24h@ros_#",
       "b2_24h@ros_minus_#",
       "b2_24h@ros_n_#",
       "b2_24h@ros_one",
       "b2_24h@rovn_#",
-      "b2_3h@exp",
+      "b2_3h@return_n_uv",
       "b2_3h@ros_#",
       "b2_3h@ros_minus_#",
       "b2_3h@ros_n_#",
       "b2_3h@ros_one",
       "b2_3h@rovn_#",
-      "b2_6h@exp",
-      "b2_6h@ros_#",
-      "b2_6h@ros_minus_#",
-      "b2_6h@ros_n_#",
-      "b2_6h@ros_one",
-      "b2_6h@rovn_#",
       "b3_24h@is_share",
+      "b3_24h@return_n_uv",
       "b3_24h@ros_#",
       "b3_24h@ros_minus_#",
       "b3_24h@ros_n_#",
@@ -150,22 +153,15 @@ scorer-config = {
       "b3_24h@rovn_#",
       "b3_24h@str",
       "b3_24h@str_plus",
-      "b3_3h@is_share",
-      "b3_3h@ros_#",
-      "b3_3h@ros_minus_#",
-      "b3_3h@ros_n_#",
-      "b3_3h@ros_one",
-      "b3_3h@rovn_#",
-      "b3_3h@str",
-      "b3_3h@str_plus",
-      "b3_6h@is_share",
-      "b3_6h@ros_#",
-      "b3_6h@ros_minus_#",
-      "b3_6h@ros_n_#",
-      "b3_6h@ros_one",
-      "b3_6h@rovn_#",
-      "b3_6h@str",
-      "b3_6h@str_plus",
+      "b3_72h@is_share",
+      "b3_72h@return_n_uv",
+      "b3_72h@ros_#",
+      "b3_72h@ros_minus_#",
+      "b3_72h@ros_n_#",
+      "b3_72h@ros_one",
+      "b3_72h@rovn_#",
+      "b3_72h@str",
+      "b3_72h@str_plus",
       "b4_12h@is_share",
       "b4_12h@return_n_uv",
       "b4_12h@ros_#",
@@ -173,13 +169,6 @@ scorer-config = {
       "b4_12h@ros_n_#",
       "b4_12h@ros_one",
       "b4_12h@rovn_#",
-      "b4_1h@is_share",
-      "b4_1h@return_n_uv",
-      "b4_1h@ros_#",
-      "b4_1h@ros_minus_#",
-      "b4_1h@ros_n_#",
-      "b4_1h@ros_one",
-      "b4_1h@rovn_#",
       "b4_3h@is_share",
       "b4_3h@return_n_uv",
       "b4_3h@ros_#",
@@ -187,13 +176,6 @@ scorer-config = {
       "b4_3h@ros_n_#",
       "b4_3h@ros_one",
       "b4_3h@rovn_#",
-      "b4_6h@is_share",
-      "b4_6h@return_n_uv",
-      "b4_6h@ros_#",
-      "b4_6h@ros_minus_#",
-      "b4_6h@ros_n_#",
-      "b4_6h@ros_one",
-      "b4_6h@rovn_#",
       "b5_12h@exp",
       "b5_12h@is_share",
       "b5_12h@return_n_uv",
@@ -218,11 +200,13 @@ scorer-config = {
       "b5_1h@str_plus",
       "b5_24h@exp",
       "b5_24h@is_share",
+      "b5_24h@return_n_uv",
       "b5_24h@ros_#",
       "b5_24h@ros_minus_#",
       "b5_24h@ros_n_#",
       "b5_24h@ros_one",
       "b5_24h@rovn_#",
+      "b5_24h@share_cnt",
       "b5_24h@str",
       "b5_24h@str_plus",
       "b5_3h@exp",
@@ -249,11 +233,13 @@ scorer-config = {
       "b5_6h@str_plus",
       "b5_72h@exp",
       "b5_72h@is_share",
+      "b5_72h@return_n_uv",
       "b5_72h@ros_#",
       "b5_72h@ros_minus_#",
       "b5_72h@ros_n_#",
       "b5_72h@ros_one",
       "b5_72h@rovn_#",
+      "b5_72h@share_cnt",
       "b5_72h@str",
       "b5_72h@str_plus",
       "b6_1h@is_share",
@@ -266,6 +252,7 @@ scorer-config = {
       "b6_1h@str",
       "b6_1h@str_plus",
       "b6_24h@is_share",
+      "b6_24h@return_n_uv",
       "b6_24h@ros_#",
       "b6_24h@ros_minus_#",
       "b6_24h@ros_n_#",
@@ -273,17 +260,6 @@ scorer-config = {
       "b6_24h@rovn_#",
       "b6_24h@str",
       "b6_24h@str_plus",
-      "b7_12h@exp",
-      "b7_12h@is_share",
-      "b7_12h@return_n_uv",
-      "b7_12h@ros_#",
-      "b7_12h@ros_minus_#",
-      "b7_12h@ros_n_#",
-      "b7_12h@ros_one",
-      "b7_12h@rovn_#",
-      "b7_12h@str",
-      "b7_12h@str_plus",
-      "b7_1h@exp",
       "b7_1h@is_share",
       "b7_1h@return_n_uv",
       "b7_1h@ros_#",
@@ -293,8 +269,8 @@ scorer-config = {
       "b7_1h@rovn_#",
       "b7_1h@str",
       "b7_1h@str_plus",
-      "b7_24h@exp",
       "b7_24h@is_share",
+      "b7_24h@return_n_uv",
       "b7_24h@ros_#",
       "b7_24h@ros_minus_#",
       "b7_24h@ros_n_#",
@@ -302,7 +278,6 @@ scorer-config = {
       "b7_24h@rovn_#",
       "b7_24h@str",
       "b7_24h@str_plus",
-      "b7_3h@exp",
       "b7_3h@is_share",
       "b7_3h@return_n_uv",
       "b7_3h@ros_#",
@@ -312,18 +287,8 @@ scorer-config = {
       "b7_3h@rovn_#",
       "b7_3h@str",
       "b7_3h@str_plus",
-      "b7_6h@exp",
-      "b7_6h@is_share",
-      "b7_6h@return_n_uv",
-      "b7_6h@ros_#",
-      "b7_6h@ros_minus_#",
-      "b7_6h@ros_n_#",
-      "b7_6h@ros_one",
-      "b7_6h@rovn_#",
-      "b7_6h@str",
-      "b7_6h@str_plus",
-      "b7_72h@exp",
       "b7_72h@is_share",
+      "b7_72h@return_n_uv",
       "b7_72h@ros_#",
       "b7_72h@ros_minus_#",
       "b7_72h@ros_n_#",
@@ -331,7 +296,15 @@ scorer-config = {
       "b7_72h@rovn_#",
       "b7_72h@str",
       "b7_72h@str_plus",
+      "b8_1h@is_share",
+      "b8_1h@return_n_uv",
+      "b8_1h@ros_#",
+      "b8_1h@ros_minus_#",
+      "b8_1h@rovn_#",
+      "b8_1h@str",
+      "b8_1h@str_plus",
       "b8_24h@is_share",
+      "b8_24h@return_n_uv",
       "b8_24h@ros_#",
       "b8_24h@ros_minus_#",
       "b8_24h@rovn_#",
@@ -344,7 +317,15 @@ scorer-config = {
       "b8_3h@rovn_#",
       "b8_3h@str",
       "b8_3h@str_plus",
+      "b9_1h@is_share",
+      "b9_1h@return_n_uv",
+      "b9_1h@ros_#",
+      "b9_1h@ros_minus_#",
+      "b9_1h@rovn_#",
+      "b9_1h@str",
+      "b9_1h@str_plus",
       "b9_24h@is_share",
+      "b9_24h@return_n_uv",
       "b9_24h@ros_#",
       "b9_24h@ros_minus_#",
       "b9_24h@rovn_#",
@@ -391,32 +372,32 @@ scorer-config = {
       "c9@m_s_cnt",
       "c9@r_pv",
       "c9@r_uv",
-      "c9@ros_#",
-      "c9@ros_minus_#",
+      "c9@ros",
+      "c9@ros_minus",
       "c9@ros_one",
       "c9@s_cnt",
       "c9@s_pv",
       "c9_c1s@mu",
-      "c9_c1s@ros_#",
-      "c9_c1s@ros_minus_#",
+      "c9_c1s@ros",
+      "c9_c1s@ros_minus",
       "c9_c1s@ros_one",
       "c9_c1s@rp",
       "c9_c1s@ru",
       "c9_c1s@sp",
       "c9_c2s@mu",
-      "c9_c2s@ros_#",
-      "c9_c2s@ros_minus_#",
+      "c9_c2s@ros",
+      "c9_c2s@ros_minus",
       "c9_c2s@ros_one",
       "c9_c2s@rp",
       "c9_c2s@ru",
       "c9_c2s@sp",
       "c9_l1s@mu",
-      "c9_l1s@ros_#",
-      "c9_l1s@ros_minus_#",
+      "c9_l1s@ros",
+      "c9_l1s@ros_minus",
       "c9_l1s@sp",
       "c9_l2s@mu",
-      "c9_l2s@ros_#",
-      "c9_l2s@ros_minus_#",
+      "c9_l2s@ros",
+      "c9_l2s@ros_minus",
       "c9_l2s@sp",
       "c9_lrs@1@title",
       "c9_lrs@1@ts",

+ 109 - 89
recommend-server-service/src/main/resources/feeds_score_config_fm_xgb_20250808.conf

@@ -7,50 +7,43 @@ scorer-config = {
   nor-score-config = {
     scorer-name = "com.tzld.piaoquan.recommend.server.service.score.NorXGBRegressionScorer"
     scorer-priority = 97
-    model-path = "zhangbo/model_xgb_for_recsys_v7_nor.tar.gz"
+    model-path = "zhangbo/model_xgb_for_recsys_v2_ros.tar.gz"
     param = {
-      localDir = "xgboost/recsys_v7_nor"
+      localDir = "xgboost/recsys_v2_ros"
       features = [
       "b0_12h@return_1_uv",
-      "b0_12h@ros1_#",
       "b0_12h@ros_#",
-      "b0_12h@ros_minus1_#",
+      "b0_12h@ros1_#",
       "b0_12h@ros_minus_#",
-      "b0_12h@ros_n1_#",
+      "b0_12h@ros_minus1_#",
       "b0_12h@ros_n_#",
+      "b0_12h@ros_n1_#",
       "b0_12h@ros_one",
-      "b0_12h@rovn1_#",
       "b0_12h@rovn_#",
-      "b0_1h@return_1_uv",
-      "b0_1h@ros1_#",
+      "b0_12h@rovn1_#",
       "b0_1h@ros_#",
-      "b0_1h@ros_minus1_#",
+      "b0_1h@ros1_#",
       "b0_1h@ros_minus_#",
-      "b0_1h@ros_n1_#",
+      "b0_1h@ros_minus1_#",
       "b0_1h@ros_n_#",
+      "b0_1h@ros_n1_#",
       "b0_1h@ros_one",
-      "b0_1h@rovn1_#",
       "b0_1h@rovn_#",
-      "b0_3h@return_1_uv",
-      "b0_3h@ros1_#",
+      "b0_1h@rovn1_#",
       "b0_3h@ros_#",
-      "b0_3h@ros_minus1_#",
+      "b0_3h@ros1_#",
       "b0_3h@ros_minus_#",
-      "b0_3h@ros_n1_#",
+      "b0_3h@ros_minus1_#",
       "b0_3h@ros_n_#",
-      "b0_3h@ros_one",
-      "b0_3h@rovn1_#",
       "b0_3h@rovn_#",
-      "b0_6h@return_1_uv",
-      "b0_6h@ros1_#",
+      "b0_3h@rovn1_#",
       "b0_6h@ros_#",
-      "b0_6h@ros_minus1_#",
+      "b0_6h@ros1_#",
       "b0_6h@ros_minus_#",
-      "b0_6h@ros_n1_#",
+      "b0_6h@ros_minus1_#",
       "b0_6h@ros_n_#",
       "b0_6h@ros_one",
       "b0_6h@rovn1_#",
-      "b0_6h@rovn_#",
       "b10_12h@is_share",
       "b10_12h@return_n_uv",
       "b10_12h@ros_#",
@@ -72,8 +65,20 @@ scorer-config = {
       "b11_12h@rovn_#",
       "b11_12h@str",
       "b11_12h@str_plus",
-      "b13_1h@exp",
-      "b13_1h@is_share",
+      "b1_1h@ros_#",
+      "b1_1h@ros_minus_#",
+      "b1_1h@ros_n_#",
+      "b1_24h@ros_#",
+      "b1_24h@ros_minus_#",
+      "b1_24h@ros_n_#",
+      "b1_24h@ros_one",
+      "b1_24h@rovn_#",
+      "b13_12h@exp",
+      "b13_12h@ros_minus_#",
+      "b13_12h@ros_n_#",
+      "b13_12h@ros_one",
+      "b13_12h@str",
+      "b13_12h@str_plus",
       "b13_1h@ros_#",
       "b13_1h@ros_minus_#",
       "b13_1h@ros_n_#",
@@ -89,18 +94,9 @@ scorer-config = {
       "b13_24h@ros_n_#",
       "b13_24h@ros_one",
       "b13_24h@rovn_#",
-      "b13_24h@share_cnt",
       "b13_24h@str",
       "b13_24h@str_plus",
-      "b13_3h@exp",
-      "b13_3h@is_share",
       "b13_3h@ros_#",
-      "b13_3h@ros_minus_#",
-      "b13_3h@ros_n_#",
-      "b13_3h@ros_one",
-      "b13_3h@rovn_#",
-      "b13_3h@share_cnt",
-      "b13_3h@str",
       "b13_3h@str_plus",
       "b13_72h@exp",
       "b13_72h@is_share",
@@ -112,21 +108,48 @@ scorer-config = {
       "b13_72h@share_cnt",
       "b13_72h@str",
       "b13_72h@str_plus",
-      "b1_1h@ros_#",
-      "b1_1h@ros_minus_#",
-      "b1_1h@ros_n_#",
-      "b1_1h@ros_one",
-      "b1_1h@rovn_#",
-      "b1_24h@ros_#",
-      "b1_24h@ros_minus_#",
-      "b1_24h@ros_n_#",
-      "b1_24h@ros_one",
-      "b1_24h@rovn_#",
-      "b1_3h@ros_#",
       "b1_3h@ros_minus_#",
       "b1_3h@ros_n_#",
       "b1_3h@ros_one",
-      "b1_3h@rovn_#",
+      "b14_12h@return_1_uv",
+      "b14_12h@ros_#",
+      "b14_12h@ros1_#",
+      "b14_12h@ros_minus_#",
+      "b14_12h@ros_minus1_#",
+      "b14_12h@ros_n_#",
+      "b14_12h@ros_n1_#",
+      "b14_12h@ros_one",
+      "b14_12h@rovn_#",
+      "b14_12h@rovn1_#",
+      "b14_12h@str",
+      "b14_12h@str_plus",
+      "b14_3h@return_1_uv",
+      "b14_3h@ros_#",
+      "b14_3h@ros1_#",
+      "b14_3h@ros_minus_#",
+      "b14_3h@ros_minus1_#",
+      "b14_3h@ros_n_#",
+      "b14_3h@ros_n1_#",
+      "b14_3h@ros_one",
+      "b14_3h@rovn_#",
+      "b14_3h@rovn1_#",
+      "b14_3h@str",
+      "b14_3h@str_plus",
+      "b15_12h@ros_#",
+      "b15_12h@ros_minus_#",
+      "b15_12h@ros_minus1_#",
+      "b15_12h@ros_n1_#",
+      "b15_12h@ros_one",
+      "b15_12h@rovn_#",
+      "b15_12h@rovn1_#",
+      "b15_12h@str",
+      "b15_12h@str_plus",
+      "b15_3h@ros_n_#",
+      "b15_3h@ros_one",
+      "b15_3h@rovn_#",
+      "b15_3h@rovn1_#",
+      "b15_3h@str",
+      "b15_3h@str_plus",
       "b1_72h@ros_#",
       "b1_72h@ros_minus_#",
       "b1_72h@ros_n_#",
@@ -138,21 +161,19 @@ scorer-config = {
       "b2_24h@ros_n_#",
       "b2_24h@ros_one",
       "b2_24h@rovn_#",
-      "b2_3h@return_n_uv",
-      "b2_3h@ros_#",
-      "b2_3h@ros_minus_#",
       "b2_3h@ros_n_#",
-      "b2_3h@ros_one",
-      "b2_3h@rovn_#",
+      "b2_6h@ros_minus_#",
+      "b2_6h@ros_n_#",
+      "b2_6h@ros_one",
       "b3_24h@is_share",
-      "b3_24h@return_n_uv",
       "b3_24h@ros_#",
       "b3_24h@ros_minus_#",
       "b3_24h@ros_n_#",
-      "b3_24h@ros_one",
       "b3_24h@rovn_#",
       "b3_24h@str",
       "b3_24h@str_plus",
+      "b3_6h@rovn_#",
+      "b3_6h@str",
       "b3_72h@is_share",
       "b3_72h@return_n_uv",
       "b3_72h@ros_#",
@@ -163,14 +184,11 @@ scorer-config = {
       "b3_72h@str",
       "b3_72h@str_plus",
       "b4_12h@is_share",
-      "b4_12h@return_n_uv",
       "b4_12h@ros_#",
       "b4_12h@ros_minus_#",
       "b4_12h@ros_n_#",
       "b4_12h@ros_one",
       "b4_12h@rovn_#",
-      "b4_3h@is_share",
-      "b4_3h@return_n_uv",
       "b4_3h@ros_#",
       "b4_3h@ros_minus_#",
       "b4_3h@ros_n_#",
@@ -210,25 +228,20 @@ scorer-config = {
       "b5_24h@str",
       "b5_24h@str_plus",
       "b5_3h@exp",
-      "b5_3h@is_share",
       "b5_3h@return_n_uv",
       "b5_3h@ros_#",
       "b5_3h@ros_minus_#",
       "b5_3h@ros_n_#",
       "b5_3h@ros_one",
       "b5_3h@rovn_#",
-      "b5_3h@share_cnt",
       "b5_3h@str",
       "b5_3h@str_plus",
       "b5_6h@exp",
-      "b5_6h@is_share",
-      "b5_6h@return_n_uv",
       "b5_6h@ros_#",
       "b5_6h@ros_minus_#",
       "b5_6h@ros_n_#",
       "b5_6h@ros_one",
       "b5_6h@rovn_#",
-      "b5_6h@share_cnt",
       "b5_6h@str",
       "b5_6h@str_plus",
       "b5_72h@exp",
@@ -260,6 +273,14 @@ scorer-config = {
       "b6_24h@rovn_#",
       "b6_24h@str",
       "b6_24h@str_plus",
+      "b7_12h@is_share",
+      "b7_12h@ros_#",
+      "b7_12h@ros_minus_#",
+      "b7_12h@ros_n_#",
+      "b7_12h@ros_one",
+      "b7_12h@rovn_#",
+      "b7_12h@str",
+      "b7_12h@str_plus",
       "b7_1h@is_share",
       "b7_1h@return_n_uv",
       "b7_1h@ros_#",
@@ -278,8 +299,6 @@ scorer-config = {
       "b7_24h@rovn_#",
       "b7_24h@str",
       "b7_24h@str_plus",
-      "b7_3h@is_share",
-      "b7_3h@return_n_uv",
       "b7_3h@ros_#",
       "b7_3h@ros_minus_#",
       "b7_3h@ros_n_#",
@@ -296,6 +315,13 @@ scorer-config = {
       "b7_72h@rovn_#",
       "b7_72h@str",
       "b7_72h@str_plus",
+      "b8_12h@is_share",
+      "b8_12h@return_n_uv",
+      "b8_12h@ros_#",
+      "b8_12h@ros_minus_#",
+      "b8_12h@rovn_#",
+      "b8_12h@str",
+      "b8_12h@str_plus",
       "b8_1h@is_share",
       "b8_1h@return_n_uv",
       "b8_1h@ros_#",
@@ -317,13 +343,18 @@ scorer-config = {
       "b8_3h@rovn_#",
       "b8_3h@str",
       "b8_3h@str_plus",
+      "b9_12h@is_share",
+      "b9_12h@return_n_uv",
+      "b9_12h@ros_#",
+      "b9_12h@ros_minus_#",
+      "b9_12h@rovn_#",
+      "b9_12h@str",
+      "b9_12h@str_plus",
       "b9_1h@is_share",
-      "b9_1h@return_n_uv",
       "b9_1h@ros_#",
       "b9_1h@ros_minus_#",
       "b9_1h@rovn_#",
       "b9_1h@str",
-      "b9_1h@str_plus",
       "b9_24h@is_share",
       "b9_24h@return_n_uv",
       "b9_24h@ros_#",
@@ -331,13 +362,8 @@ scorer-config = {
       "b9_24h@rovn_#",
       "b9_24h@str",
       "b9_24h@str_plus",
-      "b9_3h@is_share",
-      "b9_3h@return_n_uv",
       "b9_3h@ros_#",
       "b9_3h@ros_minus_#",
-      "b9_3h@rovn_#",
-      "b9_3h@str",
-      "b9_3h@str_plus",
       "c1_168h@is_share",
       "c1_168h@return_n_uv",
       "c1_168h@ros_#",
@@ -368,15 +394,6 @@ scorer-config = {
       "c6_tags_3d@maxscore",
       "c6_tags_7d@avgscore",
       "c6_tags_7d@maxscore",
-      "c9@m_r_uv",
-      "c9@m_s_cnt",
-      "c9@r_pv",
-      "c9@r_uv",
-      "c9@ros",
-      "c9@ros_minus",
-      "c9@ros_one",
-      "c9@s_cnt",
-      "c9@s_pv",
       "c9_c1s@mu",
       "c9_c1s@ros",
       "c9_c1s@ros_minus",
@@ -391,14 +408,8 @@ scorer-config = {
       "c9_c2s@rp",
       "c9_c2s@ru",
       "c9_c2s@sp",
-      "c9_l1s@mu",
-      "c9_l1s@ros",
-      "c9_l1s@ros_minus",
-      "c9_l1s@sp",
-      "c9_l2s@mu",
       "c9_l2s@ros",
       "c9_l2s@ros_minus",
-      "c9_l2s@sp",
       "c9_lrs@1@title",
       "c9_lrs@1@ts",
       "c9_lrs@1@uv",
@@ -417,14 +428,21 @@ scorer-config = {
       "c9_mrs@2@title",
       "c9_mrs@2@ts",
       "c9_mrs@2@uv",
+      "c9@m_r_uv",
+      "c9@m_s_cnt",
       "c9_mss@1@cnt",
       "c9_mss@1@title",
       "c9_mss@1@ts",
       "c9_mss@2@cnt",
       "c9_mss@2@title",
       "c9_mss@2@ts",
-      "d1@ros_cf_rank",
-      "d1@ros_cf_score",
+      "c9@ros",
+      "c9@ros_minus",
+      "c9@ros_one",
+      "c9@r_pv",
+      "c9@r_uv",
+      "c9@s_cnt",
+      "c9@s_pv",
       "d1@rov_cf_rank",
       "d1@rov_cf_score",
       "d2@rank",
@@ -433,16 +451,18 @@ scorer-config = {
       "d3@return_n",
       "d3@rovn",
       "h@bit_rate",
-      "h@total_time",
-      "h@ts",
       "hour",
       "hr_sim@cate2",
       "hr_sim@cate2_list",
       "hr_sim@keywords",
       "hr_sim@title",
+      "h@total_time",
+      "h@ts",
       "r@bit_rate",
       "r@total_time",
-      "r@ts"
+      "r@ts",
+      "user_level@1st",
+      "r@merge_second_level_cate@早中晚好"
       ]
     }
   }