1. 项目概述与背景
这个基于Python和Django的个性化音乐推荐系统,是我在指导计算机专业毕业设计时经常采用的经典案例。随着数字音乐平台的普及,用户面对海量音乐资源时常常陷入"选择困难",这正是推荐系统大显身手的地方。
系统采用B/S架构,前端使用HTML+CSS+JavaScript构建用户界面,后端基于Django框架开发,数据存储选用MySQL关系型数据库。核心创新点在于实现了用户协同过滤(UserCF)和物品协同过滤(ItemCF)双算法并行,通过IUF( Inverse User Frequency)优化解决了传统协同过滤在用户行为稀疏场景下的推荐质量问题。
提示:实际开发中发现,当用户行为数据不足时,传统协同过滤的推荐效果会显著下降。采用IUF加权可以缓解这个问题,这也是本系统选择ItemCF-IUF作为主要算法的原因。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型分析
后端技术选择:
- Python 3.8:语法简洁,拥有丰富的科学计算库
- Django 3.2:自带Admin后台,ORM完善,开发效率高
- Django REST framework:为未来API扩展预留空间
数据库选型考虑:
- MySQL 8.0:事务支持完善,适合结构化数据存储
- Redis(可选):用于缓存热门歌曲和用户画像
前端技术组合:
- Bootstrap 5:快速构建响应式界面
- ECharts 5:实现数据可视化
- jQuery 3.6:简化DOM操作
2.2 系统模块划分
系统采用经典的MVC架构,主要模块包括:
| 模块类别 | 包含组件 | 技术实现 |
|---|---|---|
| 用户模块 | 注册/登录/个人中心 | Django Auth系统扩展 |
| 音乐模块 | 歌曲CRUD/分类/标签 | Django Model设计 |
| 推荐模块 | 协同过滤算法 | Python算法实现 |
| 交互模块 | 播放/收藏/评论 | Django视图+AJAX |
| 管理模块 | 数据管理后台 | Django Admin定制 |
3. 核心算法实现
3.1 数据模型设计
推荐系统的数据基础是用户-物品评分矩阵。我们在MySQL中设计了以下关键表:
python复制# 用户评分模型示例
class UserRating(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
song = models.ForeignKey(Song, on_delete=models.CASCADE)
rating = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(5.0)])
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('user', 'song') # 确保用户对同一首歌只有一个评分
3.2 协同过滤算法优化
原始代码中已经展示了基于用户的协同过滤实现,这里补充物品协同过滤的优化版本:
python复制class ItemCFRecommender:
def __init__(self):
self.sim_matrix = None # 物品相似度矩阵
def calculate_similarity(self, data_model):
"""计算物品相似度矩阵,加入IUF权重"""
item_users = data_model.item_user_matrix
item_count = len(item_users)
self.sim_matrix = np.zeros((item_count, item_count))
# 计算共现矩阵
for item1, users1 in item_users.items():
for item2, users2 in item_users.items():
if item1 == item2:
continue
common_users = set(users1.keys()) & set(users2.keys())
if not common_users:
continue
# IUF权重计算
iuf = 1.0 / np.log(1 + len(common_users))
self.sim_matrix[item1][item2] = iuf * len(common_users) / (
np.sqrt(len(users1)) * np.sqrt(len(users2)))
3.3 推荐结果融合策略
实际应用中,我们采用加权混合策略:
- UserCF结果权重:0.4
- ItemCF-IUF结果权重:0.6
- 热门歌曲补全:当个性化推荐不足时,用热门歌曲填充
python复制def hybrid_recommend(user_id, n=10):
user_rec = user_cf.recommend(user_id, n*2)
item_rec = item_cf.recommend(user_id, n*2)
# 去重和加权
hybrid = {}
for song, score in user_rec.items():
hybrid[song] = score * 0.4
for song, score in item_rec.items():
hybrid[song] = hybrid.get(song, 0) + score * 0.6
# 取TopN
recommendations = sorted(hybrid.items(), key=lambda x: x[1], reverse=True)[:n]
# 结果不足时补全
if len(recommendations) < n:
hot_songs = get_hot_songs(n - len(recommendations))
recommendations.extend([(s, 0.8) for s in hot_songs])
return recommendations
4. 关键功能实现细节
4.1 实时推荐接口
在Django中实现推荐API接口:
python复制# views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def get_recommendations(request):
if not request.user.is_authenticated:
return Response({"error": "Authentication required"}, status=401)
n = request.GET.get('n', 10)
try:
n = min(int(n), 20) # 限制最大推荐数
except ValueError:
n = 10
recommendations = hybrid_recommend(request.user.id, n)
serializer = SongSerializer(
[rec[0] for rec in recommendations],
many=True,
context={'request': request}
)
return Response({
'results': serializer.data,
'scores': [rec[1] for rec in recommendations]
})
4.2 播放记录处理
使用Django信号机制实现播放记录自动记录:
python复制# signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from player.models import PlayLog
@receiver(post_save, sender=PlayLog)
def update_song_popularity(sender, instance, created, **kwargs):
if created:
# 更新歌曲热度
song = instance.song
song.play_count += 1
song.save(update_fields=['play_count'])
# 更新用户画像
update_user_profile(instance.user, song)
5. 性能优化实践
5.1 推荐结果缓存
使用Django缓存框架存储推荐结果:
python复制from django.core.cache import cache
def get_cached_recommendations(user_id):
cache_key = f"user_{user_id}_recommendations"
recommendations = cache.get(cache_key)
if not recommendations:
recommendations = hybrid_recommend(user_id)
cache.set(cache_key, recommendations, timeout=3600) # 缓存1小时
return recommendations
5.2 数据库查询优化
针对音乐列表页的N+1查询问题:
python复制# 优化前(产生N+1查询)
songs = Song.objects.filter(type=1)
for song in songs:
print(song.artist.name)
# 优化后(使用select_related)
songs = Song.objects.select_related('artist').filter(type=1)
6. 部署注意事项
6.1 生产环境配置
建议的部署架构:
- Nginx:静态文件服务和反向代理
- Gunicorn:WSGI应用服务器
- Supervisor:进程管理
- MySQL:主从配置(可选)
6.2 安全设置
必须配置的安全项:
python复制# settings.py
SECURE_SSL_REDIRECT = True # 强制HTTPS
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000 # 1年HSTS
7. 项目扩展方向
-
冷启动解决方案:
- 基于音乐元内容的推荐(流派、BPM、情绪等)
- 引入社交关系数据
-
实时推荐改进:
- 使用Kafka处理实时用户行为
- 实现增量更新的协同过滤算法
-
多算法融合:
- 加入基于深度学习的推荐模型
- 强化学习优化推荐策略
经验分享:在实际部署中发现,当用户量超过10万时,传统的协同过滤算法计算开销会急剧增加。这时可以考虑:
- 改用Spark等分布式计算框架
- 采用近邻采样技术减少计算量
- 将相似度矩阵计算改为离线批处理
