Authored by hugufei

1)REC_SKN和RT_SIM_SKN拆分

2)只保留v2w的向量召回
3)新老版本做A/B
... ... @@ -213,7 +213,7 @@ public class UserRecallResponseBuilder {
continue;
}
//2)如果是推荐出来的,则单独加分[以减分的方式依次保证顺序]
if (strategy.equals(StrategyEnum.REC_SKN)) {
if (strategy.equals(StrategyEnum.REC_SKN) || strategy.equals(StrategyEnum.RT_SIM_SKN)) {
sknResult.setScore((double) recommendSknIndex--);
continue;
}
... ... @@ -304,7 +304,7 @@ public class UserRecallResponseBuilder {
iterator = sknResultList.iterator();
while (iterator.hasNext()) {
RecallMergerResult.SknResult sknResult = iterator.next();
if (!Arrays.asList(StrategyEnum.DIRECT_TRAIN, StrategyEnum.REC_SKN).contains(sknResult.getStrategy())) {
if (!Arrays.asList(StrategyEnum.DIRECT_TRAIN, StrategyEnum.REC_SKN, StrategyEnum.RT_SIM_SKN).contains(sknResult.getStrategy())) {
results.add(sknResult);
iterator.remove();
}
... ... @@ -313,7 +313,10 @@ public class UserRecallResponseBuilder {
// 3、插入【REC_SKN】的商品-随机插入
this.addByIndexIndex(sknResultList, results, 1, 2, (sknResult -> StrategyEnum.REC_SKN.equals(sknResult.getStrategy())), dropTransfer);
// 4、插入【直通车】商品-随机插入
// 4、插入【RT_SIM_SKN】的商品-随机插入
this.addByIndexIndex(sknResultList, results, 1, 2, (sknResult -> StrategyEnum.RT_SIM_SKN.equals(sknResult.getStrategy())), dropTransfer);
// 5、插入【直通车】商品-随机插入
int directTrainIndexInterval = searchDynamicConfigService.directTrainIndexInterval();
this.addByIndexIndex(sknResultList, results, 4, directTrainIndexInterval, (sknResult -> StrategyEnum.DIRECT_TRAIN.equals(sknResult.getStrategy())), dropTransfer);
... ...
... ... @@ -100,7 +100,7 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
private List<RecallRequestResponse> batchRecall(UserRecallRequest userRecallRequest, UserPersonalFactor userPersonalFactor) {
//1、处理实时推荐SKN的召回
//CompletableFuture<List<RecallRequestResponse>> sknListCompletableFuture = this.doRecallSknList(userRecallRequest, userPersonalFactor);
CompletableFuture<List<RecallRequestResponse>> sknListCompletableFuture = this.doRecallSknList(userRecallRequest, userPersonalFactor);
//2、处理通用召回
CompletableFuture<List<RecallRequestResponse>> commonCompletableFuture = this.doRecallCommon(userRecallRequest, userPersonalFactor);
... ... @@ -108,21 +108,20 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
//3、处理实时推荐的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> realTimeSortBrandCompletableFuture = this.doRecallRealTimeSortBrand(userRecallRequest, userPersonalFactor);
//4、处理基于RNN向量生成的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> vectorRnnSortBrandCompletableFuture = this.doRecallVectorRnnSortBrand(userRecallRequest, userPersonalFactor);
//5、处理基于W2V向量生成的品类品牌的召回
//4、处理基于W2V向量生成的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> vectorW2vSortBrandCompletableFuture = this.doRecallVectorW2vSortBrand(userRecallRequest, userPersonalFactor);
//5、处理基于RNN向量生成的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> vectorRnnSortBrandCompletableFuture = this.doRecallVectorRnnSortBrand(userRecallRequest, userPersonalFactor);
//6、构造最终返回结果投入额
List<RecallRequestResponse> batchRequestResults = new ArrayList<>();
//batchRequestResults.addAll(this.getResultFromCompletableFuture(sknListCompletableFuture));//按skn召回放在第一个,不然merger的时候可能会无序
batchRequestResults.addAll(this.getResultFromCompletableFuture(sknListCompletableFuture));//按skn召回放在第一个,不然merger的时候可能会无序
batchRequestResults.addAll(this.getResultFromCompletableFuture(commonCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(realTimeSortBrandCompletableFuture));
//batchRequestResults.addAll(this.getResultFromCompletableFuture(forecastSortBrandCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(vectorRnnSortBrandCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(vectorW2vSortBrandCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(vectorRnnSortBrandCompletableFuture));
//9、日志打印
if (userRecallRequest.openDetailLog()) {
... ...
... ... @@ -55,14 +55,14 @@ public class QueryUserPersionalFactorBean {
UserPersonalFactorRspNew userFactor = userComponent.queryUserPersionalFactor(userRecallRequest.getUid(), userRecallRequest.getUdid(), pageFactor.getMisortIds());
cost = System.currentTimeMillis() - begin;
if(userRecallRequest.openDetailLog()){
if (userRecallRequest.openDetailLog()) {
StringBuilder sizeLogInfo = new StringBuilder();
sizeLogInfo.append("SKN_SIZE is ").append(userFactor.getRecommendSknList().size()).append(";");
sizeLogInfo.append("RT_SB_SIZE is ").append(userFactor.getRealTimeSortBrandList().size()).append(";");
sizeLogInfo.append("VECTOR_RNN_SIZE is ").append(userFactor.getBrandVector().size()).append("_").append(userFactor.getSortBrandVector().size()).append(";");
sizeLogInfo.append("VECTOR_W2C_SIZE is ").append(userFactor.getBrandVectorW2v().size()).append("_").append(userFactor.getSortBrandVectorW2v().size()).append(";");
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[2]:queryUserPersionalFactor. uid is[{}],udid is[{}], cost is[{}], size log info is [{}] ", uid, udid, cost, sizeLogInfo.toString());
}else{
} else {
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[2]:queryUserPersionalFactor. uid is[{}],udid is[{}], cost is[{}]", uid, udid, cost);
}
... ... @@ -83,6 +83,7 @@ public class QueryUserPersionalFactorBean {
List<SortPriceAreas> sortPriceAreasList = this.getSortPriceAreasListWithSort(userFactor, pageFactor);
//2、构造推荐的skn列表
List<Integer> recommendSknList = userFactor.getRecommendSknList();
List<Integer> realTimeSimilarSknList = userFactor.getRealTimeSimilarSknList();
//3、获取页面中存在的所有的key
Set<String> pageSortBrandKeys = new HashSet<>();
... ... @@ -97,19 +98,20 @@ public class QueryUserPersionalFactorBean {
filterSortBrandKeys.add(existSortBrand.key());
}
//5、构造基于RNN向量的【品牌+品牌】,去除实时的品类和品牌
int maxVectorRNNSortBrandCount = RecallCommonConstants.maxVectorRNNSortBrandCount;
List<SortBrand> vectorRnnSortBrandList = sortBrandVectorComponent.queryVectorSortBrandList(pageFactor, filterSortBrandKeys, userFactor.getBrandVector(), userFactor.getSortBrandVector(),true, maxVectorRNNSortBrandCount);
for (SortBrand existSortBrand : vectorRnnSortBrandList) {
filterSortBrandKeys.add(existSortBrand.key());
}
List<SortBrand> vectorRnnSortBrandList = new ArrayList<>();
// int maxVectorRNNSortBrandCount = RecallCommonConstants.maxVectorRNNSortBrandCount;
// List<SortBrand> vectorRnnSortBrandList = sortBrandVectorComponent.queryVectorSortBrandList(pageFactor, filterSortBrandKeys, userFactor.getBrandVector(), userFactor.getSortBrandVector(),true, maxVectorRNNSortBrandCount);
// for (SortBrand existSortBrand : vectorRnnSortBrandList) {
// filterSortBrandKeys.add(existSortBrand.key());
// }
//6、构造基于W2V向量的【品牌+品牌】,去除实时的品类和品牌
int maxVectorW2SortBrandCount = RecallCommonConstants.maxVectorW2SortBrandCount;
List<SortBrand> vectorW2vSortBrandList = sortBrandVectorComponent.queryVectorSortBrandList(pageFactor, filterSortBrandKeys, userFactor.getBrandVectorW2v(), userFactor.getSortBrandVectorW2v(),false, maxVectorW2SortBrandCount);
List<SortBrand> vectorW2vSortBrandList = sortBrandVectorComponent.queryVectorSortBrandList(pageFactor, filterSortBrandKeys, userFactor.getBrandVectorW2v(), userFactor.getSortBrandVectorW2v(), false, maxVectorW2SortBrandCount);
for (SortBrand existSortBrand : vectorW2vSortBrandList) {
filterSortBrandKeys.add(existSortBrand.key());
}
//8、返回最终结果
return new UserPersonalFactor(recommendSknList, sortPriceAreasList, realTimeSortBrandList, vectorRnnSortBrandList, vectorW2vSortBrandList);
//7、返回最终结果
return new UserPersonalFactor(recommendSknList, realTimeSimilarSknList, sortPriceAreasList, realTimeSortBrandList, vectorRnnSortBrandList, vectorW2vSortBrandList);
}
private List<SortBrand> getSortBrandListWithSort(Set<String> pageSortBrandKeys, Set<String> filterSortBrandKeys, List<SortBrand> userSortBrands, int maxCount) {
... ...
... ... @@ -6,6 +6,7 @@ public enum StrategyEnum {
DIRECT_TRAIN(109),//直通车
REC_SKN(99),//实时推荐的skn
RT_SIM_SKN(98),//实时推荐的skn的相似skn
REC_S_B_HEAT_VALUE(80),//实时的品牌+品类的人气值
REC_S_B_CTR_VALUE(81),//实时的品牌+品类的转化率
... ...
package com.yoho.search.recall.scene.beans.strategy.impls;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
/**
* 推荐skn的召回策略
*
* @author gufei.hu
*
*/
public class RealTimeSimilarSknStrategy extends IRecallSknStrategy{
public RealTimeSimilarSknStrategy(Integer recommendSkn) {
super(recommendSkn);
}
@Override
public StrategyEnum strategtEnum() {
return StrategyEnum.RT_SIM_SKN;
}
}
... ...
... ... @@ -9,6 +9,7 @@ import java.util.List;
public class UserPersonalFactor {
private List<Integer> recommendSknList;
private List<Integer> realTimeSimilarSknList;
private List<SortPriceAreas> sortPriceAreasList;
private List<SortBrand> realTimeSortBrandList;
... ... @@ -17,6 +18,7 @@ public class UserPersonalFactor {
public UserPersonalFactor() {
this.recommendSknList = new ArrayList<>();
this.realTimeSimilarSknList = new ArrayList<>();
this.sortPriceAreasList = new ArrayList<>();
this.realTimeSortBrandList = new ArrayList<>();
... ... @@ -24,8 +26,9 @@ public class UserPersonalFactor {
this.vectorW2vSortBrandList = new ArrayList<>();
}
public UserPersonalFactor(List<Integer> recommendSknList, List<SortPriceAreas> sortPriceAreasList, List<SortBrand> realTimeSortBrandList, List<SortBrand> vectorRnnSortBrandList, List<SortBrand> vectorW2vSortBrandList) {
public UserPersonalFactor(List<Integer> recommendSknList, List<Integer> realTimeSimilarSknList, List<SortPriceAreas> sortPriceAreasList, List<SortBrand> realTimeSortBrandList, List<SortBrand> vectorRnnSortBrandList, List<SortBrand> vectorW2vSortBrandList) {
this.recommendSknList = recommendSknList;
this.realTimeSimilarSknList = realTimeSimilarSknList;
this.sortPriceAreasList = sortPriceAreasList;
this.realTimeSortBrandList = realTimeSortBrandList;
... ... @@ -37,6 +40,10 @@ public class UserPersonalFactor {
return recommendSknList;
}
public List<Integer> getRealTimeSimilarSknList() {
return realTimeSimilarSknList;
}
public List<SortPriceAreas> getSortPriceAreasList() {
return sortPriceAreasList;
}
... ...
... ... @@ -201,6 +201,7 @@ public class SearchSortHelper {
// 都要添加次要排序条件
private void addDeafultSortBuildSorts(List<SortBuilder<?>> sortBuilders, List<String> filteredFieldNames) {
this.addSortBuildSorts(sortBuilders, filteredFieldNames, ProductIndexEsField.sevendayMoney, SortOrder.DESC);
this.addSortBuildSorts(sortBuilders, filteredFieldNames, ProductIndexEsField.salesNum, SortOrder.DESC);
this.addSortBuildSorts(sortBuilders, filteredFieldNames, ProductIndexEsField.firstShelveTime, SortOrder.DESC);
this.addSortBuildSorts(sortBuilders, filteredFieldNames, ProductIndexEsField.id, SortOrder.DESC);
... ...
... ... @@ -28,6 +28,11 @@ public class ProductListSwitchService {
@Autowired
private FuzzySceneProductListService fuzzySceneProductListService;
private boolean isAUser(int uid) {
int tail = uid % 1024;
return tail < 512 ? true : false;
}
/**
* 普通商品列表入口
*
... ... @@ -61,26 +66,33 @@ public class ProductListSwitchService {
return defaultProductListService.productListForDefaultPersional(paramMap);
}
// 5、是否使用新的召回策略
// 5、个性化版本A/B 测试
int uid = searchCommonHelper.getUid(paramMap);
if(uid>0 && isAUser(uid)){
return defaultProductListService.productListForDefaultPersional(paramMap);
}
// 6、是否使用新的召回策略
boolean searchPersionalNewStrategyOpen = searchDynamicConfigService.searchPersionalNewStrategyOpen();
if (searchPersionalNewStrategyOpen) {
return sceneRecallProductListService.recallProductList(paramMap);
}
// 6、默认-使用向量版本的个性化方案
// 7、默认-使用向量版本的个性化方案
return defaultProductListService.productListForDefaultPersional(paramMap);
}
/**
* 模糊搜索列表入口
*
* @param paramMap
* @return
*/
public SearchApiResult fuzzyProductList(Map<String, String> paramMap) {
if(searchCommonHelper.isOrderEmpty(paramMap)){
if (searchCommonHelper.isOrderEmpty(paramMap)) {
return fuzzySceneProductListService.fuzzyProductListPersional(paramMap);
}else{
} else {
return fuzzySceneProductListService.fuzzyProductListNotPersional(paramMap);
}
}
... ...