Java 實(shí)現(xiàn)協(xié)同過濾算法推薦算法的示例代碼
1. 什么是協(xié)同過濾
協(xié)同過濾主要分為兩種類型:
- 基于用戶的協(xié)同過濾:根據(jù)用戶之間的相似性推薦物品。例如,如果用戶A和用戶B的評分相似,那么用戶A喜歡的物品也可能會被推薦給用戶B。
- 基于物品的協(xié)同過濾:根據(jù)物品之間的相似性進(jìn)行推薦。如果用戶對物品X給出了高評分,且物品Y與X相似,那么物品Y會被推薦給用戶。
2. 數(shù)據(jù)準(zhǔn)備
在實(shí)現(xiàn)協(xié)同過濾之前,我們需要準(zhǔn)備一個(gè)用戶-物品評分矩陣。以下是一個(gè)簡單的示例:
用戶/物品 | 物品1 | 物品2 | 物品3 | 物品4 |
---|---|---|---|---|
用戶A | 5 | 3 | 0 | 1 |
用戶B | 4 | 0 | 0 | 1 |
用戶C | 1 | 1 | 0 | 5 |
用戶D | 0 | 0 | 5 | 4 |
在這個(gè)矩陣中,0表示用戶沒有評分。
3. 基于用戶的協(xié)同過濾實(shí)現(xiàn)
以下是基于用戶的協(xié)同過濾算法的簡單實(shí)現(xiàn):
3.1 計(jì)算相似度
我們將使用余弦相似度來計(jì)算用戶之間的相似度。余弦相似度公式為:
cosine(A,B)=A⋅B∥A∥∥B∥\text{cosine}(A, B) = \frac{A \cdot B}{\|A\| \|B\|}cosine(A,B)=∥A∥∥B∥A⋅B?
3.2 Java 實(shí)現(xiàn)代碼
import java.util.HashMap; import java.util.Map; public class CollaborativeFiltering { // 用戶評分矩陣 private static final Map<String, Map<String, Integer>> ratings = new HashMap<>(); static { ratings.put("UserA", Map.of("Item1", 5, "Item2", 3, "Item4", 1)); ratings.put("UserB", Map.of("Item1", 4, "Item4", 1)); ratings.put("UserC", Map.of("Item2", 1, "Item4", 5)); ratings.put("UserD", Map.of("Item3", 5, "Item4", 4)); } // 計(jì)算余弦相似度 private double cosineSimilarity(Map<String, Integer> ratings1, Map<String, Integer> ratings2) { double dotProduct = 0.0; double normA = 0.0; double normB = 0.0; for (String item : ratings1.keySet()) { if (ratings2.containsKey(item)) { dotProduct += ratings1.get(item) * ratings2.get(item); } normA += Math.pow(ratings1.get(item), 2); } for (double rating : ratings2.values()) { normB += Math.pow(rating, 2); } normA = Math.sqrt(normA); normB = Math.sqrt(normB); return (normA == 0 || normB == 0) ? 0 : dotProduct / (normA * normB); } // 為用戶推薦物品 public Map<String, Double> recommendItems(String user) { Map<String, Integer> userRatings = ratings.get(user); Map<String, Double> scoreMap = new HashMap<>(); for (String otherUser : ratings.keySet()) { if (!otherUser.equals(user)) { double similarity = cosineSimilarity(userRatings, ratings.get(otherUser)); for (String item : ratings.get(otherUser).keySet()) { if (!userRatings.containsKey(item)) { scoreMap.put(item, scoreMap.getOrDefault(item, 0.0) + similarity * ratings.get(otherUser).get(item)); } } } } return scoreMap; } public static void main(String[] args) { CollaborativeFiltering cf = new CollaborativeFiltering(); Map<String, Double> recommendations = cf.recommendItems("UserA"); System.out.println("推薦物品給 UserA: " + recommendations); } }
代碼解釋
- 用戶評分矩陣:使用嵌套的
Map
來存儲用戶對物品的評分。 - 余弦相似度計(jì)算:通過
cosineSimilarity
方法計(jì)算用戶之間的相似度。 - 推薦物品:在
recommendItems
方法中,遍歷所有用戶,計(jì)算相似度并為目標(biāo)用戶推薦未評分的物品。
4. 基于物品的協(xié)同過濾實(shí)現(xiàn)
基于物品的協(xié)同過濾類似于用戶的實(shí)現(xiàn),但我們需要首先計(jì)算物品之間的相似度。
4.1 Java 實(shí)現(xiàn)代碼
import java.util.HashMap; import java.util.Map; public class ItemBasedCollaborativeFiltering { private static final Map<String, Map<String, Integer>> ratings = new HashMap<>(); static { ratings.put("UserA", Map.of("Item1", 5, "Item2", 3, "Item4", 1)); ratings.put("UserB", Map.of("Item1", 4, "Item4", 1)); ratings.put("UserC", Map.of("Item2", 1, "Item4", 5)); ratings.put("UserD", Map.of("Item3", 5, "Item4", 4)); } // 計(jì)算物品之間的余弦相似度 private double cosineSimilarity(Map<String, Integer> item1, Map<String, Integer> item2) { // 與用戶的計(jì)算相似 // 省略相似度計(jì)算的具體實(shí)現(xiàn) return 0.0; // 這里應(yīng)返回實(shí)際計(jì)算的相似度 } // 為用戶推薦物品 public Map<String, Double> recommendItems(String user) { Map<String, Integer> userRatings = ratings.get(user); Map<String, Double> scoreMap = new HashMap<>(); // 計(jì)算物品之間的相似度 // 省略物品相似度計(jì)算和推薦邏輯的實(shí)現(xiàn) return scoreMap; } public static void main(String[] args) { ItemBasedCollaborativeFiltering ibcf = new ItemBasedCollaborativeFiltering(); Map<String, Double> recommendations = ibcf.recommendItems("UserA"); System.out.println("推薦物品給 UserA: " + recommendations); } }
代碼解釋
- 基于物品的實(shí)現(xiàn)邏輯與用戶的類似,只是需要調(diào)整相似度計(jì)算的方式。
- 具體實(shí)現(xiàn)中需要計(jì)算物品評分的相似度,并為用戶推薦相似物品。
5. 結(jié)論
協(xié)同過濾算法是一種強(qiáng)大的推薦技術(shù),能夠根據(jù)用戶的歷史行為和評分為用戶提供個(gè)性化的推薦。在 Java 中實(shí)現(xiàn)協(xié)同過濾算法需要對用戶評分?jǐn)?shù)據(jù)進(jìn)行處理,計(jì)算相似度,并生成推薦結(jié)果。通過上述示例,可以幫助你理解如何在實(shí)際項(xiàng)目中實(shí)現(xiàn)協(xié)同過濾推薦系統(tǒng)。
到此這篇關(guān)于Java 實(shí)現(xiàn)協(xié)同過濾算法推薦算法的文章就介紹到這了,更多相關(guān)java協(xié)同過濾算法推薦算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA OutputStreamWriter流的實(shí)現(xiàn)
OutputStreamWriter是從字符流到字節(jié)流的橋接,它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平臺的默認(rèn)字符集,本文詳細(xì)的介紹了JAVA OutputStreamWriter流的使用,感興趣的可以了解一下2021-06-06Java中IP段轉(zhuǎn)CIDR的原理與實(shí)現(xiàn)詳解
CIDR表示的是無類別域間路由,通常形式是IP地址后跟一個(gè)斜杠和數(shù)字,這篇文章主要為大家介紹了如何使用Java實(shí)現(xiàn)IP段轉(zhuǎn)CIDR,需要的可以了解下2025-03-03selenium + ChromeDriver安裝及使用方法
這篇文章主要介紹了selenium + ChromeDriver安裝及使用方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06Spring Boot拓展XML格式的請求和響應(yīng)操作過程
在我們開發(fā)過程中,我們經(jīng)常使用的參數(shù)絕大多少事HTML和JSON格式的請求和響應(yīng)處理,但是我們在實(shí)際開發(fā)過程中,我們可能經(jīng)歷一些,比如對于XML格式的請求,本文給大家介紹Spring Boot拓展XML格式的請求和響應(yīng),感興趣的朋友一起看看吧2023-10-10java idea如何根據(jù)請求路徑url自動(dòng)找到對應(yīng)controller方法插件
這篇文章主要介紹了java idea如何根據(jù)請求路徑url自動(dòng)找到對應(yīng)controller方法插件,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Maven環(huán)境安裝配置和新建項(xiàng)目介紹
這篇文章介紹了Maven環(huán)境安裝配置和新建項(xiàng)目介紹,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12java中Socket設(shè)置超時(shí)時(shí)間的兩種方式
這篇文章主要介紹了java中Socket設(shè)置超時(shí)時(shí)間的兩種方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11Spring為singleton?bean注入prototype?bean
這篇文章主要介紹了Spring為singleton?bean注入prototype?bean,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07