Bladeren bron

c9特征mid替换为uid & 头部视频类目召回

jch 1 maand geleden
bovenliggende
commit
9cc7b938d1

+ 29 - 7
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/FeatureService.java

@@ -224,6 +224,7 @@ public class FeatureService {
 
     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);
         String headVid = String.valueOf(param.getHeadVid());
         String province = param.getProvince().replaceAll("省$", "");
         String apptype = param.getAppType() + "";
@@ -280,20 +281,20 @@ public class FeatureService {
             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");
+                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)));
                 // 特殊情况
                 //protos.add(genWithKeyMap("mid_merge_cate1_feature_20250212", vid, ImmutableMap.of("mid", mid, "merge_cate1", merge_cate1)));
 
-                String merge_cate2 = baseInfo.getOrDefault("merge_second_level_cate", "unknown");
+                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)));
                 // 特殊情况
                 //protos.add(genWithKeyMap("mid_merge_cate2_feature_20250212", vid, ImmutableMap.of("mid", mid, "merge_cate2", merge_cate2)));
 
-                String channel = baseInfo.getOrDefault("channel", "unknown");
+                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");
+                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");
@@ -315,7 +316,7 @@ public class FeatureService {
         // ********************* new mid ******************
         protos.add(genWithMid("mid_global_feature_20250212", mid));
         protos.add(genWithMid("mid_u2u_friend_index_feature_20250212", mid));
-        protos.add(genWithMid("alg_recsys_feature_user_share_return_stat", mid));
+        protos.add(genWithMid("alg_recsys_feature_user_share_return_stat", mergeMid));
 
         return getFeatureByProto(protos);
     }
@@ -362,11 +363,12 @@ public class FeatureService {
         return this.getFeatureByProto(protos);
     }
 
-    public UserShareReturnProfile getUserProfile(String mid) {
+    public UserShareReturnProfile getUserProfile(String uid, String mid) {
         try {
+            String mergeMid = getMergeMid(uid, mid);
             String table = "alg_recsys_feature_user_share_return_stat";
             List<FeatureKeyProto> protos = new ArrayList<>();
-            protos.add(genWithMid(table, mid));
+            protos.add(genWithMid(table, mergeMid));
             Feature feature = getFeatureByProto(protos);
             Map<String, Map<String, String>> userFeature = feature.getUserFeature();
             if (null != userFeature) {
@@ -384,6 +386,18 @@ public class FeatureService {
         return null;
     }
 
+    public Map<String, String> getHeadVideoInfo(String headVid) {
+        try {
+            if (null != headVid && !headVid.isEmpty()) {
+                Map<String, Map<String, Map<String, String>>> videoBaseInfoMap = getVideoBaseInfo(headVid, new ArrayList<>());
+                return videoBaseInfoMap.getOrDefault(headVid, new HashMap<>()).get("alg_vid_feature_basic_info");
+            }
+        } catch (Exception e) {
+            log.error("get head info error! value=[{}]", headVid, e);
+        }
+        return null;
+    }
+
     private Feature getFeatureByProto(List<FeatureKeyProto> protos) {
         Map<String, String> result = remoteService.getFeature(protos);
         Feature feature = new Feature();
@@ -414,6 +428,14 @@ public class FeatureService {
         return feature;
     }
 
+    private String getMergeMid(String uid, String mid) {
+        if (null != uid && !uid.isEmpty() && !uid.equals("null")) {
+            return uid;
+        } else {
+            return mid;
+        }
+    }
+
     private final String videoUkFormat = "v:%s:%s";
     private final String userUkFormat = "u:%s";
     private final String kvUkFormat = "v:%s:%s";

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

@@ -429,6 +429,7 @@ public class RecommendService {
         rankParam.setTopK(param.getTopK());
         rankParam.setAppType(param.getAppType());
         rankParam.setMid(param.getMid());
+        rankParam.setUid(param.getUid());
         rankParam.setProvince(param.getProvince());
         rankParam.setCity(param.getCity());
         rankParam.setMachineInfo(param.getMachineInfo());

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

@@ -20,6 +20,7 @@ public class RankParam {
     private int appType;
     private boolean specialRecommend;
     private String mid;
+    private String uid;
     private String province;
     private String city;
     private MachineInfo machineInfo;

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

@@ -90,6 +90,12 @@ public class RankStrategy4RegionMergeModelV567 extends RankStrategy4RegionMergeM
         // -------------------cate2------------------
         int cate2RecallN = mergeWeight.getOrDefault("cate2RecallN", 5.0).intValue();
         addRecall(param, cate2RecallN, UserCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------head province cate1------------------
+        int headCate1RecallN = mergeWeight.getOrDefault("headCate1RecallN", 5.0).intValue();
+        addRecall(param, headCate1RecallN, HeadProvinceCate1RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        // -------------------head province cate2------------------
+        int headCate2RecallN = mergeWeight.getOrDefault("headCate2RecallN", 5.0).intValue();
+        addRecall(param, headCate2RecallN, HeadProvinceCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
 
         //-------------------排-------------------
         //-------------------序-------------------

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

@@ -117,6 +117,8 @@ public class RecallService implements ApplicationContextAware {
         if (CollectionUtils.isNotEmpty(abExpCodes) && abExpCodes.contains("567")) {
             strategies.add(strategyMap.get(UserCate1RecallStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(UserCate2RecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HeadProvinceCate1RecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HeadProvinceCate2RecallStrategy.class.getSimpleName()));
         }
 
         // 命中用户黑名单不走流量池

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

@@ -0,0 +1,106 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.FeatureService;
+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.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 HeadProvinceCate1RecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    @Autowired
+    private FeatureService featureService;
+
+    public static final String PUSH_FORM = "recall_strategy_head_cate1";
+    public static final String redisKeyPrefix = "province_merge_cate_recall:cate1";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FORM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            if (null == param.getVideoId() || 0 == param.getVideoId()) {
+                return videosResult;
+            }
+            Long headVid = param.getVideoId();
+            Map<String, String> headVideoInfo = featureService.getHeadVideoInfo(String.valueOf(headVid));
+            if (null != headVideoInfo) {
+                String cate = headVideoInfo.getOrDefault("merge_first_level_cate", "").trim();
+                if (!cate.isEmpty() && !"unknown".equals(cate)) {
+                    String province = param.getProvince().replaceAll("省$", "");
+                    String key = String.format("%s:%s:%s", redisKeyPrefix, province, cate);
+                    String value = redisTemplate.opsForValue().get(key);
+                    if (null == value || value.isEmpty()) {
+                        return videosResult;
+                    }
+                    List<Long> vidList = parseVidList(headVid, value);
+                    fillVideoResult(param, vidList, videosResult);
+                }
+            }
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private List<Long> parseVidList(Long headVid, String data) {
+        List<Long> vidList = new ArrayList<>();
+        if (null != data && !data.isEmpty()) {
+            String[] pair = data.split("\t");
+            if (2 == pair.length) {
+                Set<Long> hit = new HashSet<>();
+                hit.add(headVid);
+                List<Long> ids = Arrays.stream(pair[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty()) {
+                    for (Long id : ids) {
+                        if (!hit.contains(id)) {
+                            hit.add(id);
+                            vidList.add(id);
+                        }
+                    }
+                }
+            }
+        }
+        return vidList;
+    }
+
+    private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
+        FilterParam filterParam = FilterParamFactory.create(param, vidList);
+        FilterResult filterResult = filterService.filter(filterParam);
+        if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+            List<Long> filterIds = filterResult.getVideoIds();
+            int n = filterIds.size();
+            for (int i = 0; i < n; i++) {
+                Video video = new Video();
+                video.setVideoId(filterIds.get(i));
+                video.setRovScore(n - i);
+                video.setPushFrom(pushFrom());
+                videosResult.add(video);
+            }
+        }
+    }
+}

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

@@ -0,0 +1,106 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.FeatureService;
+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.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 HeadProvinceCate2RecallStrategy implements RecallStrategy {
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    @Autowired
+    private FeatureService featureService;
+
+    public static final String PUSH_FORM = "recall_strategy_head_cate2";
+    public static final String redisKeyPrefix = "province_merge_cate_recall:cate2";
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FORM;
+    }
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videosResult = new ArrayList<>();
+        try {
+            if (null == param.getVideoId() || 0 == param.getVideoId()) {
+                return videosResult;
+            }
+            Long headVid = param.getVideoId();
+            Map<String, String> headVideoInfo = featureService.getHeadVideoInfo(String.valueOf(headVid));
+            if (null != headVideoInfo) {
+                String cate = headVideoInfo.getOrDefault("merge_second_level_cate", "").trim();
+                if (!cate.isEmpty() && !"unknown".equals(cate)) {
+                    String province = param.getProvince().replaceAll("省$", "");
+                    String key = String.format("%s:%s:%s", redisKeyPrefix, province, cate);
+                    String value = redisTemplate.opsForValue().get(key);
+                    if (null == value || value.isEmpty()) {
+                        return videosResult;
+                    }
+                    List<Long> vidList = parseVidList(headVid, value);
+                    fillVideoResult(param, vidList, videosResult);
+                }
+            }
+        } catch (Exception e) {
+            log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
+        }
+        return videosResult;
+    }
+
+    private List<Long> parseVidList(Long headVid, String data) {
+        List<Long> vidList = new ArrayList<>();
+        if (null != data && !data.isEmpty()) {
+            String[] pair = data.split("\t");
+            if (2 == pair.length) {
+                Set<Long> hit = new HashSet<>();
+                hit.add(headVid);
+                List<Long> ids = Arrays.stream(pair[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
+                if (!ids.isEmpty()) {
+                    for (Long id : ids) {
+                        if (!hit.contains(id)) {
+                            hit.add(id);
+                            vidList.add(id);
+                        }
+                    }
+                }
+            }
+        }
+        return vidList;
+    }
+
+    private void fillVideoResult(RecallParam param, List<Long> vidList, List<Video> videosResult) {
+        FilterParam filterParam = FilterParamFactory.create(param, vidList);
+        FilterResult filterResult = filterService.filter(filterParam);
+        if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
+            List<Long> filterIds = filterResult.getVideoIds();
+            int n = filterIds.size();
+            for (int i = 0; i < n; i++) {
+                Video video = new Video();
+                video.setVideoId(filterIds.get(i));
+                video.setRovScore(n - i);
+                video.setPushFrom(pushFrom());
+                videosResult.add(video);
+            }
+        }
+    }
+}

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

@@ -48,7 +48,7 @@ public class UserCate1RecallStrategy implements RecallStrategy {
     public List<Video> recall(RecallParam param) {
         List<Video> videosResult = new ArrayList<>();
         try {
-            UserShareReturnProfile userProfile = featureService.getUserProfile(param.getMid());
+            UserShareReturnProfile userProfile = featureService.getUserProfile(param.getUid(), param.getMid());
             if (null != userProfile && null != userProfile.getC1_s()) {
                 List<String> keys = getRedisKey(userProfile.getC1_s());
                 if (!keys.isEmpty()) {

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

@@ -48,7 +48,7 @@ public class UserCate2RecallStrategy implements RecallStrategy {
     public List<Video> recall(RecallParam param) {
         List<Video> videosResult = new ArrayList<>();
         try {
-            UserShareReturnProfile userProfile = featureService.getUserProfile(param.getMid());
+            UserShareReturnProfile userProfile = featureService.getUserProfile(param.getUid(), param.getMid());
             if (null != userProfile && null != userProfile.getC2_s()) {
                 List<String> keys = getRedisKey(userProfile.getC2_s());
                 if (!keys.isEmpty()) {