简介:本资源是一套完整的Python高分毕业设计项目,面向计算机专业本科生及Python初学者,聚焦推荐系统核心算法实践,解决电影信息过载场景下的个性化推荐问题。资源包含可直接运行的协同过滤推荐系统源码、万字技术论文、全流程操作视频演示、MySQL数据库脚本及配套文档,覆盖从算法实现、Django前后端开发到系统部署的全链路学习需求。压缩包共690个文件,21.8MB,含38个核心Python模块(含协同过滤算法逻辑与Django视图)、162个SVG图标与30个PNG/JPG素材(用于前端界面)、162个JS与33个Vue组件(构建响应式管理后台)、51个CSS样式文件及2个SQL数据库脚本,结构清晰、模块解耦,支持管理员与用户双角色操作。目前已有58人学习下载,资源经本地严格调试,评审得分超95分,附带安装/运行/构建批处理脚本(.bat)及多份备份与配置文件(.bak/.ini/.yml),显著降低环境配置门槛与排错成本。
1. 项目概述与核心价值
最近在整理过往的课程设计和毕业设计资料时,翻出了一个当年让我印象深刻的“大作业”——一个完整的电影推荐系统。这个项目之所以能拿高分,不仅仅是因为它功能完整,更重要的是它把一个听起来高大上的“推荐算法”实实在在地落地了,从数据爬取、算法实现、前后端交互到最后的论文撰写和演示,走完了一个完整的数据产品开发流程。如果你正在为你的Python课程设计、数据挖掘大作业或者毕业设计寻找一个既有技术深度又有展示效果的课题,这个基于Python和协同过滤算法的电影推荐系统,绝对是一个值得深入研究和复现的经典案例。
简单来说,这个系统就是一个模拟的“电影版豆瓣”。用户可以在上面注册、登录,对看过的电影进行1-5星的评分。系统后台会收集这些评分数据,运用协同过滤算法,分析出用户之间的相似性或者电影之间的相似性,从而为当前用户预测他可能感兴趣但尚未看过的电影,并生成一个个性化的推荐列表。整个项目麻雀虽小,五脏俱全:它用Python的Flask或Django框架搭建Web后端,用MySQL或SQLite存储用户、电影、评分数据,用Pandas、NumPy进行数据处理,用Scikit-learn或者自写算法实现核心的推荐逻辑,最后通过一个简洁的前端页面展示出来。完成这样一个项目,你不仅能巩固Python Web开发、数据库操作的知识,更能深入理解推荐系统这个AI热门应用领域的基础原理,这份经历写在简历里也是相当有分量的。
2. 系统整体架构与设计思路拆解
2.1 为什么选择协同过滤算法?
做推荐系统,算法选型是第一道坎。主流算法有基于内容的推荐、协同过滤、矩阵分解以及深度学习模型等。对于一个大作业或入门项目,协同过滤(Collaborative Filtering, CF)几乎是必然选择。原因有三:第一,原理直观,易于理解。它的核心思想就是“物以类聚,人以群分”,要么找到和你口味相似的用户,把他们喜欢的东西推荐给你(User-Based CF);要么找到和你喜欢过的物品相似的物品推荐给你(Item-Based CF)。这种逻辑非常符合人的直觉。第二,它不依赖于物品本身的属性(如电影的类型、导演、演员),只依赖用户的历史行为数据(评分),这在数据获取上门槛较低,我们只需要用户-物品的评分矩阵即可。第三,实现起来相对简单,有清晰的数学步骤(计算相似度、寻找近邻、生成预测),非常适合用Python的数值计算库来实现,是教学和入门实践的绝佳载体。
在我们的电影推荐系统中,通常会优先实现并对比基于用户的协同过滤(UserCF)和基于物品的协同过滤(ItemCF)。UserCF更适合用户数量相对稳定、兴趣变化较慢的场景;而ItemCF则因为物品的相似度相对稳定,可预先计算,更适合用户数量庞大、兴趣变化快的场景。对于电影推荐,两者都可以尝试,通过实验对比效果,这本身就能成为你论文中的一个重要章节。
2.2 技术栈选型背后的考量
一个完整的系统离不开技术栈的支撑。下面这个选型表是基于稳定、易学、社区资源丰富原则的经典组合:
| 组件 | 推荐技术 | 选型理由 |
|---|---|---|
| 后端框架 | Flask / Django | Flask轻量灵活,适合快速构建API;Django功能全面,自带ORM和Admin,适合需要复杂管理的项目。大作业更推荐Flask,能让你更清晰地理解每个模块。 |
| 数据库 | MySQL / SQLite | MySQL是生产级关系型数据库,学习它有益无害。SQLite是文件型数据库,无需安装服务器,部署极其简单,非常适合原型演示。 |
| 数据处理 | Pandas, NumPy | 处理评分矩阵、计算相似度、进行向量运算的绝对主力。它们的接口高效且符合直觉。 |
| 算法实现 | Scikit-learn / 自实现 | 使用Scikit-learn的cosine_similarity等函数可以快速完成相似度计算。但为了深入理解,我强烈建议至少自实现一次核心的相似度计算和预测评分步骤。 |
| 前端展示 | HTML/CSS/JS + Bootstrap | 无需复杂的前端框架,用Bootstrap可以快速搭建一个整洁美观的界面,将主要精力放在后端逻辑和算法上。 |
| 数据源 | MovieLens数据集 | 推荐系统领域的标准数据集,包含用户、电影、评分信息,质量高且免费,避免了自行爬取数据的法律和稳定性风险。 |
注意:很多同学想用爬虫抓取豆瓣等网站的实时数据。这虽然更“真实”,但会引入反爬、数据清洗格式不统一、法律风险等诸多问题,极易让项目卡在数据准备阶段。对于以算法学习和工程实现为目标的大作业,强烈建议直接使用MovieLens公开数据集,它能让你快速进入核心环节。
2.3 系统核心模块设计
整个系统可以划分为五个松耦合的模块,这样设计便于开发、调试和后期扩展:
- 数据模块:负责连接数据库,定义用户(User)、电影(Movie)、评分(Rating)等数据模型,并提供增删改查的接口。
- 算法模块:这是系统的“大脑”。包含数据加载、评分矩阵构建、相似度计算(如余弦相似度、皮尔逊相关系数)、近邻筛选、评分预测等核心函数。
- 服务模块(Web后端):基于Flask/Django,提供RESTful API。例如:
/api/register(注册),/api/login(登录),/api/rate(提交评分),/api/recommend(获取推荐列表)。 - 展示模块(Web前端):简单的页面,用于用户注册登录、浏览电影、进行评分、查看个人推荐列表。
- 评估模块:用于离线测试算法效果。通常将数据集按比例划分为训练集和测试集,在训练集上训练模型,在测试集上计算预测评分与实际评分的误差(如均方根误差RMSE、平均绝对误差MAE),以量化推荐质量。
3. 核心算法原理与实现细节解析
3.1 协同过滤的数学基础与步骤
协同过滤的核心是评分矩阵和相似度计算。假设我们有m个用户和n部电影,那么评分矩阵R就是一个m行n列的矩阵,其中R[i][j]代表用户i对电影j的评分(如果未评分则为空)。
基于用户的协同过滤(UserCF)步骤如下:
- 构建评分矩阵:将数据库中的评分记录转换为一个用户-电影评分矩阵。对于缺失值(用户未评分的电影),通常先进行简单填充,如用该用户的平均分或全局平均分。
- 计算用户相似度:这是最关键的一步。最常用的方法是余弦相似度和皮尔逊相关系数。
- 余弦相似度:将每个用户看作一个n维向量(对n部电影的评分),计算两个用户向量夹角的余弦值。值越接近1,兴趣越相似。
import numpy as np from sklearn.metrics.pairwise import cosine_similarity # 假设 user_ratings 是一个二维数组,每一行是一个用户的评分向量 user_sim_matrix = cosine_similarity(user_ratings) - 皮尔逊相关系数:衡量两个用户评分趋势的线性相关性。它考虑了用户评分尺度的差异,比余弦相似度更常用。
from scipy.stats import pearsonr # 计算用户u和用户v的皮尔逊相关系数,需要处理共同评分的电影 common_movies = np.where((ratings[u] > 0) & (ratings[v] > 0))[0] if len(common_movies) > 1: # 需要有共同评分项 sim = pearsonr(ratings[u][common_movies], ratings[v][common_movies])[0] else: sim = 0 # 或一个默认值
- 余弦相似度:将每个用户看作一个n维向量(对n部电影的评分),计算两个用户向量夹角的余弦值。值越接近1,兴趣越相似。
- 寻找最近邻:对于目标用户u,根据相似度排序,选出最相似的K个用户作为“邻居”(K值需要调优,通常取20-50)。
- 生成评分预测:预测用户u对电影i的评分。公式为加权平均:
预测评分 = 用户u的平均分 + (∑ [邻居v与u的相似度 * (v对i的评分 - v的平均分)]) / ∑ |邻居v与u的相似度|这个公式的本质是:用邻居们的“评分偏差”(相对于他们自己的平均分)的加权平均,来修正目标用户自己的平均分。 - 生成推荐列表:对目标用户所有未评分的电影进行预测评分,按预测分从高到低排序,取Top-N部电影作为推荐结果。
基于物品的协同过滤(ItemCF)逻辑类似,只是将“用户-电影”矩阵转置为“电影-用户”矩阵,然后计算电影之间的相似度(看哪些用户同时对两部电影打了高分),最后根据用户历史喜欢的电影,推荐与之相似的其他电影。
3.2 算法实现中的关键技巧与坑点
1. 相似度计算的优化:直接计算所有用户两两之间的相似度,时间复杂度是O(m²),当用户数上万时计算量巨大。在实际项目中,我们需要优化:
- 稀疏矩阵存储:评分矩阵非常稀疏(一个用户只评过极少电影),使用
scipy.sparse库的CSR或CSC格式存储,能极大节省内存和计算时间。 - 向量化计算:尽量使用NumPy/Pandas的向量化操作,避免Python层的for循环。例如,用
cosine_similarity函数一次性计算整个矩阵。 - 分块或采样:对于超大数据集,可以考虑对用户进行聚类后分块计算,或者对候选邻居进行采样。
2. 冷启动问题:对于新用户(没有任何评分历史)或新电影(没有被任何用户评分),协同过滤完全失效。这是它的固有缺陷。在大作业中,你可以提出一些简单的解决方案作为论文的“展望”部分,例如:
- 热门推荐:给新用户推荐当前评分最高、观看次数最多的热门电影。
- 基于内容的混合推荐:为新电影提取关键词、类型等属性,当协同过滤失效时, fallback 到基于内容的推荐(计算电影属性相似度)。
3. 评分预测的细节:
- 分母为零处理:在预测公式中,如果所有相似邻居都没有对电影i评分,分母求和为零,会导致计算错误。必须增加判断,此时可直接返回用户u的平均分。
- 相似度负数处理:皮尔逊相关系数可能为负,表示兴趣相悖。在加权平均时,通常只考虑正相似度的邻居,或者将负相似度视为0。
实操心得:在第一次实现时,不要追求大规模和高性能。先用一个很小的数据集(比如MovieLens 100k),用最直观的for循环把算法流程跑通,得到正确的预测结果。验证逻辑正确后,再逐步引入稀疏矩阵、向量化计算进行优化。这个“先正确,再高效”的过程非常重要。
4. 系统工程实现与代码组织
4.1 数据库设计与模型定义
良好的数据库设计是系统的基石。我们至少需要三张核心表:
-- 用户表 CREATE TABLE `user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) UNIQUE NOT NULL, `password_hash` VARCHAR(128) NOT NULL, -- 务必存储哈希值,而非明文! `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 电影表 (数据可从MovieLens导入) CREATE TABLE `movie` ( `id` INT PRIMARY KEY, -- 可使用MovieLens自带的movieId `title` VARCHAR(255) NOT NULL, `genres` VARCHAR(255), -- 类型,如 'Adventure|Animation|Children' `release_year` INT, `imdb_id` VARCHAR(20) ); -- 评分表 CREATE TABLE `rating` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `user_id` INT NOT NULL, `movie_id` INT NOT NULL, `rating` FLOAT NOT NULL CHECK (rating >= 0.5 AND rating <= 5.0), -- 通常为0.5-5的步进 `timestamp` BIGINT, FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE, FOREIGN KEY (`movie_id`) REFERENCES `movie`(`id`) ON DELETE CASCADE, UNIQUE KEY `unique_rating` (`user_id`, `movie_id`) -- 防止同一用户对同一电影重复评分 );在Python中,我们可以使用ORM(对象关系映射)库如SQLAlchemy(搭配Flask)或Django ORM来定义这些模型,这样就能用Python类的方式来操作数据库,更加安全和方便。
4.2 后端API服务搭建(以Flask为例)
Flask的轻量特性使其非常适合构建这种系统的API层。下面是一个极简的结构示例:
movie_recommendation_system/ ├── app.py # Flask应用主入口 ├── config.py # 配置文件(数据库连接等) ├── requirements.txt # 项目依赖 ├── models.py # 数据库模型定义(使用Flask-SQLAlchemy) ├── cf_algorithms.py # 协同过滤算法实现 ├── utils.py # 工具函数(如加载数据、评估指标) ├── routes/ │ ├── auth.py # 认证相关路由:注册、登录 │ ├── movie.py # 电影相关路由:列表、详情 │ └── recommend.py # 推荐相关路由:提交评分、获取推荐 └── static/ & templates/ # 前端静态文件和模板(如果不用前后端分离)核心API接口示例 (app.py或routes/recommend.py):
from flask import Flask, request, jsonify from models import db, User, Rating, Movie from cf_algorithms import user_based_cf_predict # 导入算法函数 app = Flask(__name__) # ... 配置数据库等初始化代码 ... @app.route('/api/recommend', methods=['GET']) def get_recommendations(): """为当前登录用户获取电影推荐列表""" # 1. 获取当前用户ID (通常从session或JWT token中) current_user_id = get_current_user_id() if not current_user_id: return jsonify({'error': 'Unauthorized'}), 401 # 2. 从数据库加载所有评分数据,构建评分矩阵 # 这里可以优化:缓存评分矩阵,避免每次请求都全量查询数据库 all_ratings = Rating.query.all() # 将all_ratings转换为 pandas DataFrame 或字典格式,供算法使用 ratings_data = load_ratings_to_matrix(all_ratings) # 3. 调用协同过滤算法,生成推荐电影ID列表及预测评分 # top_n 参数控制返回推荐数量 recommended_movies_with_score = user_based_cf_predict(current_user_id, ratings_data, top_n=10) # 4. 根据电影ID查询电影详细信息 movie_ids = [item[0] for item in recommended_movies_with_score] movies = Movie.query.filter(Movie.id.in_(movie_ids)).all() # 将查询结果与预测评分合并,并按评分排序 results = [] for movie in movies: pred_score = next(score for mid, score in recommended_movies_with_score if mid == movie.id) results.append({ 'id': movie.id, 'title': movie.title, 'genres': movie.genres.split('|') if movie.genres else [], 'predicted_rating': round(pred_score, 2) }) results.sort(key=lambda x: x['predicted_rating'], reverse=True) # 5. 返回JSON格式的推荐列表 return jsonify({'recommendations': results}) @app.route('/api/rate', methods=['POST']) def submit_rating(): """用户对电影进行评分""" data = request.get_json() user_id = data.get('user_id') movie_id = data.get('movie_id') rating_value = data.get('rating') # 验证数据有效性... # 查找或创建评分记录 rating = Rating.query.filter_by(user_id=user_id, movie_id=movie_id).first() if rating: rating.rating = rating_value else: rating = Rating(user_id=user_id, movie_id=movie_id, rating=rating_value) db.session.add(rating) db.session.commit() # 评分更新后,可以异步触发更新用户的推荐缓存(如果需要) # update_user_recommendation_cache(user_id) return jsonify({'success': True, 'message': 'Rating submitted.'})4.3 前端界面与交互实现
前端的目标是清晰直观。我们可以用Bootstrap快速搭建几个页面:
- 登录/注册页:简单的表单。
- 电影浏览页:以卡片形式展示电影海报、标题、类型和平均评分。提供搜索和过滤功能。
- 电影详情页:展示电影详细信息,并有一个五星评分组件,用户点击后调用
/api/rate接口。 - 个人推荐页:展示系统为用户生成的Top-N推荐电影列表,并显示预测评分。
交互的核心是通过JavaScript(或jQuery、Axios)调用后端API。例如,评分提交的JS代码:
// 假设使用jQuery $('.star-rating').on('click', function() { let movieId = $(this).data('movie-id'); let rating = $(this).data('rating-value'); $.ajax({ url: '/api/rate', method: 'POST', contentType: 'application/json', data: JSON.stringify({user_id: currentUserId, movie_id: movieId, rating: rating}), success: function(response) { alert('评分成功!'); // 可选:刷新推荐列表 fetchRecommendations(); }, error: function(xhr) { alert('评分失败: ' + xhr.responseJSON.error); } }); });5. 项目进阶:从实现到优化与评估
5.1 离线评估:你的算法到底好不好?
实现算法只是第一步,量化评估其性能才能体现工作的严谨性。我们采用离线实验的方法:
- 数据集划分:将完整的用户-电影评分数据随机划分为训练集(如80%)和测试集(20%)。确保每个用户在训练集和测试集中都有记录。
- 训练:在训练集上运行协同过滤算法,构建模型(即计算好用户相似度矩阵或物品相似度矩阵)。
- 预测:对于测试集中的每一个评分记录(用户u,电影i,真实评分r),我们用训练好的模型去预测用户u对电影i的评分p。
- 计算指标:比较预测值p和真实值r的差异。最常用的两个指标是:
- 均方根误差(RMSE):
RMSE = sqrt(mean((p - r)^2))。它对大的预测误差惩罚更重。 - 平均绝对误差(MAE):
MAE = mean(|p - r|)。更直观地反映预测误差的平均大小。
- 均方根误差(RMSE):
- 对比分析:你可以计算UserCF和ItemCF的RMSE/MAE,对比哪种算法在该数据集上表现更好。还可以尝试调整K(近邻数量)、相似度计算方法等超参数,观察指标变化,找到最优组合。
import numpy as np from sklearn.model_selection import train_test_split def evaluate_model(ratings_df, algo_func, test_size=0.2): """评估推荐算法模型""" # 划分训练集和测试集 train_data, test_data = train_test_split(ratings_df, test_size=test_size, random_state=42) # 在训练集上训练/拟合模型 (例如,计算相似度矩阵) model_params = algo_func.fit(train_data) predictions = [] truths = [] # 对测试集的每一条记录进行预测 for _, row in test_data.iterrows(): user_id = row['user_id'] movie_id = row['movie_id'] true_rating = row['rating'] # 使用训练好的模型进行预测 pred_rating = algo_func.predict(user_id, movie_id, model_params, train_data) if pred_rating is not None: # 确保可以预测 predictions.append(pred_rating) truths.append(true_rating) # 计算指标 predictions = np.array(predictions) truths = np.array(truths) rmse = np.sqrt(np.mean((predictions - truths) ** 2)) mae = np.mean(np.abs(predictions - truths)) return rmse, mae, len(predictions)5.2 性能优化与工程化思考
当系统从Demo走向可用时,性能问题就会凸显:
- 实时性:每次请求推荐都全量计算相似度和预测是不可接受的。解决方案是离线计算+缓存。可以设置一个定时任务(如每天凌晨),为所有用户预计算好推荐列表,并存入缓存(如Redis)或数据库的推荐表中。当用户请求时,直接读取缓存结果,实现毫秒级响应。
- 可扩展性:用户和电影数量增长后,内存中的全量评分矩阵会放不下。需要考虑更高级的算法,如矩阵分解(Matrix Factorization),其代表是奇异值分解(SVD)及其变种(如FunkSVD, BiasSVD)。这些算法可以将高维稀疏的评分矩阵分解为低维的用户隐因子矩阵和物品隐因子矩阵,大大降低了存储和计算复杂度,并且往往能取得比传统协同过滤更好的效果。使用
surprise库可以很方便地实现这些高级算法。 - 系统部署:完整的项目需要部署到服务器。可以使用Docker将你的Flask应用、MySQL数据库打包成容器,用Nginx做反向代理,用Gunicorn管理Python进程。编写
docker-compose.yml一键部署,这会是项目的一个巨大亮点。
5.3 论文撰写与演示准备
对于大作业或毕业设计,文档和演示与代码同等重要。
论文结构建议:
- 摘要与引言:阐述推荐系统的背景、意义,以及本项目的主要工作和创新点。
- 相关技术综述:介绍协同过滤算法(UserCF, ItemCF)的原理、发展,以及所用技术栈(Python, Flask等)。
- 系统需求分析与设计:包括功能性需求(用户管理、评分、推荐)和非功能性需求(性能、可用性),以及系统架构图、模块设计、数据库设计。
- 核心算法实现与优化:详细阐述你实现的协同过滤算法的步骤、公式、关键代码(可贴核心片段),以及你做的任何优化(如稀疏矩阵、相似度计算优化)。
- 系统实现与测试:展示系统主要界面截图,描述前后端交互流程。给出离线评估的实验设置、结果(RMSE/MAE表格或图表),并对结果进行分析。
- 总结与展望:总结项目成果,分析不足之处(如冷启动、可扩展性),并提出可能的改进方向(如引入矩阵分解、深度学习模型、混合推荐等)。
视频演示要点:录制一个5-10分钟的演示视频,内容应流畅连贯:
- 开场:简要介绍项目目标和功能。
- 功能演示:以一个新用户视角,完整走一遍流程:注册 -> 登录 -> 浏览电影并对几部电影评分 -> 查看“我的推荐”页面,展示系统根据新评分实时(或触发更新后)生成的个性化推荐列表。
- 后台说明:可以切换到命令行或简单的管理界面,展示数据库中的评分记录变化,或者运行一下离线评估脚本,展示评估指标。
- 结尾:总结演示,再次强调系统的核心价值。
6. 常见问题排查与开发心得
在实际开发中,你几乎一定会遇到下面这些问题:
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 推荐结果全是热门电影,没有个性化 | 1. 新用户评分太少。 2. 算法中的K值设置过大或相似度计算有问题,导致近邻失去代表性。 3. 未处理评分矩阵的稀疏性,预测时有效邻居过少。 | 1. 为新用户设置默认推荐策略(如热门电影、随机电影)。 2. 调整K值(尝试10, 20, 50),检查相似度计算代码,确保共同评分项足够。 3. 在预测前,检查为目标用户和候选电影找到的有效邻居数,如果太少,则fallback到全局热门推荐。 |
| 算法运行速度极慢,页面超时 | 1. 使用Python原生列表和循环进行全量矩阵计算。 2. 每次请求都从数据库加载全部数据并重新计算。 | 1.必须使用NumPy向量化操作和SciPy稀疏矩阵。将评分数据一次性读入内存的稀疏矩阵中。 2.实施缓存:将用户相似度矩阵、物品相似度矩阵甚至用户推荐列表进行离线计算和缓存。 |
| 预测评分出现NaN或异常值(如>5或<0.5) | 1. 预测公式中分母为零未处理。 2. 相似度计算出现异常(如标准差为零导致皮尔逊相关系数为NaN)。 | 1. 在预测函数中加入严格的判断:if sum_of_similarities == 0: return user_mean_rating。2. 在计算相似度时,过滤掉共同评分项少于2个的用户对或物品对,并将NaN相似度置为0。 |
| 前端提交评分后,推荐列表不更新 | 1. 前端评分提交成功,但未触发推荐列表刷新。 2. 后端是离线计算推荐,新评分未纳入实时计算。 | 1. 在前端AJAX评分成功的回调函数中,主动调用一次获取推荐列表的API并更新DOM。 2. 如果后端是离线模式,可以提示用户“推荐列表将在下次更新时刷新”,或设计一个“更新我的推荐”按钮,手动触发一次轻量级的实时计算(仅针对该用户)。 |
| 数据库连接失败或操作超时 | 1. 数据库服务未启动。 2. 连接字符串配置错误。 3. 并发操作时连接未正确管理。 | 1. 检查MySQL/SQLite服务状态。 2. 核对配置文件中的主机、端口、用户名、密码、数据库名。 3. 使用Web框架的ORM(如SQLAlchemy)管理数据库会话(Session),确保请求结束后连接被正确释放。 |
最后的个人体会:完成这个项目最大的收获不是学会了某个库的调用,而是打通了“数据 -> 算法 -> 工程 -> 产品”的完整链路。它让你明白,一个有效的推荐系统不仅仅是调包实现一个算法,更需要考虑数据质量、系统实时性、用户体验和可维护性。从自己手写相似度计算时对循环的优化,到第一次看到RMSE随着K值变化而下降时的兴奋,再到前端点击评分后推荐列表实时变化的成就感,每一步都是实实在在的成长。如果你能在此基础上,进一步尝试用surprise库实现SVD,或者用Docker-compose把整个系统部署到云服务器上,那这份大作业的含金量将会再上一个台阶。
本文还有配套的精品资源,点击获取