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

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

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

相关推荐
努力也学不会java11 分钟前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
攒了一袋星辰13 分钟前
高并发强一致性顺序号生成系统 -- SequenceGenerator
java·数据库·mysql
小涛不学习15 分钟前
Spring Boot 详解(从入门到原理)
java·spring boot·后端
于先生吖1 小时前
Java框架开发短剧漫剧系统:后台管理与接口开发
java·开发语言
daidaidaiyu2 小时前
Spring IOC 源码学习 声明式事务的入口点
java·spring
myloveasuka2 小时前
[Java]查找算法&排序算法
java·算法·排序算法
清水白石0082 小时前
Free-Threaded Python 实战指南:机遇、风险与 PoC 验证方案
java·python·算法
发际线还在2 小时前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
_周游3 小时前
Kaptcha—Google验证码工具
java·intellij-idea·jquery
我真会写代码3 小时前
深入理解JVM GC:触发机制、OOM关联及核心垃圾回收算法
java·jvm·架构