|
@@ -20,6 +20,7 @@ import com.tzld.piaoquan.recommend.server.service.rank.extractor.RankExtractorIt
|
|
import com.tzld.piaoquan.recommend.server.service.rank.extractor.RankExtractorUserFeature;
|
|
import com.tzld.piaoquan.recommend.server.service.rank.extractor.RankExtractorUserFeature;
|
|
import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
|
|
import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
|
|
import com.tzld.piaoquan.recommend.server.util.JSONUtils;
|
|
import com.tzld.piaoquan.recommend.server.util.JSONUtils;
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -52,12 +53,23 @@ public class TopRecommendPipeline {
|
|
|
|
|
|
public List<Video> feeds(final RecommendRequest requestData,
|
|
public List<Video> feeds(final RecommendRequest requestData,
|
|
final int requestIndex,
|
|
final int requestIndex,
|
|
- final User userInfo) {
|
|
|
|
|
|
+ final User userInfo, Boolean logPrint) {
|
|
// Step 1: Attention extraction
|
|
// Step 1: Attention extraction
|
|
- List<RankItem> rankItems = feedByRec(requestData, requestIndex, userInfo);
|
|
|
|
|
|
+ List<RankItem> rankItems = feedByRec(requestData, requestIndex, userInfo, logPrint);
|
|
if (rankItems == null || rankItems.isEmpty()) {
|
|
if (rankItems == null || rankItems.isEmpty()) {
|
|
return new ArrayList<>();
|
|
return new ArrayList<>();
|
|
}
|
|
}
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, rankItems = {}", requestData.getRequestId(), JSONUtils.toJson(rankItems));
|
|
|
|
+ }
|
|
|
|
+ List<Video> videos = rankVideos(rankItems, requestData.getRequestId());
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, videos = {}", requestData.getRequestId(), JSONUtils.toJson(videos));
|
|
|
|
+ }
|
|
|
|
+ return videos;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<Video> rankVideos(List<RankItem> rankItems, String requestId) {
|
|
List<String> rtFeaPartKey = new ArrayList<>(Arrays.asList("item_rt_fea_1day_partition", "item_rt_fea_1h_partition"));
|
|
List<String> rtFeaPartKey = new ArrayList<>(Arrays.asList("item_rt_fea_1day_partition", "item_rt_fea_1h_partition"));
|
|
List<String> rtFeaPartKeyResult = this.redisTemplate.opsForValue().multiGet(rtFeaPartKey);
|
|
List<String> rtFeaPartKeyResult = this.redisTemplate.opsForValue().multiGet(rtFeaPartKey);
|
|
Calendar calendar = Calendar.getInstance();
|
|
Calendar calendar = Calendar.getInstance();
|
|
@@ -123,8 +135,11 @@ public class TopRecommendPipeline {
|
|
item.scoresMap.getOrDefault("share2returnScore", 0.0)
|
|
item.scoresMap.getOrDefault("share2returnScore", 0.0)
|
|
+ alpha * trendScore
|
|
+ alpha * trendScore
|
|
+ beta * newVideoScore;
|
|
+ beta * newVideoScore;
|
|
- Video video = new Video();
|
|
|
|
- video.setVideoId(Long.parseLong(item.getId()));
|
|
|
|
|
|
+ Video video = item.getVideo();
|
|
|
|
+ if (video == null) {
|
|
|
|
+ log.error("video is null in rankVideos, traceId = {}, videoId = {}", requestId, item.getId());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
video.setScore(score);
|
|
video.setScore(score);
|
|
video.setSortScore(score);
|
|
video.setSortScore(score);
|
|
video.setScoreStr(item.getScoreStr());
|
|
video.setScoreStr(item.getScoreStr());
|
|
@@ -194,7 +209,7 @@ public class TopRecommendPipeline {
|
|
|
|
|
|
public List<RankItem> feedByRec(final RecommendRequest requestData,
|
|
public List<RankItem> feedByRec(final RecommendRequest requestData,
|
|
final int requestIndex,
|
|
final int requestIndex,
|
|
- final User userInfo) {
|
|
|
|
|
|
+ final User userInfo, Boolean logPrint) {
|
|
int recallNum = 200;
|
|
int recallNum = 200;
|
|
|
|
|
|
// Step 1: Attention extraction
|
|
// Step 1: Attention extraction
|
|
@@ -204,11 +219,16 @@ public class TopRecommendPipeline {
|
|
|
|
|
|
// Step 2: create top queue
|
|
// Step 2: create top queue
|
|
StrategyQueue topQueue = MergeUtils.createTopQueue(MERGE_CONF, "top-queue");
|
|
StrategyQueue topQueue = MergeUtils.createTopQueue(MERGE_CONF, "top-queue");
|
|
-
|
|
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, topQueue = {}", requestData.getRequestId(), JSONUtils.toJson(topQueue));
|
|
|
|
+ }
|
|
|
|
|
|
// Step 3: Candidate
|
|
// Step 3: Candidate
|
|
Map<String, Candidate> candidates = new HashMap<String, Candidate>();
|
|
Map<String, Candidate> candidates = new HashMap<String, Candidate>();
|
|
topQueue.candidate(candidates, recallNum, userInfo, requestData, 0, 0);
|
|
topQueue.candidate(candidates, recallNum, userInfo, requestData, 0, 0);
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, candidates = {}", requestData.getRequestId(), JSONUtils.toJson(candidates));
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
// Step 4: Recalling & Basic Scoring
|
|
// Step 4: Recalling & Basic Scoring
|
|
@@ -216,28 +236,39 @@ public class TopRecommendPipeline {
|
|
|
|
|
|
BaseRecaller recaller = new BaseRecaller(queueProvider);
|
|
BaseRecaller recaller = new BaseRecaller(queueProvider);
|
|
List<RankItem> items = recaller.recalling(requestData, userInfo, requestIndex, new ArrayList<>(candidates.values()));
|
|
List<RankItem> items = recaller.recalling(requestData, userInfo, requestIndex, new ArrayList<>(candidates.values()));
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, items = {}", requestData.getRequestId(), JSONUtils.toJson(items));
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
// Step 4: Advance Scoring
|
|
// Step 4: Advance Scoring
|
|
// timestamp = System.currentTimeMillis();
|
|
// timestamp = System.currentTimeMillis();
|
|
// ScorerPipeline scorerPipeline = getScorerPipeline(requestData);
|
|
// ScorerPipeline scorerPipeline = getScorerPipeline(requestData);
|
|
// items = scorerPipeline.scoring(requestData, userInfo, requestIndex, items);
|
|
// items = scorerPipeline.scoring(requestData, userInfo, requestIndex, items);
|
|
-
|
|
|
|
|
|
+ if (CollectionUtils.isEmpty(items)) {
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
|
|
// Step 5: Merger
|
|
// Step 5: Merger
|
|
MergeUtils.distributeItemsToMultiQueues(topQueue, items);
|
|
MergeUtils.distributeItemsToMultiQueues(topQueue, items);
|
|
topQueue.merge(recallNum * 3, userInfo, requestData, requestIndex, 0);
|
|
topQueue.merge(recallNum * 3, userInfo, requestData, requestIndex, 0);
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, topQueue after merge = {}", requestData.getRequestId(), JSONUtils.toJson(topQueue));
|
|
|
|
+ }
|
|
|
|
|
|
// 多样性融合
|
|
// 多样性融合
|
|
-// List<RankItem> mergeItems = topQueue.getItems();
|
|
|
|
|
|
+ List<RankItem> mergeItems = topQueue.getItems();
|
|
// MergeUtils.diversityRerank(mergeItems, SimilarityUtils.getIsSameUserTagOrCategoryFunc(), recallNum, 6, 2);
|
|
// MergeUtils.diversityRerank(mergeItems, SimilarityUtils.getIsSameUserTagOrCategoryFunc(), recallNum, 6, 2);
|
|
|
|
|
|
// Step 6: Global Rank & subList
|
|
// Step 6: Global Rank & subList
|
|
// TODO 前置和后置处理逻辑 hardcode,后续优化
|
|
// TODO 前置和后置处理逻辑 hardcode,后续优化
|
|
Map<String, String> sceneFeatureMap = getSceneFeature(requestData);
|
|
Map<String, String> sceneFeatureMap = getSceneFeature(requestData);
|
|
- Map<String, String> userFeatureMap = getUserFeatureMap(requestData, items);
|
|
|
|
|
|
+ Map<String, String> userFeatureMap = getUserFeatureMap(requestData, mergeItems);
|
|
List<RankItem> rovRecallRankNewallScore = ScorerUtils.getScorerPipeline(ScorerUtils.BASE_CONF_NEW_FEED)
|
|
List<RankItem> rovRecallRankNewallScore = ScorerUtils.getScorerPipeline(ScorerUtils.BASE_CONF_NEW_FEED)
|
|
- .scoring(sceneFeatureMap, userFeatureMap, items);
|
|
|
|
|
|
+ .scoring(sceneFeatureMap, userFeatureMap, mergeItems);
|
|
|
|
+ if (logPrint) {
|
|
|
|
+ log.info("traceId = {}, rovRecallRankNewallScore = {}", requestData.getRequestId(), JSONUtils.toJson(rovRecallRankNewallScore));
|
|
|
|
+ }
|
|
|
|
|
|
return rovRecallRankNewallScore;
|
|
return rovRecallRankNewallScore;
|
|
}
|
|
}
|
|
@@ -455,7 +486,6 @@ public class TopRecommendPipeline {
|
|
"新竹市".equals(city) |
|
|
"新竹市".equals(city) |
|
|
"嘉义市".equals(city)
|
|
"嘉义市".equals(city)
|
|
){
|
|
){
|
|
- ;
|
|
|
|
}else{
|
|
}else{
|
|
city = city.replaceAll("市$", "");
|
|
city = city.replaceAll("市$", "");
|
|
}
|
|
}
|