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

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

大家好,我是省赚客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开发者团队,转载请注明出处!

相关推荐
Anastasiozzzz21 分钟前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人22 分钟前
通过脚本推送Docker镜像
java·docker·容器
铁蛋AI编程实战39 分钟前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘1 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10111 小时前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠1 小时前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.1 小时前
java多态
java·开发语言·c++
李堇1 小时前
android滚动列表VerticalRollingTextView
android·java
泉-java2 小时前
第56条:为所有导出的API元素编写文档注释 《Effective Java》
java·开发语言
zfoo-framework2 小时前
帧同步和状态同步
java