导购类电商平台搜索推荐融合:基于用户行为的个性化导购系统

导购类电商平台搜索推荐融合:基于用户行为的个性化导购系统

大家好,我是省赚客APP研发者阿宝!

在省赚客这类导购型电商平台上,用户既会主动搜索商品,也会被动接受推荐内容。如何将"搜索"与"推荐"两大核心路径深度融合,构建统一的个性化导购系统,是提升转化率的关键。我们通过整合用户实时行为、历史偏好与上下文信息,设计了一套基于多路召回 + 排序模型的融合架构,并在Java技术栈中落地实现。

整体架构设计

系统分为三层:行为采集层 → 召回融合层 → 排序展示层

  • 行为采集层:通过埋点收集用户点击、加购、下单、搜索关键词等事件;
  • 召回融合层:结合搜索Query意图与推荐兴趣画像,生成候选商品池;
  • 排序展示层:使用深度学习模型对候选集打分,输出Top-N结果。

所有行为数据通过Kafka实时流入Flink进行特征计算,并写入Redis与HBase供在线服务调用。

用户行为特征建模

我们定义了三类核心特征:

  1. 短期兴趣序列:最近20次交互商品ID及行为类型(click/cart/pay);
  2. 长期画像标签:如"母婴偏好""高客单价""3C数码爱好者";
  3. 搜索上下文:当前Query、地域、设备类型等。

Java中特征提取示例如下:

java 复制代码
package juwatech.cn.recsys.feature;

import juwatech.cn.recsys.model.UserBehavior;
import java.util.List;

public class UserFeatureExtractor {

    public UserFeature buildFeature(String userId, String query) {
        List<UserBehavior> recentBehaviors = behaviorService.getRecentBehaviors(userId, 20);
        List<String> interestTags = userProfileService.getInterestTags(userId);
        String location = userLocationService.getLocation(userId);

        return UserFeature.builder()
                .userId(userId)
                .query(query)
                .location(location)
                .interestTags(interestTags)
                .behaviorSequence(recentBehaviors)
                .build();
    }
}

多路召回策略

为兼顾相关性与多样性,我们采用四路召回:

  1. Query语义召回:基于Elasticsearch的BM25 + 向量检索;
  2. 协同过滤召回:UserCF与ItemCF混合;
  3. 热门趋势召回:按类目实时热度排序;
  4. 个性化兴趣召回:DSSM双塔模型生成的向量近邻。

各路召回结果合并去重后进入排序阶段。关键代码如下:

java 复制代码
package juwatech.cn.recsys.recall;

import java.util.Set;
import java.util.stream.Collectors;

public class MultiRecallService {

    public Set<String> recall(String userId, String query, int topK) {
        Set<String> esResults = esRecallService.recallByQuery(query, topK);
        Set<String> cfResults = collaborativeFilteringService.recall(userId, topK);
        Set<String> hotResults = hotItemService.getHotItems(topK);
        Set<String> dssmResults = dssmRecallService.recall(userId, topK);

        return Stream.of(esResults, cfResults, hotResults, dssmResults)
                .flatMap(Set::stream)
                .limit(topK * 2) // 控制候选集规模
                .collect(Collectors.toSet());
    }
}

融合排序模型

排序阶段采用Wide & Deep结构,其中:

  • Wide部分:处理Query与商品标题的关键词匹配、类目一致性等规则特征;
  • Deep部分:输入用户行为序列、画像标签、商品多模态特征(文本+图像Embedding)。

模型通过TensorFlow训练,导出SavedModel后由Java服务加载推理:

java 复制代码
package juwatech.cn.recsys.rank;

import org.tensorflow.SavedModelBundle;
import org.tensorflow.Session;
import org.tensorflow.Tensor;

public class RankingModelService {

    private final Session session;

    public RankingModelService(String modelPath) {
        SavedModelBundle bundle = SavedModelBundle.load(modelPath, "serve");
        this.session = bundle.session();
    }

    public float predictScore(RankingFeatures features) {
        try (Tensor<?> input = features.toTensor();
             Tensor<?> output = session.runner()
                     .feed("input", input)
                     .fetch("output/score")
                     .run().get(0)) {
            return ((float[]) output.copyTo(new float[1]))[0];
        }
    }
}

为提升性能,我们对候选集批量打分:

java 复制代码
public List<RankedItem> rankItems(String userId, String query, Set<String> candidates) {
    UserFeature userFeature = featureExtractor.buildFeature(userId, query);
    List<RankingFeatures> batchFeatures = candidates.stream()
            .map(itemId -> buildRankingFeatures(userFeature, itemId))
            .collect(Collectors.toList());

    float[] scores = rankingModel.batchPredict(batchFeatures);
    return IntStream.range(0, candidates.size())
            .mapToObj(i -> new RankedItem(
                    (String) candidates.toArray()[i],
                    scores[i]
            ))
            .sorted((a, b) -> Float.compare(b.getScore(), a.getScore()))
            .limit(20)
            .collect(Collectors.toList());
}

冷启动与实时反馈

针对新用户或新商品,系统启用以下策略:

  • 新用户:默认走热门+地域化召回;
  • 新商品:通过内容特征(类目、价格、图文Embedding)匹配相似老品进行曝光。

同时,用户每次点击后触发在线学习反馈:

java 复制代码
@KafkaListener(topics = "user_click_event")
public void onUserClick(ClickEvent event) {
    // 更新用户短期兴趣序列
    behaviorCache.updateSequence(event.getUserId(), event.getItemId(), "click");
    
    // 触发在线模型微调(可选)
    if (onlineLearningEnabled) {
        onlineLearner.trainOnEvent(event);
    }
}

线上效果

上线后AB测试数据显示:

  • 搜索页人均点击率提升23%;
  • 推荐位GMV贡献增长31%;
  • 长尾商品曝光占比提高18%,有效缓解马太效应。

本文著作权归聚娃科技省赚客app开发者团队,转载请注明出处!

相关推荐
愿你天黑有灯下雨有伞2 分钟前
java动态渲染列导出以及分页列表
java
星火开发设计7 分钟前
共用体 union:节省内存的特殊数据类型
java·开发语言·数据库·c++·算法·内存
2301_8035545215 分钟前
阻塞,非阻塞,同步,异步以及linux上的5种IO模型阻塞,非阻塞,信号驱动,异步,IO复用
java·服务器·网络
仰望星空_Star27 分钟前
Java证书操作
java·开发语言
河北小博博30 分钟前
分布式系统稳定性基石:熔断与限流的深度解析(附Python实战)
java·开发语言·python
岳轩子31 分钟前
JVM Java 类加载机制与 ClassLoader 核心知识全总结 第二节
java·开发语言·jvm
J_liaty40 分钟前
Spring Boot + MinIO 文件上传工具类
java·spring boot·后端·minio
2601_9496130244 分钟前
flutter_for_openharmony家庭药箱管理app实战+药品详情实现
java·前端·flutter
木井巳1 小时前
【递归算法】求根节点到叶节点数字之和
java·算法·leetcode·深度优先
没有bug.的程序员1 小时前
Spring Boot 事务管理:@Transactional 失效场景、底层内幕与分布式补偿实战终极指南
java·spring boot·分布式·后端·transactional·失效场景·底层内幕