|  | @@ -1,15 +1,15 @@
 | 
											
												
													
														|  |  package com.tzld.piaoquan.recommend.server.service.score;
 |  |  package com.tzld.piaoquan.recommend.server.service.score;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.tzld.piaoquan.recommend.server.common.base.RankItem;
 | 
											
												
													
														|  | 
 |  | +import com.tzld.piaoquan.recommend.server.common.base.RequestContext;
 | 
											
												
													
														|  |  import com.tzld.piaoquan.recommend.server.common.base.UserFeature;
 |  |  import com.tzld.piaoquan.recommend.server.common.base.UserFeature;
 | 
											
												
													
														|  | -import com.tzld.piaoquan.recommend.server.common.base.VideoRankFeature;
 |  | 
 | 
											
												
													
														|  |  import com.tzld.piaoquan.recommend.server.gen.recommend.RecommendRequest;
 |  |  import com.tzld.piaoquan.recommend.server.gen.recommend.RecommendRequest;
 | 
											
												
													
														|  | -import com.tzld.piaoquan.recommend.server.model.Video;
 |  | 
 | 
											
												
													
														|  |  import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
 |  |  import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
 | 
											
												
													
														|  |  import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 |  |  import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 | 
											
												
													
														|  | -import com.tzld.piaoquan.recommend.server.service.score.feature.VlogShareFeatureExtractor;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.tzld.piaoquan.recommend.server.service.score.feature.GBDTFeatureExtractorBase;
 | 
											
												
													
														|  |  import com.tzld.piaoquan.recommend.server.service.score.model.GBDTModel;
 |  |  import com.tzld.piaoquan.recommend.server.service.score.model.GBDTModel;
 | 
											
												
													
														|  | 
 |  | +import com.tzld.piaoquan.recommend.server.model.Video;
 | 
											
												
													
														|  |  import org.apache.commons.lang.exception.ExceptionUtils;
 |  |  import org.apache.commons.lang.exception.ExceptionUtils;
 | 
											
												
													
														|  |  import org.slf4j.Logger;
 |  |  import org.slf4j.Logger;
 | 
											
												
													
														|  |  import org.slf4j.LoggerFactory;
 |  |  import org.slf4j.LoggerFactory;
 | 
											
										
											
												
													
														|  | @@ -25,52 +25,127 @@ import java.util.concurrent.Executors;
 | 
											
												
													
														|  |  import java.util.concurrent.Future;
 |  |  import java.util.concurrent.Future;
 | 
											
												
													
														|  |  import java.util.concurrent.TimeUnit;
 |  |  import java.util.concurrent.TimeUnit;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -public class FeedsShareLTRScorer extends BaseGBDTModelScorer{
 |  | 
 | 
											
												
													
														|  | 
 |  | +public class VlogShareGBDTScorer extends BaseGBDTModelScorer {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      private final static int CORE_POOL_SIZE = 64;
 |  |      private final static int CORE_POOL_SIZE = 64;
 | 
											
												
													
														|  |      private final static int TIME_OUT = 150;
 |  |      private final static int TIME_OUT = 150;
 | 
											
												
													
														|  | -    private final static Logger LOGGER = LoggerFactory.getLogger(FeedsShareLTRScorer.class);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    private final static Logger LOGGER = LoggerFactory.getLogger(VlogShareGBDTScorer.class);
 | 
											
												
													
														|  |      private final static ExecutorService executorService = Executors.newFixedThreadPool(CORE_POOL_SIZE);
 |  |      private final static ExecutorService executorService = Executors.newFixedThreadPool(CORE_POOL_SIZE);
 | 
											
												
													
														|  | 
 |  | +    private static final String VIMAGE_VIDEO_REC_TAG = "小视频";
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    public FeedsShareLTRScorer(ScorerConfigInfo configInfo) {
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public VlogShareGBDTScorer(ScorerConfigInfo configInfo) {
 | 
											
												
													
														|  | 
 |  | +        super(configInfo);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      private RequestContext getRequestContext(RecommendRequest request) {
 |  |      private RequestContext getRequestContext(RecommendRequest request) {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +        RequestContext requestContext = new RequestContext();
 | 
											
												
													
														|  | 
 |  | +        return requestContext;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  | -    public List<Video> scoring(final RecommendRequest recommendRequest,
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public List<RankItem> scoring(final RecommendRequest request,
 | 
											
												
													
														|  |                                 final RankParam param,
 |  |                                 final RankParam param,
 | 
											
												
													
														|  | -                               final RecallResult recallResult,
 |  | 
 | 
											
												
													
														|  |                                 final UserFeature userFeature,
 |  |                                 final UserFeature userFeature,
 | 
											
												
													
														|  | -                               final VideoRankFeature videoFeature) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +                               final List<RankItem> rankItems) {
 | 
											
												
													
														|  | 
 |  | +        RecallResult recallResult = param.getRecallResult();
 | 
											
												
													
														|  | 
 |  | +        if (recallResult.getData().size() == 0) {
 | 
											
												
													
														|  | 
 |  | +            return rankItems;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        long startTime = System.currentTimeMillis();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        GBDTModel model = (GBDTModel) this.getModel();
 | 
											
												
													
														|  | 
 |  | +        if (model == null) {
 | 
											
												
													
														|  | 
 |  | +            LOGGER.error("not found model");
 | 
											
												
													
														|  | 
 |  | +            return rankItems;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        RequestContext requestContext = getRequestContext(request);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        feedsShareScore();
 |  | 
 | 
											
												
													
														|  | -        Collections.sort();
 |  | 
 | 
											
												
													
														|  | -        return items;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        // 多Rank的rank打分
 | 
											
												
													
														|  | 
 |  | +        multipleGBDTScore(rankItems, model, userFeature, request, requestContext);
 | 
											
												
													
														|  | 
 |  | +        Collections.sort(rankItems);
 | 
											
												
													
														|  | 
 |  | +        LOGGER.debug("dwelltime ranker excute time: [{}]", System.currentTimeMillis() - startTime);
 | 
											
												
													
														|  | 
 |  | +        return rankItems;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 分数转换
 | 
											
												
													
														|  | 
 |  | +     *
 | 
											
												
													
														|  | 
 |  | +     * @param oldScore
 | 
											
												
													
														|  | 
 |  | +     * @param dwelltimeOrCompletion
 | 
											
												
													
														|  | 
 |  | +     * @param duration
 | 
											
												
													
														|  | 
 |  | +     * @param itemId
 | 
											
												
													
														|  | 
 |  | +     * @return
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private double predictMultipleGBDTScore(final double oldScore, final double dwelltimeOrCompletion,
 | 
											
												
													
														|  | 
 |  | +                                         final double duration, final String itemId,
 | 
											
												
													
														|  | 
 |  | +                                         final RecommendRequest requestData, final UserFeature user) {
 | 
											
												
													
														|  | 
 |  | +        double ctrScalePower = 0;
 | 
											
												
													
														|  | 
 |  | +        double dwelltimeScalePower = 0;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        double ctrScore = oldScore;
 | 
											
												
													
														|  | 
 |  | +        if (oldScore <= 0.0) {
 | 
											
												
													
														|  | 
 |  | +            ctrScore = 0.01;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        double newScore = Math.pow(ctrScore, ctrScalePower) * Math.pow(dwelltimeOrCompletion, dwelltimeScalePower);
 | 
											
												
													
														|  | 
 |  | +        //值越大压制越弱
 | 
											
												
													
														|  | 
 |  | +        double alpha =  1.0;
 | 
											
												
													
														|  | 
 |  | +        double suppressRatio = (1 + alpha) / (Math.max(duration, 300.0) / 300 + alpha);
 | 
											
												
													
														|  | 
 |  | +        newScore = newScore * suppressRatio;
 | 
											
												
													
														|  | 
 |  | +        LOGGER.debug("Expected dwell time score [{}]: {} ,{}, {}--> {}", new Object[]{itemId, oldScore, dwelltimeOrCompletion, duration, newScore});
 | 
											
												
													
														|  | 
 |  | +        return newScore;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    private void gbdtBaseScore(final Video item,
 | 
											
												
													
														|  | 
 |  | +                                final GBDTModel model,
 | 
											
												
													
														|  | 
 |  | +                                final RequestContext requestContext,
 | 
											
												
													
														|  | 
 |  | +                                final Map<String, Double> userFeatures,
 | 
											
												
													
														|  | 
 |  | +                                final Map<String, Double> contextFeatures,
 | 
											
												
													
														|  | 
 |  | +                                final RecommendRequest requestData, final UserFeature user) {
 | 
											
												
													
														|  | 
 |  | +        try {
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            Map<String, Double> articleFeatures;
 | 
											
												
													
														|  | 
 |  | +            double freshness;
 | 
											
												
													
														|  | 
 |  | +            Map<String, Double> features;
 | 
											
												
													
														|  | 
 |  | +            features = GBDTFeatureExtractorBase.extractUserFeatures(user);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +            if (model != null) {
 | 
											
												
													
														|  | 
 |  | +                Map<String, Double> featureScoreMap = new HashMap<String, Double>();
 | 
											
												
													
														|  | 
 |  | +                double pro = model.score(features, featureScoreMap);
 | 
											
												
													
														|  | 
 |  | +                featureScoreMap.put("TOTAL_SCORE", pro);
 | 
											
												
													
														|  | 
 |  | +                pro = pro > 1 ? pro : 1;
 | 
											
												
													
														|  | 
 |  | +                Double rankScore = item.getRankScore();
 | 
											
												
													
														|  | 
 |  | +                LOGGER.debug("xgb score = {}, lgb score = {}", rankScore, pro);
 | 
											
												
													
														|  | 
 |  | +                double lgbWeight = 1.0;
 | 
											
												
													
														|  | 
 |  | +                pro = (rankScore + lgbWeight * pro) / (1.0 + lgbWeight);
 | 
											
												
													
														|  | 
 |  | +                item.setRankScore(pro);
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    public void feedsShareScore(final List<Video> items,
 |  | 
 | 
											
												
													
														|  | 
 |  | +        } catch (Exception e) {
 | 
											
												
													
														|  | 
 |  | +            LOGGER.error("Exception {},{}", requestContext, ExceptionUtils.getFullStackTrace(e));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    public void multipleGBDTScore(final List<Video> items,
 | 
											
												
													
														|  |                                         final GBDTModel model,
 |  |                                         final GBDTModel model,
 | 
											
												
													
														|  |                                         final UserFeature user,
 |  |                                         final UserFeature user,
 | 
											
												
													
														|  | -                                       final RecommendRequest requestData) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +                                       final RecommendRequest requestData,
 | 
											
												
													
														|  | 
 |  | +                                       final RequestContext requestContext) {
 | 
											
												
													
														|  |          final int size = items.size();
 |  |          final int size = items.size();
 | 
											
												
													
														|  |          if (size == 0) {
 |  |          if (size == 0) {
 | 
											
												
													
														|  |              return;
 |  |              return;
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |          final Map<String, Double> userFeatures;
 |  |          final Map<String, Double> userFeatures;
 | 
											
												
													
														|  |          final Map<String, Double> contextFeatures;
 |  |          final Map<String, Double> contextFeatures;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |          // context feature
 |  |          // context feature
 | 
											
												
													
														|  | -        contextFeatures = VlogShareFeatureExtractor.extractContextFeatures(requestContext);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        contextFeatures = GBDTFeatureExtractorBase.extractRequestContextFeatures(requestContext);
 | 
											
												
													
														|  |          // user feature
 |  |          // user feature
 | 
											
												
													
														|  | -        userFeatures = VlogShareFeatureExtractor.extractUserFeatures();
 |  | 
 | 
											
												
													
														|  | 
 |  | +        userFeatures = GBDTFeatureExtractorBase.extractUserFeatures(user);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          // score item
 |  |          // score item
 | 
											
												
													
														|  |          List<Callable<Object>> callables = new ArrayList<Callable<Object>>();
 |  |          List<Callable<Object>> callables = new ArrayList<Callable<Object>>();
 | 
											
										
											
												
													
														|  | @@ -80,9 +155,9 @@ public class FeedsShareLTRScorer extends BaseGBDTModelScorer{
 | 
											
												
													
														|  |                                @Override
 |  |                                @Override
 | 
											
												
													
														|  |                                public Object call() throws Exception {
 |  |                                public Object call() throws Exception {
 | 
											
												
													
														|  |                                    try {
 |  |                                    try {
 | 
											
												
													
														|  | -                                      dwelltimeScore(items.get(fIndex), model, requestContext, userFeatures, contextFeatures, requestData, user);
 |  | 
 | 
											
												
													
														|  | 
 |  | +                                      gbdtBaseScore(items.get(fIndex), model, requestContext, userFeatures, contextFeatures, requestData, user);
 | 
											
												
													
														|  |                                    } catch (Exception e) {
 |  |                                    } catch (Exception e) {
 | 
											
												
													
														|  | -                                      LOGGER.error("dwelltime exception: [{}] [{}]", items.get(fIndex).getId(), ExceptionUtils.getFullStackTrace(e));
 |  | 
 | 
											
												
													
														|  | 
 |  | +                                      LOGGER.error("dwelltime exception: [{}] [{}]", items.get(fIndex), ExceptionUtils.getFullStackTrace(e));
 | 
											
												
													
														|  |                                    }
 |  |                                    }
 | 
											
												
													
														|  |                                    return new Object();
 |  |                                    return new Object();
 | 
											
												
													
														|  |                                }
 |  |                                }
 | 
											
										
											
												
													
														|  | @@ -103,7 +178,7 @@ public class FeedsShareLTRScorer extends BaseGBDTModelScorer{
 | 
											
												
													
														|  |                  try {
 |  |                  try {
 | 
											
												
													
														|  |                      if (future != null && future.isDone() && !future.isCancelled() && future.get() != null) {
 |  |                      if (future != null && future.isDone() && !future.isCancelled() && future.get() != null) {
 | 
											
												
													
														|  |                      } else {
 |  |                      } else {
 | 
											
												
													
														|  | -                        LOGGER.debug("Canceled Dwelltime Score {}", requestContext.getId());
 |  | 
 | 
											
												
													
														|  | 
 |  | +                        LOGGER.debug("Canceled Dwelltime Score {}", requestContext);
 | 
											
												
													
														|  |                      }
 |  |                      }
 | 
											
												
													
														|  |                  } catch (Exception e) {
 |  |                  } catch (Exception e) {
 | 
											
												
													
														|  |                      LOGGER.error("InterruptedException {},{}", ExceptionUtils.getFullStackTrace(e));
 |  |                      LOGGER.error("InterruptedException {},{}", ExceptionUtils.getFullStackTrace(e));
 | 
											
										
											
												
													
														|  | @@ -111,65 +186,5 @@ public class FeedsShareLTRScorer extends BaseGBDTModelScorer{
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    // GBDT计算score
 |  | 
 | 
											
												
													
														|  | -    private void shareScore(final RankerItem item,
 |  | 
 | 
											
												
													
														|  | -                                final GBDTModel model,
 |  | 
 | 
											
												
													
														|  | -                                final RequestContext requestContext,
 |  | 
 | 
											
												
													
														|  | -                                final Map<String, Double> userFeatures,
 |  | 
 | 
											
												
													
														|  | -                                final Map<String, Double> contextFeatures,
 |  | 
 | 
											
												
													
														|  | -                                final int debugLevel,
 |  | 
 | 
											
												
													
														|  | -                                final RecommendRequest requestData, final User user) {
 |  | 
 | 
											
												
													
														|  | -        try {
 |  | 
 | 
											
												
													
														|  | -            //judge null
 |  | 
 | 
											
												
													
														|  | -            if (item == null || item.getItemInfo() == null) {
 |  | 
 | 
											
												
													
														|  | -                return;
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -            ArticleInfo articleInfo = (ArticleInfo) item.getItemInfo();
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -            Map<String, Double> articleFeatures;
 |  | 
 | 
											
												
													
														|  | -            double freshness;
 |  | 
 | 
											
												
													
														|  | -            Map<String, Double> features;
 |  | 
 | 
											
												
													
														|  | -            articleFeatures = DurationFeatureExtractor.extractArticleFeatures(articleInfo);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -            if (model != null) {
 |  | 
 | 
											
												
													
														|  | -                Map<String, Double> featureScoreMap = new HashMap<String, Double>();
 |  | 
 | 
											
												
													
														|  | -                double pro = model.score(features, featureScoreMap, debugLevel);
 |  | 
 | 
											
												
													
														|  | -                featureScoreMap.put("TOTAL_SCORE", pro);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -                pro = pro > 1 ? pro : 1;
 |  | 
 | 
											
												
													
														|  | -                LOGGER.debug("xgb score = {}, lgb score = {}", item.getDwelltimeScore(), pro);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -                double lgbWeight = Configuration.getDouble("mivideo-recommend-service.dwelltime_ranker.lgb.weight", 1.0);
 |  | 
 | 
											
												
													
														|  | -                pro = (item.getDwelltimeScore() + lgbWeight * pro) / (1.0 + lgbWeight);
 |  | 
 | 
											
												
													
														|  | -                item.setDwelltimeScore(pro);
 |  | 
 | 
											
												
													
														|  | -                double duration = 0;
 |  | 
 | 
											
												
													
														|  | -                if(item.getItemInfo() != null) {
 |  | 
 | 
											
												
													
														|  | -                    duration = ((ArticleInfo) item.getItemInfo()).getDuration();
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -                duration = Math.min(Math.max(duration, 1), 1800);
 |  | 
 | 
											
												
													
														|  | -                item.setScore(predictDwelltimeScore(item.getRecScore(), pro, duration, item.getId(), requestData, user));
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        } catch (Exception e) {
 |  | 
 | 
											
												
													
														|  | -            LOGGER.error("Exception {},{}", requestContext.getId(), ExceptionUtils.getFullStackTrace(e));
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +
 |