1. 导购APP推荐系统架构设计思路
在电商导购领域,推荐系统的核心价值已经从简单的商品展示转变为精准的个性化匹配。我们团队在开发省赚客APP的过程中,构建了一套完整的推荐系统架构,主要解决三个核心问题:
- 如何快速理解用户偏好?
- 如何从海量商品中筛选出相关候选集?
- 如何对候选商品进行精准排序?
整个系统采用分层架构设计,分为数据层、召回层、排序层和展示层。数据层负责用户行为采集和画像构建;召回层通过多路并行策略快速筛选候选商品;排序层则使用机器学习模型对商品进行精细排序。
关键设计原则:实时性(毫秒级响应)与准确性(精准匹配)的平衡,既要快速响应又要保证推荐质量。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 用户画像构建与实时更新机制
2.1 标签体系设计
用户画像是推荐系统的基石,我们设计了多维度的标签体系:
-
静态属性:
- 基础信息:性别、年龄、地域
- 设备特征:手机型号、操作系统
- 注册信息:会员等级、注册渠道
-
动态兴趣:
- 短期兴趣(7天内):浏览、搜索、加购行为
- 长期兴趣(30天):购买频次、复购类目
- 价格敏感度:基于历史购买价格分布计算
java复制// 用户画像数据模型示例
public class UserProfile {
private Map<String, Double> shortTermInterest; // 短期兴趣分
private Map<String, Double> longTermInterest; // 长期兴趣分
private PriceSensitivity priceSensitivity; // 价格敏感度
// 兴趣分更新算法
public void updateInterest(String category, double score, boolean isShortTerm) {
Map<String, Double> interestMap = isShortTerm ? shortTermInterest : longTermInterest;
double current = interestMap.getOrDefault(category, 0.0);
// 使用衰减因子更新兴趣分
interestMap.put(category, current * 0.7 + score * 0.3);
}
}
2.2 实时更新策略
为了实现画像的实时性,我们建立了完整的行为数据处理流水线:
-
数据采集层:
- 客户端埋点采集用户行为
- 通过Kafka实时传输行为数据
-
实时处理层:
- Flink实时计算引擎处理行为流
- 关键行为(如加购、收藏)触发即时画像更新
-
特征存储:
- Redis存储短期兴趣特征(低延迟)
- HBase存储长期兴趣特征(大容量)
java复制// 实时画像更新服务示例
public class RealtimeProfileUpdateService {
@KafkaListener(topics = "user_behavior")
public void handleBehaviorEvent(BehaviorEvent event) {
// 关键行为权重配置
Map<BehaviorType, Double> behaviorWeights = Map.of(
BehaviorType.CLICK, 0.3,
BehaviorType.ADD_TO_CART, 0.7,
BehaviorType.PURCHASE, 1.0
);
double score = behaviorWeights.getOrDefault(event.getType(), 0.1);
userProfileRepository.updateInterest(
event.getUserId(),
event.getCategoryId(),
score,
true // 短期兴趣
);
}
}
3. 多路召回策略实现
3.1 召回策略设计
我们采用多路并行召回策略,确保覆盖不同类型的用户需求:
| 召回类型 | 适用场景 | 核心算法 | 响应时间 |
|---|---|---|---|
| 协同过滤 | 相似用户偏好 | ItemCF | <50ms |
| 内容召回 | 精准类目匹配 | 标签匹配 | <30ms |
| 热门召回 | 新品/爆款 | 热度排序 | <20ms |
| 促销召回 | 大促场景 | 规则过滤 | <25ms |
3.2 核心实现代码
java复制// 召回策略接口定义
public interface RecallStrategy {
List<ItemInfo> recall(UserProfile user, int limit);
default List<ItemInfo> filterByPrice(List<ItemInfo> items, PriceSensitivity sensitivity) {
// 根据用户价格敏感度过滤商品
return items.stream()
.filter(item -> matchPriceLevel(item, sensitivity))
.collect(Collectors.toList());
}
}
// 协同过滤召回实现
public class ItemCFRecall implements RecallStrategy {
@Override
public List<ItemInfo> recall(UserProfile user, int limit) {
// 1. 获取用户最近交互商品
List<String> recentItems = getRecentInteractions(user.getUserId());
// 2. 查找相似商品
List<ItemInfo> candidates = findSimilarItems(recentItems);
// 3. 价格过滤
return filterByPrice(candidates, user.getPriceSensitivity())
.stream()
.limit(limit)
.collect(Collectors.toList());
}
}
3.3 召回结果融合
多路召回会产生大量候选商品,需要进行去重和融合:
-
去重策略:
- 基于商品ID的精确去重
- 基于商品标题的模糊去重(Jaccard相似度>0.8)
-
融合算法:
- 加权打分:不同召回源赋予不同权重
- 多样性保证:每路召回至少保留20%名额
java复制public class RecallMerger {
public List<ItemInfo> merge(List<List<ItemInfo>> recallResults) {
// 1. 初始化融合结果
Map<String, ItemInfo> mergedItems = new HashMap<>();
// 2. 多路结果融合
for (List<ItemInfo> result : recallResults) {
for (ItemInfo item : result) {
mergedItems.merge(item.getItemId(), item, this::mergeItems);
}
}
// 3. 按综合分排序
return mergedItems.values().stream()
.sorted(Comparator.comparingDouble(ItemInfo::getRecallScore).reversed())
.collect(Collectors.toList());
}
private ItemInfo mergeItems(ItemInfo oldItem, ItemInfo newItem) {
// 合并策略:取最高分,保留多渠道信息
double newScore = Math.max(oldItem.getRecallScore(), newItem.getRecallScore());
oldItem.setRecallScore(newScore);
oldItem.addRecallSource(newItem.getRecallSources());
return oldItem;
}
}
4. 精排模型与特征工程
4.1 特征体系构建
精排阶段使用的特征分为三大类:
-
用户特征:
- 人口统计学特征:性别、年龄等
- 行为特征:点击率、转化率等
- 偏好特征:类目偏好、价格偏好
-
商品特征:
- 基础属性:类目、品牌、价格
- 统计特征:销量、收藏量、好评率
- 时效特征:上新时间、促销信息
-
上下文特征:
- 时间特征:时段、节假日
- 场景特征:搜索词、入口页面
java复制public class FeatureBuilder {
public Map<String, Object> buildFeatures(UserProfile user, ItemInfo item) {
Map<String, Object> features = new HashMap<>();
// 用户特征
features.put("user_gender", user.getGender());
features.put("user_age", user.getAge());
// 商品特征
features.put("item_price", item.getPrice());
features.put("item_discount", item.getDiscount());
// 交叉特征
features.put("price_sensitivity_match",
matchPriceSensitivity(user, item));
// 时序特征
features.put("hour_of_day", LocalDateTime.now().getHour());
return features;
}
}
4.2 模型训练与部署
我们采用XGBoost和DeepFM双模型架构:
-
XGBoost模型:
- 特征重要性分析
- 快速迭代验证
- 基线效果保障
-
DeepFM模型:
- 自动特征交叉
- 高阶特征组合
- 最终线上效果
模型更新策略:
- 天级全量更新
- 小时级增量更新
- 实时特征补充
java复制public class RankingModel {
private XGBoostModel xgboostModel;
private DeepFMModel deepfmModel;
public double predict(UserProfile user, ItemInfo item) {
// 特征构建
Map<String, Object> features = featureBuilder.buildFeatures(user, item);
// 双模型融合
double xgbScore = xgboostModel.predict(features);
double fmScore = deepfmModel.predict(features);
// 加权融合
return 0.3 * xgbScore + 0.7 * fmScore;
}
}
5. 系统优化与效果评估
5.1 性能优化方案
-
缓存策略:
- 用户画像缓存:Redis集群,5分钟TTL
- 热门商品缓存:本地缓存+Redis二级缓存
- 模型特征缓存:Guava Cache,LRU策略
-
计算优化:
- 召回阶段:并行化多路召回
- 特征计算:预计算+实时计算结合
- 模型预测:批量请求优化
-
降级方案:
- 画像降级:使用最近7天画像
- 召回降级:保留热门召回通路
- 排序降级:回退到规则排序
5.2 效果评估指标
我们建立了多维度的评估体系:
| 指标类型 | 核心指标 | 目标值 |
|---|---|---|
| 准确性 | CTR | >5% |
| 商业价值 | GMV贡献率 | >15% |
| 用户体验 | 停留时长 | >90s |
| 多样性 | 类目覆盖率 | >60% |
实际效果提升:
- CTR提升42%
- 加购率提升35%
- GMV贡献提升28%
6. 实践经验与避坑指南
-
冷启动问题解决方案:
- 新用户:基于设备特征推荐
- 新商品:加入热门召回池
- 混合策略:30%个性化+70%热门
-
数据稀疏性处理:
- 行为增强:模拟相似用户行为
- 标签泛化:使用类目层级标签
- 降维处理:PCA减少特征维度
-
线上问题排查清单:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 推荐结果重复 | 去重逻辑失效 | 检查Jaccard相似度阈值 |
| 新商品无曝光 | 召回策略过滤 | 调整新商品权重 |
| CTR突然下降 | 特征数据异常 | 检查特征流水线 |
- 关键调优经验:
- 价格敏感度特征对转化率影响最大
- 实时行为数据能提升15%的CTR
- 多模型融合比单模型效果稳定
这套架构在实际运行中每天处理超过500万次推荐请求,平均响应时间控制在80ms以内。最大的收获是认识到推荐系统需要持续迭代,我们建立了AB测试平台,每周都会上线新的算法策略进行验证。
