尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+Vue协同过滤音乐推荐系统源码解析与部署指南

SpringBoot+Vue协同过滤音乐推荐系统源码解析与部署指南 简介一套基于Spring Boot Vue MySQL的协同过滤音乐推荐系统完整源码面向需要全栈实战或理解推荐算法落地的开发者适合课程设计、毕业设计及推荐系统入门学习。项目以Vue搭建前后台界面后端采用Spring Boot与MyBatis开发接口数据库使用MySQL推荐逻辑涵盖用户行为采集、物品或用户相似度计算、结果排序等关键环节便于边读源码边对照算法流程。压缩包共有901个文件大小约34.01MB主干以java后端类、vue页面组件、js脚本、scss样式、xml配置和sql脚本为核心配以240张jpg图片、115段mp3音频、132个js文件与84个vue组件等静态资源基本能支撑音乐网站完整运行与界面还原。目录按controller、service、mapper、dao及前端模块分层组织结构清楚降低上手门槛。已有8687人学习下载解压后可直接获得完整工程、推荐核心代码与MySQL建表脚本方便本地部署、调试和二次扩展。1. 拿到 springbootvue 协同过滤音乐推荐系统源码先学会看货再动手springbootvue 基于协同过滤算法的音乐推荐系统源码.zip这类包几乎每天都在被人搜索。我拆过不少同型项目能一次跑起来的不到三成倒不是代码有多复杂而是环境版本、端口、跨域、数据库编码这些小东西在捣乱。这个包本质上是一套前后端分离的音乐推荐系统后端用 springboot 写数据接口和推荐逻辑前端用 vue 做播放页、榜单页和用户页推荐部分由协同过滤算法完成。对正在做课程设计、毕业设计的同学来说它是很好的参考起点对想入门推荐系统工程的开发者它也能让你看清一个“从评分到推荐”的完整闭环。这篇笔记我按自己拆项目的方式来讲先确认项目结构再把三端跑起来然后深入算法实现最后把常见坑一次说清。2. 项目源码拆解springboot 后端、vue 前端、协同过滤算法各在哪一层拿到 zip 之后先别急着启动先花十分钟把工程结构看清楚。这类项目通常是标准的前后端分离结构后端是一个 Maven 工程前端是一个 Vue 工程两个目录各自独立通过 HTTP 接口通信。算法代码集中在后端的 service 层前端只管展示和交互。搞清楚这三个模块的边界后面调试时就能少走弯路。2.1 从前端到后端的调用链路先知道三个模块的边界页面上的“猜你喜欢”“相似歌曲”“热门榜单”这些功能数据不是凭空来的。前端 vue 组件在 mounted 生命周期里调用 axios 或 fetch请求打到后端 springboot 暴露的 REST 接口后端 controller 层接收请求后调用 service 层service 层里跑协同过滤算法查询数据库里的评分、用户、歌曲数据计算出一批推荐结果返回给前端渲染。链路是“页面 - 前端接口层 - 后端 Controller - Service - Mapper - MySQL”算法只出现在 Service 这一层它不负责存数据只负责算结果。这条链路里最容易搞混的是“推荐结果存在哪”。常见做法是协同过滤算法计算出来的 TopN 歌曲 id 列表直接由接口返回不落库也有的项目会把推荐结果写进一张推荐表方便前端分页查询和后续做效果分析。拿到源码后先看 controller 层有没有一个类似 recommend/getRecommendList 的接口如果直接查库说明算法结果做了持久化如果跑完算法直接 return说明是无状态的实时计算。两种方式各有取舍实时计算逻辑简单但每次请求都重算数据量大时性能吃紧落库方案查询快但需要定时任务或手动触发来更新结果。2.2 目录结构和文件清单拿到 zip 后先看这几个位置展开 zip 之后典型目录结构长下面这样具体包名可能略有出入但套路基本一致music-recommend/ ├── backend/ # springboot 后端工程 │ ├── src/main/java # Java 源码 │ ├── src/main/resources # application.yml、mapper xml │ └── pom.xml # Maven 依赖配置 ├── frontend/ # vue 前端工程 │ ├── src/ # 组件、路由、状态管理 │ ├── package.json │ └── vue.config.js # 开发代理配置 └── sql/ └── music.sql # 建库建表脚本先看几个关键位置一是 pom.xml确认 springboot 版本和依赖组件的版本号二是 application.yml 或 application.properties确认数据库连接配置、端口、JWT 密钥等三是 sql 脚本确认数据库里到底有哪些表四是 vue 前端的 package.json确认依赖版本和启动脚本。这四样东西直接决定你能不能顺利启动。pom.xml 里我最关心的是 springboot parent 版本和 mybatis、mysql-connector 的版本。很多项目跑不起来是因为 mysql-connector-java 的坐标在 Spring Boot 2.7 之后从 mysql:mysql-connector-java 变成了 com.mysql:mysql-connector-j如果你看到的是旧坐标在 2.7 版本上会直接报依赖找不到。vue 前端则要注意 vue-cli 版本和 node 版本是否匹配这也是一个高频爆炸点。拿到包先核对版本比闷头启动快得多。2.3 数据库表设计评分数据、用户数据、歌曲数据怎么存协同过滤算法需要三类数据用户、物品、用户对物品的评分。在音乐推荐场景里物品就是歌曲评分可能是一张独立的评分表也可能用播放次数、收藏状态、搜索行为折算而来。常见表设计如下表名核心字段作用userid, username, password, nickname用户信息songid, name, singer, album, duration, cover_url, audio_url歌曲元数据ratingid, user_id, song_id, score, create_time用户对歌曲的显式/隐式评分collectid, user_id, song_id, create_time收藏记录可折算为评分play_recordid, user_id, song_id, play_count播放次数统计rating 表是整个推荐系统的核心数据源。score 的取值范围常见的是 1 到 5也有项目用 0 到 10如果只有收藏表没有评分表那算法层就需要把“是否收藏”映射成 1 和 0 的隐式评分。拿到 sql 脚本后先看 rating 表里有没有造好的测试数据数据量直接决定推荐效果——如果表里只有十几行数据协同过滤算出来的结果基本是乱的。另外注意 sql 脚本的字符集。音乐类数据涉及大量中文歌名、歌手名如果建表语句里没有指定 utf8mb4导入后很容易出现中文乱码推荐算法本身不依赖歌名计算但前端页面显示出来的全是乱码观感很差。3. 把源码跑起来环境、命令、配置与参数说明这一章的目标是把三个进程全部拉起来MySQL 数据库、springboot 后端、vue 前端。每一步都给出具体命令和参数说明照着做就能跑通。不同机器的环境差异很大所以第一步先统一版本。3.1 环境准备JDK、Node、MySQL 版本怎么选这类项目对环境的敏感度极高版本不对连编译都过不去。我一般按下面的标准来准备组件推荐版本说明JDK1.8 或 11取决于 pom.xml 里的 java.version很多课程设计源码停留在 1.8Maven3.6IDEA 自带可用命令行需确认 settings.xml 有镜像Node.js14.x 或 16.xvue-cli 4/5 对 node 版本敏感高版本 node 容易踩坑详见第五章MySQL5.7 或 8.05.7 最稳8.0 需要处理时区和驱动坐标IDEIDEA 2021前端用 VSCode 也行后端建议 IDEA编译信息明确先看 pom.xml 里 spring-boot-starter-parent 的版本号。如果是 2.x 且 java.version 是 1.8就老老实实用 JDK 8如果强行用 JDK 17 编译大概率会碰到 maven-compiler-plugin 报错。前端方面先看 package.json 里是否使用了 vue-cli-service如果是node 14 或 16 最稳node 20 会在安装和构建时报 OpenSSL 错误。这些都属于“可以绕过但没必要”的问题把版本对齐能省下大量调试时间。3.2 初始化数据库导入 SQL 的完整命令与常见失败点先创建数据库实例再导入项目自带的 sql 脚本。假设 SQL 文件在 sql/music.sqlMySQL 用户名为 root执行命令如下mysql -u root -p -e CREATE DATABASE IF NOT EXISTS music_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; mysql -u root -p music_db sql/music.sql第一条命令创建数据库并指定字符集为 utf8mb4防止中文乱码第二条命令把建表语句和测试数据导入。执行完成后用下面这条命令确认 rating 表的数据量数据量太少会影响后续推荐效果mysql -u root -p -e USE music_db; SELECT COUNT(*) FROM rating;导入失败时先看两个地方一是 sql 脚本开头有没有 CREATE DATABASE 语句如果有第二条命令就不需要指定库名否则会双重建库二是脚本里是否包含 DROP TABLE 语句课程设计的 sql 脚本经常在开头写 DROP TABLE IF EXISTS如果你不想覆盖已有数据导入前要手动删掉。再检查一下 application.yml 里的数据库配置注意 url 参数中的 serverTimezoneMySQL 8.0 默认使用 UTC 时区不配置时区会导致连接报错。常见配置如下spring: datasource: url: jdbc:mysql://127.0.0.1:3306/music_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driverdriver-class-name 在 MySQL 8.0 下必须写成 com.mysql.cj.jdbc.Driver写成旧驱动 com.mysql.jdbc.Driver 也能启动但会在日志里出现弃用警告部分高版本 springboot 会直接启动失败。3.3 启动 springboot 后端IDEA 与命令行两种启动方式后端启动有两种方式。第一种是 IDEA 图形化操作导入 backend 目录为 Maven 工程等待依赖下载完成后找到带有 SpringBootApplication 注解的主类右键直接 Run。第二种是命令行启动适合脚本化部署cd backend mvn clean package -DskipTests java -jar target/music-recommend-0.0.1-SNAPSHOT.jar第一条命令把项目编译成可执行 jar 包-DskipTests 跳过单元测试避免测试代码不通过导致打包失败。第二条命令启动 jar启动成功后日志里会打印 Tomcat started on port(s): 8080。如果端口被占用在 application.yml 中修改 server.port 配置比如改成 8090。提示IDEA 首次导入 Maven 工程时如果 pom.xml 里有依赖无法下载检查 Maven 配置的镜像源国内环境建议使用阿里云镜像。依赖下载卡死是常见现象不要反复重启 IDEA优先检查 settings.xml 里的 mirror 配置。后端启动时要注意一个问题springboot 项目会加载自定义过滤器或拦截器。有的源码里带了 XSS 过滤、JWT 登录拦截如果你不登录直接调推荐接口会被拦截器拦下返回 401。调试时先看后端日志如果出现 Interceptor 相关输出说明需要先请求登录接口拿 token再在请求头里带上 Authorization 字段。这不算 bug是权限设计的正常行为但首次排查时会让人误以为后端没起来。3.4 启动 vue 前端npm 依赖安装、代理配置与端口说明前端启动分三步安装依赖、配置代理、启动服务。先执行依赖安装cd frontend npm install npm run devnpm install 的耗时常驻选手一要看网络二要看依赖版本。如果报 ERESOLVE 错误第五章细说如果只报了 warning一般不影响启动。npm run dev 启动后终端会打印访问地址常见的是 http://localhost:3000 或 http://localhost:8081取决于 package.json 里的 scripts 配置是 vue-cli-service serve 还是 vite。此时打开页面如果白屏且控制台满是接口报错说明代理没配好。vue 项目通常把后端接口地址写死在代码里或者通过代理转发避免跨域。常见的 vue.config.js 配置如下const { defineConfig } require(vue/cli-service) module.exports defineConfig({ devServer: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: /api } } } } })这段配置的意思是前端运行在 3000 端口所有以 /api 开头请求都由 devServer 转发到后端的 8080 端口。changeOrigin: true 会修改请求头中的 Host 字段防止后端反代校验失败。如果前端请求接口时使用 /api/user/login而后端 controller 的映射路径是 /user/login就需要在 pathRewrite 里把 /api 去掉改成 pathRewrite: { ^/api: }反之如果后端接口路径本身就带 /api 前缀就保持原样不重写。这个参数不对前端会直接 404。如果项目不是用 vue-cli 而是用 vite配置在 vite.config.js 里写法略有差异export default { server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } } }vite 的 rewrite 和 webpack 的 pathRewrite 作用相同都是路径重写。把代理配置好之后前端页面能正常拿到接口数据整个系统就算跑起来了。4. 协同过滤算法在项目里是怎么实现的从评分矩阵到 TopN 推荐协同过滤是标题里的核心词也是这个项目的灵魂。很多初学者把启动成功当成任务完成但面试或答辩时被问到“推荐结果怎么算出来的”就卡住了。这一章把算法讲的透一点数据从哪来、相似度怎么算、推荐列表怎么生成。4.1 用户评分数据从哪来把收藏、播放、打分折算成评分矩阵协同过滤的输入是“用户-物品评分矩阵”矩阵的行是用户列是歌曲值表示用户对歌曲的喜好程度。项目里如果只有一张打分表直接查出来填入矩阵即可如果项目没有显式评分表而是靠收藏和播放来判断喜好就需要数据折算。折算公式通常长这样SELECT user_id, song_id, CASE WHEN score IS NOT NULL THEN score WHEN collect_count 0 THEN 5 ELSE 1 play_count / 5 END AS final_score FROM user_song_behavior这段 SQL 的优先级是有显式评分用显式评分有收藏记录直接给最高分 5否则按播放次数折算成 1 到 5 的分数。折算规则没有唯一标准不同项目差异很大但只要语义自洽就行播放越多、收藏过的歌曲分值越高。拿到评分数据之后后端 Java 代码里会把这些数据组装成一个 Map 结构key 是用户 idvalue 是另一个 Map内部存储歌曲 id 到评分的映射。这个结构在内存里就等价于评分矩阵。矩阵大多数情况是稀疏的一个用户听过的歌只占全量曲库的很小比例所以用 HashMap 存储比二维数组更合适这也是项目源码里最常见的数据结构选择。4.2 基于用户的协同过滤怎么算余弦相似度与预测评分基于用户的协同过滤核心思想是“找到和你口味相似的人把这些人喜欢的歌推荐给你”。步骤是先计算用户之间的相似度再根据相似用户的评分预测你对某首歌的偏好。用户相似度常见用余弦相似度公式是两个用户评分向量夹角的余弦值值越接近 1 越相似。核心实现逻辑可以用一段 Java 伪代码说明真实项目里结构也类似// 根据用户评分数据计算两个用户的余弦相似度 public double cosineSimilarity(MapLong, Double userRatingsA, MapLong, Double userRatingsB) { double dotProduct 0; // 点积 double normA 0; // A 向量模长 double normB 0; // B 向量模长 for (Map.EntryLong, Double entry : userRatingsA.entrySet()) { normA entry.getValue() * entry.getValue(); if (userRatingsB.containsKey(entry.getKey())) { dotProduct entry.getValue() * userRatingsB.get(entry.getKey()); } } for (Double value : userRatingsB.values()) { normB value * value; } if (normA 0 || normB 0) return 0; return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); }代码逻辑是从评分矩阵中取两个用户的评分向量先计算点积再计算各自的模长最后相除得到余弦值。注意点只算两个用户都评过分的歌曲只有单方面评分的项对点积无贡献。参数上要注意normA 和 normB 为 0 的场景要返回 0否则会除零异常。这个边界常见于只有收藏行为折算评分、且某个用户没有任何行为记录的情况。算出用户相似度后需要选取 TopK 个相似用户然后聚合他们听过的歌曲计算目标用户对每首歌的预测评分。预测评分常见做法是对相似用户的评分做加权求和权重就是相似度。这一步会额外过滤掉目标用户已经听过的歌曲然后按预测分排序取前 N 首这就是“猜你喜欢”的完整流程。源码里通常会把 TopK 和 TopN 定义成常量方便调整比如取 10 个相似用户、推荐 20 首歌。4.3 基于物品的协同过滤怎么算歌曲相似度与“喜欢这个也喜欢那个”基于物品的协同过滤在音乐场景里更常见因为歌曲数量远大于用户数量且相对稳定物品相似度可以预先计算好线上推荐时响应更快。它的核心是“如果大量用户同时收藏或播放了歌曲 A 和歌曲 B那么 A 和 B 相似”。物品相似度的主流计算方式不是简单套余弦公式而是用改进后的余弦相似度计算时减去用户平均分以消除不同用户打分习惯的影响。实际项目里由于歌曲数据量不大直接存相似度矩阵没有问题。计算完成后推荐阶段给用户推荐的是“与用户听过的歌相似、但用户没听过”的歌。// 根据用户行为统计两首歌同时被喜欢的次数并计算相似度 public MapLong, Double getSimilarSongs(Long songId) { MapLong, Double result new HashMap(); // 伪代码遍历该歌曲的相似度存储结构取出 songId 对应的相似项 // result.put(similarSongId, similarityScore); return result; }这段代码只是结构示意真实项目中 computeItemSimilarity 会遍历所有用户的评分列表统计歌曲共现次数代价是 O(用户数 × 歌曲数)所以大多数系统不会在请求时实时计算而是在项目启动时预加载或者用定时任务离线算好存表。看到源码里在 PostConstruct 或 ApplicationRunner 里跑算法的基本都是这个思路。ItemCF 的优点是推荐结果可解释性强“因为你在听 A所以推荐和 A 相似的 B”前端可以直接展示这个理由缺点是偏向热门歌曲小众人群的推荐多样性差。UserCF 则更适合冷启动阶段用户行为很少时也能通过相似用户找到候选集。4.4 混合策略与冷启动新用户、新歌曲的兜底推荐协同过滤有天然的冷启动问题新用户没有任何行为数据相似用户算不出来新歌曲没有用户评分无法进入候选集。项目源码里通常不会只依赖纯协同过滤而是加一层兜底逻辑。常见做法是新用户或行为数据不足 5 条的用户直接按热度排序返回热门歌曲新歌曲则被赋予一个初始分定期参与随机曝光。混合策略实现时优先判断条件如果用户评分数小于阈值走热门榜逻辑否则走协同过滤逻辑。这种方式代码简单效果稳定也能保证新用户打开首页时有内容可看。如果你想让推荐效果更好可以把基于内容的推荐根据歌曲的风格、歌手标签计算相似度和协同过滤的结果做加权融合比重可以手动调。源码没有覆盖这部分的话可以自己扩展这也是很多毕业设计项目选择增加打磨的地方。5. 拿源码跑通前后的避坑记录现象、原因、解决这一章写的是我拆同类型项目时反复踩过的坑。每一条都按“现象 - 原因 - 解决”的顺序给出来照着排查能省出大把时间。5.1 Node 版本太高npm install 报 ERESOLVE 或编译失败现象npm install 执行到一半报错提示 ERESOLVE unable to resolve dependency tree或者安装完成后 npm run dev 编译失败报 opensslErrorStack 和 digital envelope routines unsupported。原因node 17 默认使用了 OpenSSL 3.0和旧版 webpack 的哈希算法不兼容同时 vue-cli 旧版本依赖解析逻辑与 npm 7 冲突node 版本越高越容易触发这两类问题。源码里的 vue 项目是旧版本脚手架生成的它没有跟上生态变化。解决别去改 package.json也别换构建工具最省事的就是把 node 切回 16.x。用 nvm 管理 node 版本执行 nvm install 16.20.2 nvm use 16.20.2清掉 node_modules 重新 npm install。如果你不想切换全局 node也可以在启动命令前临时设置 NODE_OPTIONS--openssl-legacy-provider env但这是临门一脚的补救日常开发还是建议切回稳定兼容版本。5.2 MySQL 8.0 时区问题数据库连接失败、启动即抛异常现象后端启动时日志刷出 Communications link failure或者报 The server time zone value ʱ is unrecognized一大段英文异常看到人发懵。原因MySQL 8.0 默认时区是 UTC而 JDBC 驱动在连接时默认要用本地时区做时间换算两边对不上就报错。出现乱码提示通常是系统本地时区不是标准时区名驱动无法识别。解决修改数据源 url末尾拼接 serverTimezoneAsia/Shanghai这是最直接的做法。如果你用的是连接池配置注意有些版本的 druid 会覆盖 url 参数需要同时检查 spring.datasource.druid.url 是否也要改。另外 MySQL 8.0 需要配套 mysql-connector-java 8.x 驱动坐标要确认正确。5.3 前后端跨域问题接口 200 但页面拿不到数据现象浏览器 F12 里能看到接口请求返回 200但控制台报 CORS error前端拿不到 response 数据。或者接口直接 OPTIONS 请求后就没有后续了。原因前端和后端不在同一个端口下浏览器根据“协议 域名 端口”判断是否跨域。就算代理配了也有可能因为代理路径和后端接口路径不匹配导致请求实际没有发到后端。解决优先修 devServer 的 proxy不要在后端开全局跨域。全局跨域有两种后遗症一是所有接口都暴露给任意域名不安全二是如果后端代码里做了自定义 CORS 过滤器会和 Spring 自带的跨域处理重复产生更隐蔽的问题。在 vue.config.js 中确认代理 target 的端口与后端 server.port 一致确认 pathRewrite 后的路径与后端 RequestMapping 路径一致。两个配置对不上请求就飞了。5.4 vue 路由 history 模式刷新后 404现象从前端首页跳转到推荐页正常但手动刷新浏览器或者直接访问 http://localhost:3000/recommend 时页面变成 404 或者白屏。原因vue-router 开启了 history 模式路由路径是前端虚拟路径没有真实对应的后端文件。刷新时 devServer 尝试查找 /recommend 这个静态路径找不到就 404。这是所有 SPA 项目的通病不是代码 bug。解决开发环境最简单的方式是改用 hash 模式路由路径变成 /#/recommend这样不需要服务端配置刷新永远能找到 index.html。但如果你拿的是课程设计源码不想改路由那就得把 devServer 配置成 historyApiFallback告诉 devServer 在所有路径找不到时都返回 index.html。生产部署时还要在 Nginx 里配置 try_files $uri $uri/ /index.html这一步是最常被漏掉的。5.5 端口占用与上下文路径不一致后端日志正常前端仍然 502现象后端日志显示 Tomcat started on port(s): 8080前端代理也指向 8080但页面请求还是报 502 或 ERR_CONNECTION_REFUSED。原因一类是 8080 端口被其他进程占用后端起的是 8081日志里往下翻能看到真正的端口另一类是后端配置了 server.servlet.context-path比如 /music此时接口完整路径是 /music/api/user/login前端代理却只配了 /api于是请求落到不存在的路径上被网关拒了。解决启动时看清楚 Spring Boot 启动日志里的端口和上下文路径。前端代理配置 target 只负责管协议、IP、端口不管路径前缀context-path 必须体现在 pathRewrite 里。如果有 context-path正确做法是代理 target 设成 http://localhost:8080不要带 /music然后 pathRewrite 去掉 /api 前的部分或者让前端所有请求统一以 /music/api 开头。路径前缀搞错时最明显的特征是前端报 404 而不是 502如果报 502 基本是端口或代理 target 的问题。6. 从“能交作业”到“能上线”进阶改造的三个方向跑通只是第一步真正值得投入的方向是把它改成一个“推荐逻辑合理、能应对真实数据”的系统。我做完这类项目后通常会做三个改造。6.1 把隐式反馈折算成评分而不是只依赖打分表真实场景里主动打分的用户非常少绝大多数行为是播放、收藏、搜索。直接把这些行为折算成评分比空着一张 rating 表强得多。折算规则我用的是加权求和播放一次记 1 分收藏记 8 分搜索点击记 3 分设置一个衰减窗口把三个月前的行为分数打六折。折算后的分数不是简单 sum而是一个综合权重。实现上可以用 SQL 聚合也可以在 service 层汇总数据量上来后建议落到一张 user_item_score 表每天定时刷新。6.2 热点惩罚与多样性让推荐结果不总是那几首纯协同过滤有个明显问题热门歌曲被推荐的频率过高推荐列表里来来去去都是那些高播放歌曲。冷门但符合用户口味的歌曲很难浮上来。我常用的一种做法是给热门歌曲加惩罚系数公式大致是 score * (1 / (1 log2(popularity)))热度越高的歌曲相似度权重被拉得越低。另一种做法是在候选集里强制插入一定比例的随机歌曲这个比例我一般控制在 10% 到 20%保证结果有新鲜感。6.3 离线计算 缓存把相似度矩阵从启动时计算改为定时任务课程设计项目通常在 ApplicationRunner 里里面对整个评分矩阵做全量重算用户几百人、歌曲几百首时无所谓用户量上万后启动耗时和内存都会成为问题。要想让它能扛住真实数据就把相似度计算改成定时任务用 Scheduled 每天凌晨算一次结果写入 Redis 或 MySQL 的相似度表推荐接口运行时只查缓存不再重新计算。这样接口响应时间可以从几百毫秒降到几十毫秒代价只是推荐结果最长有一天的延迟。对音乐推荐这种场景来说一天内的口味变化没那么明显完全可接受。改造过程中最常被忽略的是监控。跑通项目之后建议先做一件事把用户真实点击了推荐位的结果收集起来统计推荐位点击率。推荐系统不是做了就完了它需要持续看数据效果。我自己在这个阶段踩过的最大教训是花大量时间调算法参数效果不如先把用户行为日志收集干净再按点击率反馈做迭代。行为数据的质量决定了算法的上限越早意识到这一点越好。这套方案从头到尾并不复杂胜在边界清晰适合把每个环节吃透希望帮到你。本文还有配套的精品资源点击获取
返回列表