同過濾:Java電影推薦系統(tǒng)源碼解析與部署指南)
簡介基于SSM與Vue實現(xiàn)的一套電影推薦系統(tǒng)源碼面向需要完成課程設計、畢業(yè)設計或入門SSM前后端分離項目的開發(fā)者涉及Spring、SpringMVC、MyBatisPlus、MySQL、Maven等多個主流技術框架。項目圍繞用戶信息、圖片素材與視頻素材等核心模塊完整覆蓋從數(shù)據(jù)庫設計、數(shù)據(jù)接口實現(xiàn)到前端頁面展示的流程并從可行性分析、系統(tǒng)設計到實際編碼均有體現(xiàn)可作為電影推薦管理系統(tǒng)的直接參考方案。壓縮包共845個文件、約17.62MB以Java后端代碼、Vue組件、JS腳本、HTML頁面和CSS樣式為主另含SQL數(shù)據(jù)庫腳本、Maven配置及環(huán)境啟動腳本導入Eclipse或IDEA配合MySQL5.7即可運行調試。目前已有282人學習包內同時提供環(huán)境構建腳本、設計文檔和項目說明可幫助快速梳理用戶管理、電影信息維護、素材展示等模塊的開發(fā)思路適合需要一套可直接復現(xiàn)的SSMVue項目資料。1. 這份電影推薦系統(tǒng)源碼到底能干什么先說結論這是一個用 Java SSMSpring SpringMVC MyBatis寫的 Web 電影推薦管理系統(tǒng)前后端不分離JSP 頁面渲染數(shù)據(jù)庫用 MySQL。它不是我見過最花哨的項目但它是那種「拿過來能跑、能改、能寫進簡歷、能當畢設」的典型代表。你拿到的資源里包含完整源碼、SQL 建表腳本和部署說明。系統(tǒng)核心不是簡單做 CRUD而是實現(xiàn)了一套基于物品的協(xié)同過濾推薦引擎用戶登錄、用戶對電影打分之后系統(tǒng)會基于「喜歡電影 A 的人也喜歡電影 B」的邏輯算出相似電影列表并推給當前用戶。除了推薦模塊后臺還有電影管理、用戶管理、評分管理、輪播圖管理這些常規(guī)功能。什么人適合下載如果你正在找 Java Web 課設或畢設題目或者想研究 SSM 整合和協(xié)同過濾推薦在實際項目里怎么落地這份源碼是很好的參照物。它不涉及 Spring Boot用的是偏傳統(tǒng)的 SSM 配置方式恰恰是很多課程還在教、面試還在問的那一套。下面我按「算法與數(shù)據(jù)怎么設計 → 部署怎么做 → 坑在哪 → 怎么改得更好」的順序把這套系統(tǒng)完整拆一遍你照著走完就能跑起來。2. 推薦算法與數(shù)據(jù)模型基于物品的協(xié)同過濾選型與五張表設計這部分我先講算法為什么選型再落到數(shù)據(jù)庫表和代碼實現(xiàn)。推薦模塊是這套系統(tǒng)的靈魂如果只是增刪改查那它和普通管理系統(tǒng)的區(qū)別就沒了如果你想把推薦邏輯改掉第一步得先把數(shù)據(jù)模型吃透。2.1 為什么選基于物品的協(xié)同過濾而不是基于用戶推薦系統(tǒng)最常見的兩個方向是按用戶相似度推薦UserCF和按物品相似度推薦ItemCF。這套源碼選的是 ItemCF也就是基于物品的協(xié)同過濾。我傾向于認為這是對的尤其是對電影這類物品數(shù)量相對穩(wěn)定、用戶數(shù)量會持續(xù)增長的業(yè)務模型。ItemCF 的核心思想是先找用戶和歷史行為的關系算出電影之間的相似度再根據(jù)用戶已經看過的電影去推薦相似電影。它和 UserCF 的區(qū)別在于UserCF 是要找到和你品味相似的人把這個人看過的而你沒看過的電影推薦給你ItemCF 則是找到你已看過的電影的相似品推薦給用戶。為什么更適合電影網(wǎng)站因為用戶的興趣變化相對慢而電影的「鄰居關系」是比較穩(wěn)定的。再加上電影這種物品的用戶行為矩陣很稀疏絕大多數(shù)用戶只看過幾百部電影中的幾十部UserCF 計算用戶相似度時矩陣太稀疏結果不穩(wěn)定ItemCF 只需要為目標電影找 Top-K 個相似電影這個計算是離線可以預處理的在線推薦時只需查表即可。這套系統(tǒng)的實現(xiàn)方式是在 Java 服務啟動時加載評分數(shù)據(jù)內存里直接算好每個電影的相似列表存入緩存。用戶請求推薦接口時拉取用戶自己的評分記錄將這些電影的各相似電影按相似度加權求和排序后返回 Top-N。2.2 數(shù)據(jù)庫表五張基礎表覆蓋業(yè)務閉環(huán)這套系統(tǒng)跑起來之后MySQL 里會自動建出的核心表是五張我建議你拿到源碼先看一遍 SQL 腳本對字段千萬別懶著不看。它們的職責分布是表名職責關鍵字段user用戶表id, username, password, nickname, avatar, typemovie電影表id, title, cover, director, actors, description, publish_date, scorerating評分表id, user_id, movie_id, rating_score, create_timecategory或 type電影分類表id, namenotice / carousel公告或輪播圖表id, content, image_url, create_time需要注意 rating 表是推薦算法的主數(shù)據(jù)源。它存儲的是用戶對某部電影的打分字段名字可能在不同版本里叫 score 或 rating_score但邏輯一樣user_id 和 movie_id 聯(lián)合起來不能重復這約束了同一用戶對同一電影只能有一個評分。movie 表里的 score 字段不是用戶的評分而是電影自身的綜合評分后臺管理員錄入的初始值或者系統(tǒng)加權計算出的展示分。這個字段很容易混淆很多初學者會直接把 movie.score 當成用戶評分傳給推薦算法導致相似度計算完全失真。后面避坑章節(jié)我會再強調一次。2.3 相似度計算余弦相似度的 Java 實現(xiàn)與參數(shù)說明代碼包里和推薦算法相關的核心類通常是RecommendService或ItemCFService我按這套系統(tǒng)最可能的實現(xiàn)方式給你拆解。以下是基于物品的協(xié)同過濾中計算電影相似度的核心代碼// 根據(jù)用戶評分數(shù)據(jù)構建“電影-用戶”倒排表 public MapInteger, ListInteger buildItemUserMap() { // key: movieId, value: 對該電影評過分的userId列表 MapInteger, ListInteger itemUserMap new HashMap(); ListRating ratings ratingMapper.selectAll(); for (Rating r : ratings) { itemUserMap.computeIfAbsent(r.getMovieId(), k - new ArrayList()).add(r.getUserId()); } return itemUserMap; } public MapInteger, ListSimilarMovie calcSimilarity() { MapInteger, ListInteger itemUserMap buildItemUserMap(); ListInteger movieIds new ArrayList(itemUserMap.keySet()); MapInteger, ListSimilarMovie simMap new HashMap(); for (int i 0; i movieIds.size(); i) { ListInteger usersA itemUserMap.get(movieIds.get(i)); for (int j i 1; j movieIds.size(); j) { ListInteger usersB itemUserMap.get(movieIds.get(j)); // 取兩個電影評分用戶集合的交集 SetInteger intersection new HashSet(usersA); intersection.retainAll(usersB); if (intersection.size() 2) { continue; // 共同評分的用戶太少相似度沒有統(tǒng)計意義 } double sim cosineSimilarity(usersA, usersB); // 雙向寫入相似關系只保留Top-K控制內存占用 simMap.computeIfAbsent(movieIds.get(i), k - new ArrayList()) .add(new SimilarMovie(movieIds.get(j), sim)); simMap.computeIfAbsent(movieIds.get(j), k - new ArrayList()) .add(new SimilarMovie(movieIds.get(i), sim)); } } // 每部電影的相似列表按相似度降序截斷為TOP_N simMap.values().forEach(list - { list.sort((a, b) - Double.compare(b.getSimilarity(), a.getSimilarity())); if (list.size() TOP_N) list.subList(TOP_N, list.size()).clear(); }); return simMap; }這段代碼有兩個關鍵參數(shù)。TOP_N控制相似列表保留多少個鄰居默認 10 到 20 之間為好。設太小推薦結果的多樣性不夠設太大會讓后續(xù)的加權聚合計算變慢而且相似度排名靠后的電影貢獻很小。intersection.size() 2這個過濾條件是常見的工程處理如果兩部電影只有一個共同評分用戶那說明兩個電影之間并沒有穩(wěn)定的「共同偏好」支撐保留這個相似度會引入大量噪聲。2.4 推薦結果生成根據(jù)用戶評分加權聚合相似度算完推薦的第二步是把用戶評分過的電影作為「種子」聚合它們的相似電影得到最終推薦列表。核心邏輯是用戶給電影 A 打了 5 分A 和電影 B 的相似度是 0.8那么 B 獲得一個候選分 5 × 0.8 4.0。public ListMovie recommendForUser(Integer userId, int topN) { // 1. 拉取該用戶的歷史評分評分3分的電影作為種子 ListRating userRatings ratingMapper.selectByUserId(userId); MapInteger, Double seedMovieScores new HashMap(); for (Rating r : userRatings) { if (r.getRatingScore() 3.0) { seedMovieScores.put(r.getMovieId(), r.getRatingScore()); } } if (seedMovieScores.isEmpty()) { // 冷啟動無評分時退化為返回熱度榜避免列表空洞 return movieMapper.selectHotMovies(topN); } // 2. 聚合候選電影 所有種子電影相似列表的并集 MapInteger, Double candidateScoreMap new HashMap(); for (Map.EntryInteger, Double seed : seedMovieScores.entrySet()) { ListSimilarMovie similarList similarityCache.get(seed.getKey()); if (similarList null) continue; for (SimilarMovie sm : similarList) { if (seedMovieScores.containsKey(sm.getMovieId())) { continue; // 過濾掉用戶已經看過的 } double rawScore sm.getSimilarity() * seed.getValue(); // 同一個電影來自多個種子的得分做累加 candidateScoreMap.merge(sm.getMovieId(), rawScore, Double::sum); } } // 3. 排序并截斷 return candidateScoreMap.entrySet().stream() .sorted((a, b) - Double.compare(b.getValue(), a.getValue())) .limit(topN) .map(entry - movieMapper.selectById(entry.getKey())) .collect(Collectors.toList()); }這里需要注意過濾已看過的電影這步必須在聚合之后、排序之前做否則種子電影自己會排到榜首。閾值選 3.0 是我調試時常用的默認值低于 3 分的電影通常意味著用戶不喜歡把它作為推薦種子反而會推薦出用戶討厭的類型。給用戶的推薦頁可以同時展示三個列表猜你喜歡、相似電影、熱門榜單前兩個來自這套算法高情商的頁面設計會把沒有評分的新注冊用戶先引導到熱門榜上而不是讓他對著空列表發(fā)呆。3. 從源碼到運行環(huán)境要求、建庫配置與啟動鏈路源碼能下載是一回事能跑起來是另一回事。這個項目對新手來說存在一些不動手根本發(fā)現(xiàn)不了的隱性要求。我先按照「環(huán)境 → 建庫 → 改配置 → 啟動」這條鏈路把完整流程走一遍再單獨把啟動過程中常見的故障點集中講透。3.1 環(huán)境版本組合JDK 8 Tomcat 8.5 MySQL 5.7我先說版本組合這是因為 SSM 項目對版本非常敏感。這套源碼是 Maven 工程pom.xml 里的依賴版本大概鎖定在比較保守的區(qū)間Spring 4.x 或 5.x、MyBatis 3.4 左右。我建議你用下面的組合去準備環(huán)境組件版本理由JDK1.8SSM 項目原生基于 JDK 8 編譯用 JDK 11 可能出現(xiàn)反射或字節(jié)碼增強問題Tomcat8.5支持 Servlet 3.1兼容項目 web.xml 配置Tomcat 9 對部分舊配置更嚴格MySQL5.7與 MyBatis 的 SQL 寫法兼容性最好8.0 的認證插件會導致驅動連接失敗Maven3.6構建工具版本過老可能拉不到依賴IntelliJ IDEA2020配置 Tomcat 和部署 war 包更方便有兩點容易踩。MySQL 8.0 是重災區(qū)如果你用 8.0必須把驅動換成mysql-connector-java 8.0.x并且 url 后面要加useSSLfalseserverTimezoneAsia/Shanghai。T8.0 的 caching_sha2_password 認證插件是舊版驅動不認的。另外 Tomcat 版本如果高于 9JSP 編譯依賴的 javax.servlet 包名會有兼容性變化項目里舊的 EL 表達式寫法可能直接取不到值。3.2 建庫導入 SQL 腳本三條命令搞定初始化源碼包里應該包含一個movie.sql或db_movie.sql腳本文件。用下面的方式導入即可# 登錄本地MySQLroot用戶 mysql -u root -p # 在MySQL命令行中執(zhí)行 CREATE DATABASE IF NOT EXISTS movie_db DEFAULT CHARACTER SET utf8mb4; USE movie_db; SOURCE /your/path/movie.sql; # 查看是否導入成功 SHOW TABLES;這里SOURCE的路徑必須用正斜杠Windows 下也如此否則 MySQL 會報語法錯誤。utf8mb4這個字符集不是可選項——如果表結構里原本是 utf8遇到 emoji 或冷門中文名稱會存入失敗。導入完成后重點確認 rating 表里有數(shù)據(jù)或者執(zhí)行一條統(tǒng)計 SQL 查看各表行數(shù)如果發(fā)現(xiàn) user 表有數(shù)據(jù)但 rating 表是空的推薦接口是調不出結果的后面我會解釋這是最常見的一個翻車點。3.3 修改配置jdbc.properties 與 Maven 依賴接著打開src/main/resources/jdbc.properties數(shù)據(jù)庫連接配置改成你自己的本地環(huán)境jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/movie_db?useUnicodetruecharacterEncodingutf-8useSSLfalse jdbc.usernameroot jdbc.passwordyourpassword這里驅動類名值得說一句。如果用的是 MySQL 5.7 mysql-connector-java 5.1.x驅動類名是com.mysql.jdbc.Driver如果換了 MySQL 8.0 8.0 驅動必須改成com.mysql.cj.jdbc.Driver否則啟動日志會給出ClassNotFoundException。characterEncodingutf-8是必填參數(shù)不寫的話亂碼問題幾乎百分百出現(xiàn)而且亂碼會貫穿從 JSP 頁面到數(shù)據(jù)庫的全鏈路。pom.xml 里如果缺少某項依賴Maven 會在編譯時報錯。建議先執(zhí)行一次mvn clean package -DskipTests確認所有依賴能順利拉取這樣可以把「代碼問題」和「環(huán)境問題」分開排查。如果項目里有本地lib目錄的 jar 包記得確認 IDE 是否正確引用了這是很多從網(wǎng)盤下載的源碼里被忽略的問題——構建時 Maven 報包找不到實際上 jar 就放在 lib 下。3.4 部署啟動IDEA 配置 Tomcat 的完整步驟我不在這里展開 IDEA 的每個點擊步驟只把最關鍵的三步寫清楚。第一步Project Structure 里把 Artifacts 設為 war exploded 模式而不是 war 包模式war exploded 允許熱部署 JSP 和 Java 文件修改代碼后不用反復重啟整個項目。第二步Run Configuration 里添加 Tomcat Server LocalDeployment 面板把項目 artifact 部署上去Application context 建議設為/movie這樣可以避免根路徑下的靜態(tài)資源沖突。第三步啟動前確認 Tomcat 的 VM options 里沒設置奇怪的-Dfile.encoding否則 JSP 中文輸出可能有隱藏的編碼坑。啟動成功后瀏覽器訪問http://localhost:8080/movie。到這里系統(tǒng)的登錄、注冊、電影列表、電影詳情、評分功能應該全部可用。如果首頁能打開但推薦列表為空問題幾乎都出在數(shù)據(jù)或算法觸發(fā)條件上這是下一章要細講的內容。3.5 推薦鏈路驗證怎樣確認推薦真的在生效服務起來以后想要確認推薦模塊真的在工作有一個簡單的驗證路徑。注冊一個新用戶給三五部電影打高分然后打開「猜你喜歡」頁面。如果頁面上出現(xiàn)了你沒打過分、但和你打過分的電影類型相近的電影說明推薦鏈路是通的。更好的是直接查日志。推薦接口的 Service 通常會打印用戶種子電影數(shù)和候選電影數(shù)看到seed3 candidate45這類信息就能確定算法層的輸入輸出正常。如果打了分但日志里seed0一定是評分數(shù)據(jù)沒有被 Service 拿到「查一下是不是用錯了 mapper 方法」是這類問題最直接的排查方向。4. 避坑指南四類高頻問題與排查路徑這一章寫的是我在反復部署這類 SSM 源碼項目時踩過的坑每條都按「現(xiàn)象 → 原因 → 解決」來講。你對照著排能省下大量瞎試時間。4.1 登錄后推薦頁空白或 500 報錯現(xiàn)象首頁能打開登錄也正常但進入推薦頁直接白屏后端日志報 NullPointerException指向 RecommendService 里的某一行業(yè)務代碼。原因推薦模塊的相似度計算在啟動時沒有成功完成或者說緩存的similarityCache是空的。常見誘因有兩個一是 rating 表數(shù)據(jù)為空算法沒有輸入自然沒法產出二是 MovieMapper 的查詢字段名和實體類屬性沒對應上比如數(shù)據(jù)庫字段是publish_date實體里是publishDateMyBatis 默認自動映射下駝峰轉下劃線沒啟用導致查出來的對象是半空的。解決先查數(shù)據(jù)庫確認 rating 表有數(shù)據(jù)SELECT COUNT(*) FROM rating;。然后檢查 mybatis-config.xml 里是否配置了setting namemapUnderscoreToCamelCase valuetrue/。沒配置的話要么加這個配置要么在 SQL 里顯式使用別名比如SELECT publish_date AS publishDate FROM movie。4.2 注冊用戶后推薦列表全是熱門電影而非個性化推薦現(xiàn)象無論哪個用戶登錄推薦頁展示的都是同一批電影看起來就是按熱度排的。原因這套系統(tǒng)的推薦設計里有冷啟動退化邏輯當用戶沒有評分時返回熱門榜。如果所有用戶看到的東西都一樣而且你確認這些用戶明明打過評分那要檢查推薦入口是否真的調用了推薦接口。有時頁面直接渲染了默認列表熱門榜推薦接口根本沒有被調用。解決看瀏覽器的 Network 面板或后端日志確認「猜你喜歡」板塊的 Ajax 請求是否發(fā)到了recommend接口。如果發(fā)到了但返回內容仍是熱門榜就查用戶評分是否真正寫入了數(shù)據(jù)庫——HTTP 200 不等于事務已提交檢查評分表單提交后是否調用了 ratingMapper.insert 并確認userId是當前登錄用戶而不是默認的 1。4.3 中文亂碼頁面亂碼和數(shù)據(jù)庫亂碼同時出現(xiàn)現(xiàn)象電影標題在頁面上顯示為問號或方格MySQL 里存進去的中文也是亂碼。原因三層編碼不一致。JSP 頁面沒指定 UTF-8Tomcat 接收 POST 請求時 URIEncoding 沒配置數(shù)據(jù)庫連接的 characterEncoding 沒加。解決JSP 頂部加上% page contentTypetext/html;charsetUTF-8 languagejava %MySQL 的 url 加characterEncodingutf-8Tomcat 的 server.xml 里 Connector 配置加上URIEncodingUTF-8。這三處都改好后重啟 Tomcat把表的字符集也統(tǒng)一用ALTER TABLE movie CONVERT TO CHARACTER SET utf8mb4;這樣比較穩(wěn)妥。4.4 MySQL 8.0 連接失敗Access denied 或 Public Key Retrieval 錯誤現(xiàn)象項目啟動時提示Access denied for user rootlocalhost或者連接 MySQL 時報Public Key Retrieval is not allowed。原因MySQL 8.0 默認的認證插件是 caching_sha2_password舊版的 5.x 驅動不認識。如果 root 密碼是空或者用了老密碼也會導致相同報錯。解決兩個方案任選。方案一把 pom.xml 里的 mysql-connector-java 版本換成 8.0.xurl 加allowPublicKeyRetrievaltrueuseSSLfalse。方案二在 MySQL 里把 root 用戶的認證插件改回 mysql_native_passwordALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY yourpassword;。我建議方案一因為改插件會有其他兼容性隱患而且 8.0 驅動是向前兼容 5.7 的。5. 再進一步加上時間衰減和用戶行為權重讓推薦列表真正變可用基礎版協(xié)同過濾能跑通是一回事但如果你把這份源碼當成畢業(yè)設計或上線項目去打磨你會發(fā)現(xiàn)還有三個值得優(yōu)化的方向。它們是推薦系統(tǒng)從「能演示」走向「可用」的分水嶺我把具體做法和代碼給你寫出來。5.1 時間衰減讓三個月前的評分和昨天的評分權重不同基礎版算法里用戶的每個評分權重是完全一樣的。實際上三個月前的評分和昨天的評分對用戶當前興趣的反映程度是不同的所以推薦結果里容易出現(xiàn)「舊片堆砌」的問題——用戶看過的老電影和相似老電影長期霸榜新上架的電影永遠沒機會被推薦。常見做法是給評分加一個時間衰減因子比如衰減權重decay Math.pow(0.95, daysFromToday / 7.0)表示每過一周權重降低 5%。把算好的權重乘到種子評分的 value 上去。實現(xiàn)非常簡單核心代碼不超過十行。在recommendForUser方法里拿到 Rating 對象后多讀一個createTime字段計算天數(shù)差然后在聚合時把 rawScore 乘上衰減因子。這樣同比兩部電影近期評分貢獻的推薦分更高推薦列表會跟隨用戶近期口味變化而不是永遠停留在注冊頭一個月的觀影記錄上。配合這個改動數(shù)據(jù)庫里 publish_date 字段就有了實用價值電影相似度相同或接近時讓發(fā)布時間更新的電影排名靠前這也是解決冷門新片很難被發(fā)現(xiàn)的標配手法。ORDER BY publish_date DESC不是簡單地在最后排一下而是把它以很小的權重比如 0.01 系數(shù)加進排序分數(shù)否則會讓相似度計算失去主導權。5.2 行為權重擴展不只依賴評分把收藏和瀏覽也納入用戶偏好這套系統(tǒng)有評分接口但通常還有收藏或想看功能。如果你有收藏表或瀏覽歷史表可以將它們轉成隱性反饋不需要用戶主動給分。單次瀏覽算 0.5 分收藏算 2 分評分算實際分數(shù)。這樣即使用戶只是隨便逛逛、沒打幾分也能積累足夠的行為種子。尤其是新注冊用戶讓他一上來先看到熱門榜收藏兩三部動作片之后立刻就能看到動作片方向的推薦這個體驗遠勝于等用戶打完 5 部電影才出結果。5.3 評測方法離線切分評測集量化推薦效果很多畢業(yè)設計只講到「推薦出來了」就停了面試官一問「效果好不好」就答不上來。這個問題推薦系統(tǒng)有標準解法離線評測。把用戶評分按時間排序前 80% 當訓練集后 20% 當測試集。用訓練集數(shù)據(jù)重新計算相似度和預測分看預測的 Top-N 電影里有多少出現(xiàn)在測試集的實際評分記錄里。-- 按用戶分組按時間排序把最后一條評分作為測試集 -- 訓練數(shù)據(jù)該用戶其他評分為訓練集 SELECT user_id FROM rating GROUP BY user_id HAVING COUNT(*) 5;這種切分方式比隨機切分更接近真實場景因為它是按時間前后模擬預測未來行為。算出準確率PrecisionN和召回率RecallN就能成為論文里的核心數(shù)據(jù)指標。調參時重點看兩個方向TOP_N值設到多少時準確率下降、覆蓋率上升以及時間衰減系數(shù)設成 0.95 還是 0.90 時推薦列表里的新片占比是否有明顯差異。這組實驗數(shù)據(jù)拿出來和你簡歷上的「實現(xiàn)推薦系統(tǒng)」相比說服力好得多。5.4 一個讓推薦列表更像產品的小技巧最后說一個改動量很小但體驗提升很大的點在推薦結果的渲染層去重和打散。算相似度時我已經做了 Top-K 截斷但多路推薦合并猜你喜歡 相似電影 熱門榜會出現(xiàn)同一部電影在多個列表里重復出現(xiàn)。前端展示時先把所有候選合并成一個 Map按類型或導演做一次去重再在結果里插入一定比例的隨機熱門電影。這樣可以避免推薦列表里的前幾條全是同一系列的電影——否則用戶會覺得系統(tǒng)根本沒在推薦只是把自己看過的系列又列了一遍。從那以后我每次部署完推薦系統(tǒng)都要強制走一遍三件事先看數(shù)據(jù)庫評分數(shù)據(jù)分布確認種子不是全空的再人為構造一個「只看過動作片」的用戶來驗證個性化方向的區(qū)分度最后把推薦接口掛上日志跑一周看看實際推薦為空的次數(shù)占多大比例。這套驗證習慣能幫你早點發(fā)現(xiàn)問題而不是上線后讓用戶自己暴露問題。希望幫到你。本文還有配套的精品資源點擊獲取