小说推荐系统是当前数字阅读平台的核心功能之一。作为一名长期从事推荐系统开发的工程师,我发现协同过滤算法在实际应用中展现出强大的用户行为模式捕捉能力。这次基于Django框架构建的系统,正是将这一经典算法与Web开发技术结合的典型实践。
系统采用B/S架构设计,前端使用HTML+CSS+JavaScript标准技术栈,后端基于Python的Django框架,数据库选用MySQL 5.7版本。整个系统实现了用户管理、小说信息管理、推荐计算等核心模块,其中推荐算法部分采用基于用户的协同过滤(UserCF)实现。这种架构选择主要基于以下考量:
注意:实际部署时建议使用MySQL 5.7而非8.0版本,因部分Python连接器对8.0的caching_sha2_password认证方式支持不够稳定
系统采用典型的三层架构:
code复制表示层(Django模板)
业务逻辑层(Django视图+推荐算法)
数据访问层(Django ORM+MySQL)
关键组件说明:
主要数据表结构设计如下:
users_user(用户表)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| username | varchar(50) | 用户名 |
| password | varchar(128) | 加密密码 |
| last_login | datetime | 最后登录时间 |
books_novel(小说表)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| title | varchar(100) | 书名 |
| author | varchar(50) | 作者 |
| category | varchar(20) | 分类 |
| tags | varchar(200) | 标签 |
books_rating(评分表)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| user_id | int | 外键关联用户 |
| novel_id | int | 外键关联小说 |
| rating | float | 评分(1-5) |
| create_time | datetime | 评分时间 |
提示:实际项目中建议为评分表添加联合索引(user_id, novel_id)以提高查询效率
核心算法采用基于用户的协同过滤,主要步骤如下:
相似度计算采用改进的余弦相似度公式:
code复制sim(u,v) = ∑(r_u,i - r̄_u)(r_v,i - r̄_v) / (√∑(r_u,i - r̄_u)² × √∑(r_v,i - r̄_v)²)
Python实现代码片段:
python复制from sklearn.metrics.pairwise import cosine_similarity
def calculate_user_similarity(ratings):
# 评分标准化(减去用户平均分)
user_mean = ratings.mean(axis=1)
ratings_centered = ratings.sub(user_mean, axis=0)
# 计算余弦相似度
similarity = cosine_similarity(ratings_centered.fillna(0))
return pd.DataFrame(similarity, index=ratings.index, columns=ratings.index)
预测评分采用加权平均法:
code复制p(u,i) = r̄_u + [∑sim(u,v)(r_v,i - r̄_v)] / ∑|sim(u,v)|
实际项目中还需考虑:
推荐接口核心代码:
python复制# views.py
from django.http import JsonResponse
from .recommender import get_recommendations
def recommend(request):
if not request.user.is_authenticated:
return JsonResponse({'status': 'error', 'msg': '需要登录'})
user_id = request.user.id
top_n = int(request.GET.get('top', 10))
try:
novels = get_recommendations(user_id, top_n)
data = [{
'id': novel.id,
'title': novel.title,
'author': novel.author,
'score': novel.avg_score
} for novel in novels]
return JsonResponse({'status': 'success', 'data': data})
except Exception as e:
return JsonResponse({'status': 'error', 'msg': str(e)})
推荐引擎核心类:
python复制# recommender.py
import pandas as pd
from sklearn.neighbors import NearestNeighbors
class BookRecommender:
def __init__(self, rating_data):
self.ratings = rating_data
self.model = None
def train(self):
# 构建用户-物品矩阵
user_item_matrix = self.ratings.pivot_table(
index='user_id',
columns='novel_id',
values='rating',
fill_value=0
)
# 训练KNN模型
self.model = NearestNeighbors(
metric='cosine',
algorithm='brute',
n_neighbors=20
)
self.model.fit(user_item_matrix)
def recommend(self, user_id, n=10):
# 获取相似用户
user_vector = self._get_user_vector(user_id)
distances, indices = self.model.kneighbors([user_vector])
# 合并相似用户的阅读记录
similar_users = self.user_ids[indices[0]]
recommendations = self.ratings[
self.ratings['user_id'].isin(similar_users)
].groupby('novel_id')['rating'].mean().sort_values(ascending=False)
return recommendations.head(n)
实际运行中发现两个性能瓶颈:
采用的优化策略:
优化后性能对比:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 推荐响应时间 | 520ms | 85ms |
| 计算资源占用 | CPU 90% | CPU 35% |
| 内存使用 | 2.1GB | 1.3GB |
问题1:新用户冷启动
现象:新用户获取的推荐质量差
解决方案:
问题2:推荐多样性不足
现象:推荐列表过于相似
解决方案:
问题3:数据稀疏性
现象:用户-物品矩阵稀疏度高(>95%)
解决方案:
经过三个月的开发和优化,系统最终实现了:
后续改进方向:
实际部署中发现,Django自带的ORM在处理大规模连接查询时性能较差,对于用户量超过50万的平台,建议考虑以下架构调整: