1. 项目概述与核心需求
一个完整的在线书城系统需要解决三个核心问题:商品展示、个性化推荐和交易处理。基于协同过滤算法的书籍推荐系统能够根据用户历史行为(浏览、评分、购买)自动推荐可能感兴趣的书籍,这是提升用户粘性和转化率的关键技术。
我选择的技术栈组合是:
- 后端核心:Python + Django(快速开发、丰富的ORM和生态系统)
- 前端:Vue.js(组件化开发、响应式数据绑定)
- 可选扩展:Java/Spring Boot(适合高并发订单处理场景)
这种组合既保证了推荐系统的开发效率(Python在算法实现上的优势),又能通过Vue实现良好的用户体验,Java的加入则为系统后续扩展提供了可能性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 整体架构分层
code复制表示层 (Vue.js)
↑↓ HTTP/JSON
应用层 (Django REST Framework)
↑↓ ORM
数据层 (MySQL + Redis)
↑↓ 可选RPC调用
Java订单服务 (Spring Boot)
2.2 数据库设计要点
书籍系统的核心表结构设计需要特别注意数据关系的建立:
python复制# models.py 核心模型示例
class Book(models.Model):
title = models.CharField(max_length=200, db_index=True) # 书名加索引
author = models.CharField(max_length=100)
publisher = models.CharField(max_length=100, blank=True)
publish_date = models.DateField(null=True)
isbn = models.CharField(max_length=13, unique=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
cover_url = models.URLField(blank=True)
description = models.TextField(blank=True)
inventory = models.PositiveIntegerField(default=0) # 库存量
class User(AbstractUser): # 继承Django内置用户模型
gender = models.CharField(max_length=10, choices=GENDER_CHOICES, blank=True)
birth_date = models.DateField(null=True, blank=True)
preferences = models.JSONField(default=dict) # 存储用户偏好标签
class Rating(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
book = models.ForeignKey(Book, on_delete=models.CASCADE, db_index=True)
score = models.IntegerField(choices=[(i, i) for i in range(1, 6)]) # 1-5分制
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('user', 'book') # 防止重复评分
关键设计原则:
- 评分表必须建立(user_id, book_id)联合唯一索引
- 书籍名称和ISBN需要单独索引
- 用户偏好使用JSONField存储可扩展的标签数据
- 库存字段需要特别注意并发控制
3. 协同过滤算法实现
3.1 基于用户的协同过滤
实现步骤分解:
- 数据准备阶段:
- 构建用户-书籍评分矩阵
- 处理稀疏性问题(默认评分填充)
python复制import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
def build_rating_matrix():
"""构建评分矩阵,行=用户,列=书籍"""
users = User.objects.all()
books = Book.objects.all()
matrix = np.zeros((len(users), len(books)))
for rating in Rating.objects.select_related('user', 'book'):
user_idx = list(users).index(rating.user)
book_idx = list(books).index(rating.book)
matrix[user_idx][book_idx] = rating.score
# 处理未评分项(用用户平均分填充)
user_means = np.mean(matrix, axis=1)
for i in range(matrix.shape[0]):
matrix[i][matrix[i] == 0] = user_means[i]
return matrix, users, books
- 相似度计算优化:
python复制def calculate_user_similarities(matrix):
"""计算用户相似度矩阵"""
# 使用余弦相似度
sim_matrix = cosine_similarity(matrix)
# 对角线置零(排除自己)
np.fill_diagonal(sim_matrix, 0)
return sim_matrix
def find_similar_users(target_user_idx, sim_matrix, n=5):
"""找出最相似的n个用户"""
similar_users = sim_matrix[target_user_idx].argsort()[::-1][:n]
return [(i, sim_matrix[target_user_idx][i]) for i in similar_users]
- 推荐生成逻辑:
python复制def generate_recommendations(target_user, sim_matrix, matrix, books, n=10):
"""生成推荐书籍列表"""
user_idx = list(User.objects.all()).index(target_user)
similar_users = find_similar_users(user_idx, sim_matrix)
# 计算加权评分
recommendations = {}
for book_idx in range(matrix.shape[1]):
if matrix[user_idx][book_idx] != 0: # 跳过已评分的
continue
weighted_sum = 0
sim_sum = 0
for other_user_idx, similarity in similar_users:
if matrix[other_user_idx][book_idx] > 0:
weighted_sum += similarity * matrix[other_user_idx][book_idx]
sim_sum += similarity
if sim_sum > 0:
predicted_score = weighted_sum / sim_sum
recommendations[books[book_idx]] = predicted_score
# 返回TopN推荐
return sorted(recommendations.items(), key=lambda x: -x[1])[:n]
3.2 性能优化策略
- 离线计算+缓存:
- 每晚定时任务计算用户相似度矩阵
- 结果存入Redis(过期时间24小时)
python复制# tasks.py
from django.core.cache import cache
from celery import shared_task
@shared_task
def update_recommendations():
matrix, users, books = build_rating_matrix()
sim_matrix = calculate_user_simil
