1. 项目概述与背景
在电商平台商品数量爆炸式增长的今天,用户面临着严重的信息过载问题。根据行业研究数据,一个中型电商平台的平均SKU数量超过50万,而用户的有效浏览深度通常不超过3页。这意味着大量优质商品因为曝光不足而被埋没,同时用户也难以快速找到真正符合自己需求的商品。
我去年参与开发的一个化妆品电商平台就遇到了这样的困境:尽管平台拥有超过8万种商品,但用户平均下单转化率仅为1.2%,远低于行业平均水平。经过数据分析发现,超过60%的用户流失发生在浏览前5分钟,主要原因就是"找不到想要的商品"。
这正是我们开发这个基于双协同过滤算法的商品推荐系统的初衷。系统采用Python+Django技术栈,创新性地结合了基于用户(UserCF)和基于物品(ItemCF)的两种协同过滤算法,通过分析用户行为数据,为每个用户生成个性化的商品推荐列表。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体技术栈选型
在项目启动阶段,我们评估了多种技术方案,最终确定了以下技术栈:
-
后端框架:选择Django而非Flask,主要考虑因素包括:
- Django自带ORM、Admin后台等完整功能,适合快速开发业务系统
- 内置的用户认证系统可直接用于用户模块开发
- 成熟的模板引擎便于前后端协作
- 社区活跃,遇到问题容易找到解决方案
-
数据库:采用MySQL 8.0,主要优势:
- 成熟稳定,支持事务和复杂查询
- 与Django ORM无缝集成
- 适合存储结构化商品和用户数据
- 支持JSON字段,便于存储商品属性等半结构化数据
-
推荐算法:实现双协同过滤机制:
- 基于用户的协同过滤(UserCF):适合发现用户潜在兴趣
- 基于物品的协同过滤(ItemCF):适合精准推荐相似商品
- 两种算法结果加权融合,提升推荐多样性
-
数据采集:使用Requests+BeautifulSoup爬虫方案:
- Requests处理HTTP请求简单高效
- BeautifulSoup解析HTML灵活稳定
- 配合自定义去重和异常处理机制
2.2 系统架构设计
系统采用典型的三层架构:
code复制[表现层]
Django模板 + HTML/CSS/JS
↓
[业务逻辑层]
Django Views + 推荐算法模块
↓
[数据访问层]
Django ORM → MySQL数据库
关键设计决策:
-
推荐结果缓存:为避免每次请求都重新计算推荐结果,采用Redis缓存:
- 用户登录后立即预计算推荐结果
- 缓存有效期24小时,或直到用户有新行为
- 缓存命中率可达85%,大幅降低服务器负载
-
行为数据收集:设计专门的数据表记录:
- 浏览记录(footmark):用户ID、商品ID、浏览时间
- 收藏记录(collect):用户ID、商品ID、收藏时间
- 购买记录(order):用户ID、商品ID、购买时间、数量
-
算法融合策略:
- UserCF结果权重0.4,适合发现多样性
- ItemCF结果权重0.6,保证推荐精准度
- 最终按加权分数排序取TopN商品
3. 核心模块实现
3.1 用户认证模块
用户模块基于Django内置auth系统扩展开发:
python复制# account/models.py
from django.contrib.auth.models import AbstractUser
class Account(AbstractUser):
GENDER_CHOICES = (
('M', '男'),
('F', '女'),
('U', '未知')
)
mobile = models.CharField(max_length=11, unique=True)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default='U')
avatar = models.ImageField(upload_to='avatars/', default='avatars/default.png')
def __str__(self):
return self.username
关键实现细节:
-
密码安全:
- 使用PBKDF2算法加密存储
- 密码强度验证:至少8位,包含字母和数字
- 登录失败5次锁定账户30分钟
-
会话管理:
- 使用Django session机制
- 会话有效期7天,支持"记住我"功能
- 每次登录生成新session,防止会话固定攻击
-
扩展字段:
- 手机号必填,用于找回密码
- 用户画像字段:性别、年龄区间等
- 后期可用于改进推荐精准度
3.2 商品数据模型设计
商品模型设计考虑了电商业务的复杂性:
python复制# p
