Browse Source

feat:修改Bug

zhaohaipeng 3 ngày trước cách đây
mục cha
commit
fc2384eb2e

+ 12 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/FeatureService.java

@@ -347,6 +347,18 @@ public class FeatureService {
         return null;
     }
 
+    public Map<String, String> getUserSocialRecallInfo(String mid) {
+        if (StringUtils.isEmpty(mid)) {
+            return new HashMap<>();
+        }
+
+
+        List<FeatureKeyProto> protos = new ArrayList<>();
+        protos.add(genWithMid("alg_recsys_user_social_recall_feature_day", mid));
+        Feature feature = getFeatureByProto(protos);
+        return feature.getUserFeature().getOrDefault("alg_recsys_user_social_recall_feature_day", new HashMap<>());
+    }
+
     private Feature getFeatureByProto(List<FeatureKeyProto> protos) {
         Map<String, String> result = remoteService.getFeature(protos);
         Feature feature = new Feature();

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

@@ -494,6 +494,9 @@ public class RecommendService {
         String vid = String.valueOf(param.getVideoId());
         UserShareReturnProfile userProfile = featureService.getUserProfile(param.getUid(), param.getMid());
         Map<String, Map<String, String>> behaviorVideos = featureService.getBehaviorVideos(vid, userProfile);
+
+        Map<String, String> userSocialRecallInfo = featureService.getUserSocialRecallInfo(param.getMid());
+
         Map<String, String> headVideoInfo;
         if (null != behaviorVideos && behaviorVideos.containsKey(vid)) {
             headVideoInfo = behaviorVideos.get(vid);
@@ -509,6 +512,7 @@ public class RecommendService {
         recallParam.setHeadInfo(headVideoInfo);
         recallParam.setUserRTShareList(param.getUserRTShareList());
         recallParam.setBehaviorVideos(behaviorVideos);
+        recallParam.setUserSocialRecallInfo(userSocialRecallInfo);
         RecallResult recallResult = recallService.recall(recallParam);
 
         long recallTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);

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

@@ -79,8 +79,13 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         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);
-        //-------------------priori premium rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriPremiumRovn", 0.0).intValue(), param, PrioriPremiumRovnRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
+        //-------------------social direct recall---------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("socialDirect", 5.0).intValue(), param, SocialI2IDirectRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //---------------social history share recall------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("socialHistoryShare", 5.0).intValue(), param, SocialI2IHistoryShareRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+        //---------------social history click recall------------
+        RecallUtils.extractRecall(mergeWeight.getOrDefault("socialHistoryClick", 5.0).intValue(), param, SocialI2IHistoryClickRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+
 
         //-------------------排-------------------
         //-------------------序-------------------
@@ -118,10 +123,6 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         double xgbRovNegRate = mergeWeight.getOrDefault("xgbRovNegRate", 0.059);
         double xgbNorPowerWeight = mergeWeight.getOrDefault("xgbNorPowerWeight", 1.22);
         double xgbNorPowerExp = mergeWeight.getOrDefault("xgbNorPowerExp", 1.15);
-        double prioriHighValue = mergeWeight.getOrDefault("prioriHighValue", 1.5);
-        double prioriHighWeight = mergeWeight.getOrDefault("prioriHighWeight", 1.3);
-        double prioriLowValue = mergeWeight.getOrDefault("prioriLowValue", 0.5);
-        double prioriLowWeight = mergeWeight.getOrDefault("prioriLowWeight", 1.0);
         Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_vor:");
 
         // 获取权重
@@ -136,33 +137,27 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
         }
         Double cate2CoefficientDenominator = mergeWeight.getOrDefault("cate2CoefficientDenominator", 1d);
         Map<String, String> contextInfo = getContextInfo(param);
-        Map<String, Double> prioriVidProvinceRovn = this.getPrioriVidProvinceRovn(param.getProvince(), items, videoBaseInfoMap);
 
         List<Video> result = new ArrayList<>();
         for (RankItem item : items) {
             double score;
-            String vid = String.valueOf(item.getVideoId());
             double fmRovOrigin = item.getScoreRov();
             item.getScoresMap().put("fmRovOrigin", fmRovOrigin);
             double fmRov = restoreScore(fmRovOrigin, xgbRovNegRate);
             item.getScoresMap().put("fmRov", fmRov);
-            double hasReturnRovScore = Double.parseDouble(vid2MapFeature.getOrDefault(vid, new HashMap<>()).getOrDefault("rov", "0"));
+            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(vid, new HashMap<>()).getOrDefault("vor", "0"));
+            double vor = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>()).getOrDefault("vor", "0"));
             item.getScoresMap().put("vor", vor);
 
-            String vidMergeCate2 = this.findVideoMergeCate2(videoBaseInfoMap, vid);
+            String vidMergeCate2 = this.findVideoMergeCate2(videoBaseInfoMap, String.valueOf(item.getVideoId()));
             Double scoreCoefficient = cate2Coefficient.getOrDefault(vidMergeCate2, 0d);
             item.getScoresMap().put("scoreCoefficient", scoreCoefficient);
             item.getScoresMap().put("cate2CoefficientDenominator", cate2CoefficientDenominator);
 
-            double prioriWeight = getPrioriVidProvinceWeight(prioriHighValue, prioriHighWeight, prioriLowValue, prioriLowWeight, vid, prioriVidProvinceRovn);
-            score = prioriWeight * fmRov * (0.1 + newNorXGBScore) * (0.1 + vor) * (1 + scoreCoefficient / cate2CoefficientDenominator);
-            if (!ExtractorUtils.isDoubleEqualToZero(prioriWeight - 1.0)) {
-                item.getScoresMap().put("prioriWeight", prioriWeight);
-            }
+            score = fmRov * (0.1 + newNorXGBScore) * (0.1 + vor) * (1 + scoreCoefficient / cate2CoefficientDenominator);
 
             Video video = item.getVideo();
             video.setScore(score);
@@ -170,16 +165,16 @@ public class RankStrategy4RegionMergeModelV566 extends RankStrategy4RegionMergeM
             video.setScoresMap(item.getScoresMap());
             // video.setAllFeatureMap(item.getAllFeatureMap());
 
-            String mergeCate2 = ExtractVideoMergeCate.parseMergeCate2(vid, videoBaseInfoMap);
+            String mergeCate2 = ExtractVideoMergeCate.parseMergeCate2(String.valueOf(item.getVideoId()), videoBaseInfoMap);
             if (StringUtils.isNotBlank(mergeCate2)) {
                 video.getMergeCateList().add(mergeCate2);
             }
 
-            if (MapUtils.isNotEmpty(feature.getVideoFeature()) && MapUtils.isNotEmpty(feature.getVideoFeature().get(vid))) {
-                video.getMetaFeatureMap().putAll(feature.getVideoFeature().get(vid));
+            if (MapUtils.isNotEmpty(feature.getVideoFeature()) && MapUtils.isNotEmpty(feature.getVideoFeature().get(item.getVideoId() + ""))) {
+                video.getMetaFeatureMap().putAll(feature.getVideoFeature().get(item.getVideoId() + ""));
             }
-            if (MapUtils.isNotEmpty(videoBaseInfoMap) && MapUtils.isNotEmpty(videoBaseInfoMap.get(vid))) {
-                video.getMetaFeatureMap().putAll(videoBaseInfoMap.get(vid));
+            if (MapUtils.isNotEmpty(videoBaseInfoMap) && MapUtils.isNotEmpty(videoBaseInfoMap.get(item.getVideoId() + ""))) {
+                video.getMetaFeatureMap().putAll(videoBaseInfoMap.get(item.getVideoId() + ""));
             }
             if (MapUtils.isNotEmpty(headVideoInfo)) {
                 video.getMetaFeatureMap().put("head_video", headVideoInfo);

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

@@ -49,4 +49,6 @@ public class RecallParam {
     private Map<String, String> creativeInfoFeature;
     private Map<String, Map<String, String>> behaviorVideos;
     private String openGId;
+
+    private Map<String, String> userSocialRecallInfo;
 }

+ 6 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java

@@ -125,9 +125,14 @@ public class RecallService implements ApplicationContextAware {
         strategies.add(strategyMap.get(Return1Cate2StrRecallStrategy.class.getSimpleName()));
         Set<String> abExpCodes = param.getAbExpCodes();
         if (CollectionUtils.isNotEmpty(abExpCodes)) {
-            if (abExpCodes.contains("566") || abExpCodes.contains("568")) {
+            if (abExpCodes.contains("568")) {
                 strategies.add(strategyMap.get(PrioriPremiumRovnRecallStrategy.class.getSimpleName()));
             }
+            if (abExpCodes.contains("566")){
+                strategies.add(strategyMap.get(SocialI2IDirectRecallStrategy.class.getSimpleName()));
+                strategies.add(strategyMap.get(SocialI2IHistoryShareRecallStrategy.class.getSimpleName()));
+                strategies.add(strategyMap.get(SocialI2IHistoryClickRecallStrategy.class.getSimpleName()));
+            }
         }
 
         // 命中用户黑名单不走流量池

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

@@ -0,0 +1,155 @@
+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.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 SocialI2IBasicRecallStrategy implements RecallStrategy {
+
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+
+    private static final String REDIS_KEY_FORMAT = "user_social_i2i_recall:";
+
+    @Autowired
+    private FilterService filterService;
+
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    protected abstract List<Long> genLeftItemList(RecallParam param);
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> videos = new ArrayList<>();
+
+        try {
+
+            List<Long> leftItems = this.genLeftItemList(param);
+            if (CollectionUtils.isEmpty(leftItems)) {
+                return videos;
+            }
+
+            Map<Long, List<Pair<Long, Double>>> recallResult = this.multiGetRecallResult(REDIS_KEY_FORMAT, leftItems);
+
+
+            // 打平多个视频的召回,并按照分数从大到小排序
+            List<Pair<Long, Double>> recallPair = this.flatAndSortRecallResult(recallResult);
+            recallPair.sort(Comparator.comparingDouble(p -> -p.getValue()));
+
+            List<Long> videoIds = recallPair.stream().map(Pair::getKey).collect(Collectors.toList());
+
+
+            // 视频过滤
+            FilterParam filterParam = FilterParamFactory.create(param, videoIds);
+            FilterResult filterResult = filterService.filter(filterParam);
+            if (Objects.isNull(filterResult) || CollectionUtils.isEmpty(filterResult.getVideoIds())) {
+                return videos;
+            }
+
+            // 返回结果
+            Map<Long, Double> videoScoreMap = recallPair.stream()
+                    .collect(Collectors.toMap(Pair::getKey, Pair::getValue, (o1, o2) -> o1));
+            for (Long videoId : filterResult.getVideoIds()) {
+                Video video = new Video();
+                video.setVideoId(videoId);
+                video.setRovScore(videoScoreMap.getOrDefault(videoId, 0D));
+                video.setPushFrom(pushFrom());
+                videos.add(video);
+            }
+        } catch (Exception e) {
+            log.error("recall error strategy is {}, pushFrom is {} \n", CLASS_NAME, pushFrom(), e);
+        }
+        return videos;
+
+    }
+
+    /**
+     * 获取多个视频的I2I召回结果
+     */
+    private Map<Long, List<Pair<Long, Double>>> multiGetRecallResult(String keyPrefix, List<Long> keySuffix) {
+        if (StringUtils.isBlank(keyPrefix) || CollectionUtils.isEmpty(keySuffix)) {
+            return new HashMap<>();
+        }
+        List<String> keys = keySuffix.stream()
+                .map(i -> keyPrefix + i)
+                .collect(Collectors.toList());
+
+        List<String> values = redisTemplate.opsForValue().multiGet(keys);
+        if (CollectionUtils.isEmpty(values)) {
+            return new HashMap<>();
+        }
+
+        Map<Long, List<Pair<Long, Double>>> resultMap = new HashMap<>();
+        for (int i = 0; i < keySuffix.size(); i++) {
+            String value = values.get(i);
+            List<Pair<Long, Double>> recallVideos = this.parseRedisValue(value);
+            if (CollectionUtils.isEmpty(recallVideos)) {
+                continue;
+            }
+            resultMap.put(keySuffix.get(i), recallVideos);
+        }
+        return resultMap;
+    }
+
+
+    private List<Pair<Long, Double>> parseRedisValue(String value) {
+        if (StringUtils.isBlank(value)) {
+            return new ArrayList<>();
+        }
+        String[] split = value.split("\t");
+        if (split.length != 2) {
+            return new ArrayList<>();
+        }
+
+        List<Long> videoIds = Arrays.stream(split[0].split(","))
+                .filter(StringUtils::isNotBlank)
+                .map(String::trim)
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+
+        List<Double> scores = Arrays.stream(split[1].split(","))
+                .filter(StringUtils::isNotBlank)
+                .map(String::trim)
+                .map(Double::parseDouble)
+                .collect(Collectors.toList());
+
+        if (videoIds.size() != scores.size()) {
+            return new ArrayList<>();
+        }
+
+        List<Pair<Long, Double>> recallVideos = new ArrayList<>();
+        for (int i = 0; i < videoIds.size(); i++) {
+            recallVideos.add(Pair.of(videoIds.get(i), scores.get(i)));
+        }
+        return recallVideos;
+    }
+
+    /**
+     * 打平多个视频的召回结果,同一个被召回的视频对其分数求和
+     */
+    private List<Pair<Long, Double>> flatAndSortRecallResult(Map<Long, List<Pair<Long, Double>>> resultMap) {
+        return resultMap.values().stream()
+                .flatMap(Collection::stream)
+                .collect(Collectors.groupingBy(Pair::getKey, Collectors.summingDouble(Pair::getValue)))
+                .entrySet()
+                .stream()
+                .map(i -> Pair.of(i.getKey(), i.getValue()))
+                .collect(Collectors.toList());
+    }
+}

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

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 用户本次访问视频的社交I2I召回
+ */
+@Slf4j
+@Component
+public class SocialI2IDirectRecallStrategy extends SocialI2IBasicRecallStrategy {
+
+    public static final String PUSH_FROM = "social_i2i_direct_recall";
+
+    @Override
+    protected List<Long> genLeftItemList(RecallParam param) {
+        return new ArrayList<>(Collections.singletonList(param.getVideoId()));
+    }
+
+
+    @Override
+    public String pushFrom() {
+        return SocialI2IDirectRecallStrategy.PUSH_FROM;
+    }
+}

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

@@ -0,0 +1,40 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户历史分享视频的社交I2I召回
+ */
+@Slf4j
+@Component
+public class SocialI2IHistoryClickRecallStrategy extends SocialI2IBasicRecallStrategy {
+
+    public static final String PUSH_FROM = "social_i2i_history_click_recall";
+
+    @Override
+    protected List<Long> genLeftItemList(RecallParam param) {
+        if (MapUtils.isEmpty(param.getUserSocialRecallInfo())) {
+            return new ArrayList<>();
+        }
+        String clickVidList = param.getUserSocialRecallInfo().getOrDefault("click_vids", "");
+        return Arrays.stream(clickVidList.split(","))
+                .map(String::trim)
+                .filter(StringUtils::isNotBlank)
+                .map(Long::valueOf)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+}

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

@@ -0,0 +1,40 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户历史分享视频的社交I2I召回
+ */
+@Slf4j
+@Component
+public class SocialI2IHistoryShareRecallStrategy extends SocialI2IBasicRecallStrategy {
+
+    public static final String PUSH_FROM = "social_i2i_history_share_recall";
+
+    @Override
+    protected List<Long> genLeftItemList(RecallParam param) {
+        if (MapUtils.isEmpty(param.getUserSocialRecallInfo())) {
+            return new ArrayList<>();
+        }
+        String shareVidList = param.getUserSocialRecallInfo().getOrDefault("share_vids", "");
+        return Arrays.stream(shareVidList.split(","))
+                .map(String::trim)
+                .filter(StringUtils::isNotBlank)
+                .map(Long::valueOf)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+}