|  | @@ -2,6 +2,7 @@ package com.tzld.piaoquan.recommend.server.implement;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  | +import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 | 
	
		
			
				|  |  |  import com.google.common.base.Stopwatch;
 | 
	
		
			
				|  |  |  import com.google.common.reflect.TypeToken;
 | 
	
		
			
				|  |  |  import com.tzld.piaoquan.recommend.server.common.base.RankItem;
 | 
	
	
		
			
				|  | @@ -46,6 +47,8 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Value("${recommend.recall.num:500}")
 | 
	
		
			
				|  |  |      private int recallNum;
 | 
	
		
			
				|  |  | +    @ApolloJsonValue("${rank.score.merge.weightv547:}")
 | 
	
		
			
				|  |  | +    private Map<String, Double> mergeWeight;
 | 
	
		
			
				|  |  |      @Resource
 | 
	
		
			
				|  |  |      private RedisSmartClient client;
 | 
	
		
			
				|  |  |      @Resource
 | 
	
	
		
			
				|  | @@ -55,6 +58,7 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |      @PostConstruct
 | 
	
		
			
				|  |  |      public void init() {
 | 
	
		
			
				|  |  |          queueProvider = new RedisBackedQueue(client, 15 * 60 * 1000L);
 | 
	
		
			
				|  |  | +        mergeWeight = mergeWeight == null ? new HashMap<>() : mergeWeight;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public List<Video> feeds(final RecommendRequest requestData,
 | 
	
	
		
			
				|  | @@ -183,21 +187,23 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private List<Video> rankItem2Video(List<RankItem> items) {
 | 
	
		
			
				|  |  | +        // 1 模型分
 | 
	
		
			
				|  |  | +        List<String> rtFeaPart = new ArrayList<>();
 | 
	
		
			
				|  |  |          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);
 | 
	
		
			
				|  |  |          Calendar calendar = Calendar.getInstance();
 | 
	
		
			
				|  |  |          String date = new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
 | 
	
		
			
				|  |  |          String hour = new SimpleDateFormat("HH").format(calendar.getTime());
 | 
	
		
			
				|  |  |          String rtFeaPart1h = date + hour;
 | 
	
		
			
				|  |  | -        if (rtFeaPartKeyResult != null){
 | 
	
		
			
				|  |  | -            if (rtFeaPartKeyResult.get(1) != null){
 | 
	
		
			
				|  |  | +        if (rtFeaPartKeyResult != null) {
 | 
	
		
			
				|  |  | +            if (rtFeaPartKeyResult.get(1) != null) {
 | 
	
		
			
				|  |  |                  rtFeaPart1h = rtFeaPartKeyResult.get(1);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          // 2 统计分
 | 
	
		
			
				|  |  |          String cur = rtFeaPart1h;
 | 
	
		
			
				|  |  | -        List<String> datehours = new LinkedList<>();
 | 
	
		
			
				|  |  | -        for (int i=0; i<24; ++i){
 | 
	
		
			
				|  |  | +        List<String> datehours = new LinkedList<>(); // 时间是倒叙的
 | 
	
		
			
				|  |  | +        for (int i = 0; i < 24; ++i) {
 | 
	
		
			
				|  |  |              datehours.add(cur);
 | 
	
		
			
				|  |  |              cur = ExtractorUtils.subtractHours(cur, 1);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -207,12 +213,12 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |              List<Double> views = getStaticData(itemRealMap, datehours, "view_pv_list_1h");
 | 
	
		
			
				|  |  |              List<Double> plays = getStaticData(itemRealMap, datehours, "play_pv_list_1h");
 | 
	
		
			
				|  |  |              List<Double> shares = getStaticData(itemRealMap, datehours, "share_pv_list_1h");
 | 
	
		
			
				|  |  | -            List<Double> returns = getStaticData(itemRealMap, datehours, "p_return_uv_list_1h");
 | 
	
		
			
				|  |  | +            List<Double> preturns = getStaticData(itemRealMap, datehours, "p_return_uv_list_1h");
 | 
	
		
			
				|  |  |              List<Double> allreturns = getStaticData(itemRealMap, datehours, "return_uv_list_1h");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            List<Double> share2return = getRateData(returns, shares, 1.0, 1000.0);
 | 
	
		
			
				|  |  | +            List<Double> share2return = getRateData(preturns, shares, 1.0, 1000.0);
 | 
	
		
			
				|  |  |              Double share2returnScore = calScoreWeight(share2return);
 | 
	
		
			
				|  |  | -            List<Double> view2return = getRateData(returns, views, 1.0, 1000.0);
 | 
	
		
			
				|  |  | +            List<Double> view2return = getRateData(preturns, views, 1.0, 1000.0);
 | 
	
		
			
				|  |  |              Double view2returnScore = calScoreWeight(view2return);
 | 
	
		
			
				|  |  |              List<Double> view2play = getRateData(plays, views, 1.0, 1000.0);
 | 
	
		
			
				|  |  |              Double view2playScore = calScoreWeight(view2play);
 | 
	
	
		
			
				|  | @@ -223,15 +229,65 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |              item.scoresMap.put("view2playScore", view2playScore);
 | 
	
		
			
				|  |  |              item.scoresMap.put("play2shareScore", play2shareScore);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            // 全部回流的rov和ros
 | 
	
		
			
				|  |  | +            List<Double> share2allreturn = getRateData(allreturns, shares, 1.0, 10.0);
 | 
	
		
			
				|  |  | +            Double share2allreturnScore = calScoreWeight(share2allreturn);
 | 
	
		
			
				|  |  | +            List<Double> view2allreturn = getRateData(allreturns, views, 0.0, 0.0);
 | 
	
		
			
				|  |  | +            Double view2allreturnScore = calScoreWeight(view2allreturn);
 | 
	
		
			
				|  |  | +            item.scoresMap.put("share2allreturnScore", share2allreturnScore);
 | 
	
		
			
				|  |  | +            item.scoresMap.put("view2allreturnScore", view2allreturnScore);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 全部回流
 | 
	
		
			
				|  |  |              Double allreturnsScore = calScoreWeight(allreturns);
 | 
	
		
			
				|  |  |              item.scoresMap.put("allreturnsScore", allreturnsScore);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 平台回流
 | 
	
		
			
				|  |  | +            Double preturnsScore = calScoreWeight(preturns);
 | 
	
		
			
				|  |  | +            item.scoresMap.put("preturnsScore", preturnsScore);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // rov的趋势
 | 
	
		
			
				|  |  | +            double trendScore = calTrendScore(view2return);
 | 
	
		
			
				|  |  | +            item.scoresMap.put("trendScore", trendScore);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 新视频提取
 | 
	
		
			
				|  |  | +            double newVideoScore = calNewVideoScore(itemBasicMap);
 | 
	
		
			
				|  |  | +            item.scoresMap.put("newVideoScore", newVideoScore);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          // 3 融合公式
 | 
	
		
			
				|  |  |          List<Video> result = new ArrayList<>();
 | 
	
		
			
				|  |  | -        for (RankItem item : items){
 | 
	
		
			
				|  |  | -            double score = item.getScoreStr() *
 | 
	
		
			
				|  |  | -                    item.scoresMap.getOrDefault("share2returnScore", 0.0) *
 | 
	
		
			
				|  |  | -                    Math.log(1 + item.scoresMap.getOrDefault("allreturnsScore", 0.0));
 | 
	
		
			
				|  |  | +        double a = mergeWeight.getOrDefault("a", 0.1);
 | 
	
		
			
				|  |  | +        double b = mergeWeight.getOrDefault("b", 0.0);
 | 
	
		
			
				|  |  | +        double c = mergeWeight.getOrDefault("c", 0.000001);
 | 
	
		
			
				|  |  | +        double d = mergeWeight.getOrDefault("d", 1.0);
 | 
	
		
			
				|  |  | +        double e = mergeWeight.getOrDefault("e", 1.0);
 | 
	
		
			
				|  |  | +        double f = mergeWeight.getOrDefault("f", 0.8);
 | 
	
		
			
				|  |  | +        double g = mergeWeight.getOrDefault("g", 2.0);
 | 
	
		
			
				|  |  | +        double h = mergeWeight.getOrDefault("h", 240.0);
 | 
	
		
			
				|  |  | +        double ifAdd = mergeWeight.getOrDefault("ifAdd", 1.0);
 | 
	
		
			
				|  |  | +        for (RankItem item : items) {
 | 
	
		
			
				|  |  | +            double trendScore = item.scoresMap.getOrDefault("trendScore", 0.0) > 1E-8 ?
 | 
	
		
			
				|  |  | +                    item.scoresMap.getOrDefault("trendScore", 0.0) : 0.0;
 | 
	
		
			
				|  |  | +            double newVideoScore = item.scoresMap.getOrDefault("newVideoScore", 0.0) > 1E-8 ?
 | 
	
		
			
				|  |  | +                    item.scoresMap.getOrDefault("newVideoScore", 0.0) : 0.0;
 | 
	
		
			
				|  |  | +            double strScore = item.getScoreStr();
 | 
	
		
			
				|  |  | +            double rosScore = item.scoresMap.getOrDefault("share2returnScore", 0.0);
 | 
	
		
			
				|  |  | +            double share2allreturnScore = item.scoresMap.getOrDefault("share2allreturnScore", 0.0);
 | 
	
		
			
				|  |  | +            double view2allreturnScore = item.scoresMap.getOrDefault("view2allreturnScore", 0.0);
 | 
	
		
			
				|  |  | +            double preturnsScore = Math.log(1 + item.scoresMap.getOrDefault("preturnsScore", 0.0));
 | 
	
		
			
				|  |  | +            double score = 0.0;
 | 
	
		
			
				|  |  | +            if (ifAdd < 0.5) {
 | 
	
		
			
				|  |  | +                score = Math.pow(strScore, a) * Math.pow(rosScore, b) + c * preturnsScore +
 | 
	
		
			
				|  |  | +                        (newVideoScore > 1E-8 ? d * trendScore * (e + newVideoScore) : 0.0);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                score = a * strScore + b * rosScore + c * preturnsScore +
 | 
	
		
			
				|  |  | +                        (newVideoScore > 1E-8 ? d * trendScore * (e + newVideoScore) : 0.0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            double allreturnsScore = item.scoresMap.getOrDefault("allreturnsScore", 0.0);
 | 
	
		
			
				|  |  | +            if (allreturnsScore > h) {
 | 
	
		
			
				|  |  | +                score += (f * share2allreturnScore + g * view2allreturnScore);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              Video video = new Video();
 | 
	
		
			
				|  |  |              video.setVideoId(Long.parseLong(item.getId()));
 | 
	
		
			
				|  |  |              video.setPushFrom(item.getQueue());
 | 
	
	
		
			
				|  | @@ -245,6 +301,33 @@ public class TopRecommendPipeline {
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    public double calNewVideoScore(Map<String, String> itemBasicMap) {
 | 
	
		
			
				|  |  | +        double existenceDays = Double.valueOf(itemBasicMap.getOrDefault("existence_days", "30"));
 | 
	
		
			
				|  |  | +        if (existenceDays > 5) {
 | 
	
		
			
				|  |  | +            return 0.0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        double score = 1.0 / (existenceDays + 10.0);
 | 
	
		
			
				|  |  | +        return score;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public double calTrendScore(List<Double> data) {
 | 
	
		
			
				|  |  | +        double sum = 0.0;
 | 
	
		
			
				|  |  | +        int size = data.size();
 | 
	
		
			
				|  |  | +        for (int i = 0; i < size - 4; ++i) {
 | 
	
		
			
				|  |  | +            sum += data.get(i) - data.get(i + 4);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (sum * 10 > 0.6) {
 | 
	
		
			
				|  |  | +            sum = 0.6;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            sum = sum * 10;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (sum > 0) {
 | 
	
		
			
				|  |  | +            // 为了打断点
 | 
	
		
			
				|  |  | +            sum = sum;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return sum;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private void duplicate(List<RankItem> items) {
 | 
	
		
			
				|  |  |          Set<String> ids = new HashSet<>();
 | 
	
		
			
				|  |  |          List<RankItem> result = new ArrayList<>();
 |