Django构建电商推荐系统实战与优化策略
1. 电商推荐系统为什么非有不可做电商的朋友都知道用户进店后的前30秒决定了80%的转化可能。去年帮一个服装电商做咨询时他们首页的跳出率高达73%——这意味着每100个访客有73人连第二屏都没看到就离开了。装上推荐系统两周后这个数字直接降到了41%。推荐系统本质上是个数字导购员它解决了三个核心痛点冷启动问题新用户进来不知道看什么信息过载商品太多导致选择困难长尾挖掘让非爆款商品也有曝光机会传统电商的解决方案是人工编排专题页但人力成本高且响应慢。我们去年双十一实测发现人工编排的专题点击率只有智能推荐的1/3。2. Django为什么是推荐系统的理想框架选技术栈时我们对比过Flask和FastAPI最终选择Django主要基于三点考量2.1 开箱即用的Admin系统Django Admin可以直接可视化操作商品和用户数据这对算法工程师特别友好。通过简单继承ModelAdmin类我们实现了这样的商品管理界面class ProductAdmin(admin.ModelAdmin): list_display (name, category, price) search_fields (name, description) list_filter (category,) readonly_fields (click_count,)2.2 完善的ORM支持处理用户行为数据时Django ORM的annotate和aggregate能大幅简化复杂查询。比如计算用户相似度时这样的查询语句就能搞定from django.db.models import Count user_sims User.objects.annotate( common_itemsCount(clicks__product, filterQ(clicks__product__intarget_user.clicks.all())) ).order_by(-common_items)[:5]2.3 成熟的扩展生态推荐系统常用的组件在Django都能找到成熟方案django-rest-framework 构建APIdjango-celery 处理异步任务django-rq 实现实时推荐队列注意如果预期QPS超过5000建议把Redis单独部署不要用Django的缓存后端直接承载。3. 用户行为数据采集方案设计没有数据再好的算法也是白搭我们设计了四级埋点体系3.1 基础埋点前端实现// 商品点击追踪 document.querySelectorAll(.product-card).forEach(card { card.addEventListener(click, () { fetch(/track/click/?product_id${card.dataset.id}, { method: POST, credentials: include }); }); });3.2 数据模型设计class UserBehavior(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE) product models.ForeignKey(Product, on_deletemodels.CASCADE) behavior_type models.CharField(max_length20) # click/fav/cart/buy timestamp models.DateTimeField(auto_now_addTrue) duration models.FloatField(nullTrue) # 停留时长(秒) class Meta: indexes [ models.Index(fields[user, -timestamp]), models.Index(fields[product, behavior_type]) ]3.3 数据清洗管道使用Celery实现异步处理app.task def clean_behavior_data(): raw_data RawBehavior.objects.filter(is_processedFalse) for item in raw_data: # 去除爬虫流量 if is_spider(item.user_agent): item.delete() continue # 合并短时重复点击 if item.behavior_type click: exists UserBehavior.objects.filter( useritem.user, productitem.product, timestamp__gttimezone.now()-timedelta(seconds10) ).exists() if exists: item.delete() continue4. 混合推荐算法实战我们采用协同过滤内容推荐的混合策略既考虑用户兴趣又避免过度收敛。4.1 用户协同过滤实现def user_based_cf(target_user, n10): # 找出相似用户 similar_users find_similar_users(target_user) # 获取相似用户喜欢的商品 candidate_products Product.objects.filter( Q(behavior__user__insimilar_users) ~Q(behavior__usertarget_user) ).annotate( sim_scoreSum(behavior__user__similarity) ).order_by(-sim_score)[:n*3] # 去重并过滤已购商品 return remove_purchased(candidate_products, target_user)[:n]4.2 内容推荐实现基于商品标签的TF-IDF计算from sklearn.feature_extraction.text import TfidfVectorizer def build_content_matrix(): products Product.objects.all() texts [f{p.category.name} {p.tags} for p in products] vectorizer TfidfVectorizer() return vectorizer.fit_transform(texts), vectorizer def content_recommend(target_product, matrix, n5): # 计算余弦相似度 similarities cosine_similarity( matrix[target_product.id], matrix ) # 返回最相似商品 similar_indices similarities.argsort()[0][-n-1:-1] return Product.objects.filter(id__insimilar_indices)4.3 混合策略def hybrid_recommend(user): cf_items user_based_cf(user, n5) content_items [] if user.recent_views.exists(): last_view user.recent_views.first().product content_items content_recommend(last_view, n5) # 合并并去重 all_items list(cf_items) list(content_items) unique_items list({item.id: item for item in all_items}.values()) # 商业规则过滤 return apply_business_rules(unique_items)[:10]5. 实时推荐性能优化推荐结果缓存是个技术活我们采用分级缓存策略5.1 缓存架构设计缓存层级存储内容过期时间命中率L1(本地)用户最近推荐结果5分钟65%L2(Redis)热门商品推荐1小时25%L3(DB)全量商品数据不缓存10%5.2 Django缓存配置CACHES { default: { BACKEND: django_redis.cache.RedisCache, LOCATION: redis://127.0.0.1:6379/1, OPTIONS: { CLIENT_CLASS: django_redis.client.DefaultClient, MAX_ENTRIES: 10000, CULL_FREQUENCY: 10 } } }5.3 缓存装饰器实现def cache_recommend(view_func): wraps(view_func) def wrapper(user, *args, **kwargs): cache_key frec_{user.id} result cache.get(cache_key) if not result: result view_func(user, *args, **kwargs) cache.set(cache_key, result, timeout300) # 异步更新相似用户缓存 update_similar_users_cache.delay(user.id) return result return wrapper6. 推荐效果评估体系没有评估的推荐系统就像蒙眼射击我们建立了多维评估指标6.1 离线指标def calculate_metrics(): # 准确率 precision sum(hits) / len(recommendations) # 覆盖率 all_items Product.objects.count() covered len(set(recommended_items)) coverage covered / all_items # 新颖度 novelty sum(-math.log(p.popularity) for p in recommendations) return { precision: round(precision, 4), coverage: round(coverage, 4), novelty: round(novelty, 4) }6.2 在线指标通过埋点采集点击率CTR转化率CVR推荐商品GMV占比6.3 A/B测试框架class ABTestMiddleware: def __init__(self, get_response): self.get_response get_response def __call__(self, request): if request.user.is_authenticated: # 分配测试组 group A if request.user.pk % 2 else B request.ab_group group response self.get_response(request) return response7. 部署实战经验7.1 服务器配置建议组件最低配置推荐配置Web2核4G4核8GRedis1核2G2核4GCelery2核4G4核8G数据库4核8G8核16G7.2 部署流程示例宝塔面板安装Python项目管理器创建Django项目虚拟环境配置uWSGI[uwsgi] socket :8000 chdir /www/wwwroot/your_project module your_project.wsgi master true processes 4设置Nginx反向代理配置Celery守护进程7.3 性能调优参数# settings.py 关键配置 DATABASES { OPTIONS: { connect_timeout: 3, max_connections: 100, } } CACHES { default: { TIMEOUT: 60, KEY_PREFIX: recsys, } }8. 常见问题排坑指南8.1 推荐结果总是那几个商品这是典型的长尾缺失问题解决方案在混合算法中增加随机因子设置品类多样性约束引入EE(探索与利用)机制8.2 新商品永远得不到推荐冷启动解决方案基于内容相似度推荐新品设置新品推荐专区人工打标运营位8.3 用户登录后推荐系统崩溃典型原因及排查步骤检查用户行为数据是否为空验证协同过滤的相似用户计算查看Celery任务队列是否堆积# 诊断代码示例 def diagnose_failure(user): if not user.behaviors.exists(): return 无用户行为数据 try: similar_users find_similar_users(user) if not similar_users: return 无相似用户 except Exception as e: return f相似计算异常: {str(e)} return 系统正常9. 项目演进方向这套系统上线后还可以考虑以下升级路径实时画像系统用Flink处理用户行为流深度学习模型引入TensorFlow实现WideDeep多目标优化平衡点击率/转化率/GMV等指标跨域推荐整合APP/小程序/PC端数据最近我们在尝试用Django Channels实现WebSocket推送当用户浏览商品时实时更新推荐栏。实测显示这样能使CTR再提升18-22%。推荐系统永远有优化空间关键是要建立完整的数据闭环推荐→收集反馈→优化模型→再推荐。每次迭代不必追求大改1%的CTR提升在百万级用户面前就是可观的商业价值。