本文目录导读:

我来提供一个完整的Java协同过滤推荐系统案例,包含基于用户的协同过滤和基于物品的协同过滤两种算法。
项目结构
src/main/java/com/recommend/
├── RecommendationSystem.java // 主类
├── model/
│ ├── UserRating.java // 用户评分模型
│ └── Recommendation.java // 推荐结果模型
├── algorithm/
│ ├── UserBasedCF.java // 基于用户的协同过滤
│ └── ItemBasedCF.java // 基于物品的协同过滤
└── util/
└── SimilarityUtil.java // 相似度计算工具
完整代码实现
数据模型类
package com.recommend.model;
import java.util.HashMap;
import java.util.Map;
/**
* 用户评分模型
*/
public class UserRating {
// 用户ID -> 物品ID -> 评分
private Map<String, Map<String, Double>> userRatings;
public UserRating() {
this.userRatings = new HashMap<>();
}
/**
* 添加用户评分
* @param userId 用户ID
* @param itemId 物品ID
* @param rating 评分(1-5分)
*/
public void addRating(String userId, String itemId, double rating) {
userRatings.computeIfAbsent(userId, k -> new HashMap<>())
.put(itemId, rating);
}
/**
* 获取用户的所有评分
*/
public Map<String, Double> getUserRatings(String userId) {
return userRatings.getOrDefault(userId, new HashMap<>());
}
/**
* 获取所有用户
*/
public Map<String, Map<String, Double>> getAllUserRatings() {
return userRatings;
}
/**
* 获取用户评分
*/
public double getRating(String userId, String itemId) {
Map<String, Double> ratings = userRatings.get(userId);
if (ratings != null && ratings.containsKey(itemId)) {
return ratings.get(itemId);
}
return 0; // 表示没评分
}
/**
* 获取所有评价过某个物品的用户
*/
public Map<String, Double> getItemRatings(String itemId) {
Map<String, Double> itemUsers = new HashMap<>();
for (Map.Entry<String, Map<String, Double>> entry : userRatings.entrySet()) {
String userId = entry.getKey();
Map<String, Double> ratings = entry.getValue();
if (ratings.containsKey(itemId)) {
itemUsers.put(userId, ratings.get(itemId));
}
}
return itemUsers;
}
/**
* 获取所有物品
*/
public java.util.Set<String> getAllItems() {
java.util.Set<String> items = new java.util.HashSet<>();
for (Map<String, Double> ratings : userRatings.values()) {
items.addAll(ratings.keySet());
}
return items;
}
}
推荐结果类
package com.recommend.model;
/**
* 推荐结果
*/
public class Recommendation implements Comparable<Recommendation> {
private String itemId;
private double score;
public Recommendation(String itemId, double score) {
this.itemId = itemId;
this.score = score;
}
public String getItemId() {
return itemId;
}
public double getScore() {
return score;
}
@Override
public int compareTo(Recommendation o) {
// 按得分降序排列
return Double.compare(o.score, this.score);
}
@Override
public String toString() {
return String.format("Recommendation{item='%s', score=%.4f}", itemId, score);
}
}
相似度计算工具类
package com.recommend.util;
import java.util.Map;
import java.util.Set;
/**
* 相似度计算工具
*/
public class SimilarityUtil {
/**
* 计算Pearson相关系数
* @param user1Ratings 用户1的评分
* @param user2Ratings 用户2的评分
*/
public static double pearsonCorrelation(Map<String, Double> user1Ratings,
Map<String, Double> user2Ratings) {
// 找到共同评分的物品
Set<String> commonItems = new java.util.HashSet<>(user1Ratings.keySet());
commonItems.retainAll(user2Ratings.keySet());
if (commonItems.size() < 2) {
return 0.0; // 共同评分物品太少,无法计算
}
double sum1 = 0, sum2 = 0, sum1Sq = 0, sum2Sq = 0, pSum = 0;
int n = commonItems.size();
for (String item : commonItems) {
double r1 = user1Ratings.get(item);
double r2 = user2Ratings.get(item);
sum1 += r1;
sum2 += r2;
sum1Sq += r1 * r1;
sum2Sq += r2 * r2;
pSum += r1 * r2;
}
double num = pSum - (sum1 * sum2 / n);
double den = Math.sqrt((sum1Sq - sum1 * sum1 / n) * (sum2Sq - sum2 * sum2 / n));
if (den == 0) return 0.0;
return num / den;
}
/**
* 计算余弦相似度
*/
public static double cosineSimilarity(Map<String, Double> user1Ratings,
Map<String, Double> user2Ratings) {
Set<String> commonItems = new java.util.HashSet<>(user1Ratings.keySet());
commonItems.retainAll(user2Ratings.keySet());
if (commonItems.isEmpty()) {
return 0.0;
}
double dotProduct = 0;
double norm1 = 0;
double norm2 = 0;
// 计算共同物品的点积
for (String item : commonItems) {
dotProduct += user1Ratings.get(item) * user2Ratings.get(item);
}
// 计算各自的范数
for (double rating : user1Ratings.values()) {
norm1 += rating * rating;
}
for (double rating : user2Ratings.values()) {
norm2 += rating * rating;
}
if (norm1 == 0 || norm2 == 0) {
return 0.0;
}
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
/**
* 修正的余弦相似度(用于物品间相似度)
*/
public static double adjustedCosineSimilarity(Map<String, Double> item1Ratings,
Map<String, Double> item2Ratings,
Map<String, Double> userAvgRatings) {
Set<String> commonUsers = new java.util.HashSet<>(item1Ratings.keySet());
commonUsers.retainAll(item2Ratings.keySet());
if (commonUsers.isEmpty()) {
return 0.0;
}
double sum = 0;
double sum1Sq = 0;
double sum2Sq = 0;
for (String user : commonUsers) {
double avg = userAvgRatings.getOrDefault(user, 3.0); // 默认平均分3.0
double r1 = item1Ratings.get(user) - avg;
double r2 = item2Ratings.get(user) - avg;
sum += r1 * r2;
sum1Sq += r1 * r1;
sum2Sq += r2 * r2;
}
if (sum1Sq == 0 || sum2Sq == 0) {
return 0.0;
}
return sum / (Math.sqrt(sum1Sq) * Math.sqrt(sum2Sq));
}
}
基于用户的协同过滤算法
package com.recommend.algorithm;
import com.recommend.model.Recommendation;
import com.recommend.model.UserRating;
import com.recommend.util.SimilarityUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* 基于用户的协同过滤算法
*/
public class UserBasedCF {
private UserRating userRating;
private Map<String, Map<String, Double>> userSimilarityCache;
public UserBasedCF(UserRating userRating) {
this.userRating = userRating;
this.userSimilarityCache = new HashMap<>();
}
/**
* 为用户生成推荐
* @param userId 用户ID
* @param topN 推荐数量
* @param k 邻居数量
*/
public List<Recommendation> recommend(String userId, int topN, int k) {
Map<String, Double> targetUserRatings = userRating.getUserRatings(userId);
Map<String, Map<String, Double>> allUsers = userRating.getAllUserRatings();
// 1. 计算与其他用户的相似度
Map<String, Double> userSimilarities = new HashMap<>();
for (String otherUser : allUsers.keySet()) {
if (otherUser.equals(userId)) continue;
double similarity = SimilarityUtil.pearsonCorrelation(
targetUserRatings,
allUsers.get(otherUser)
);
if (similarity > 0) { // 只考虑正相似度
userSimilarities.put(otherUser, similarity);
}
}
// 2. 找到K个最近邻居
List<Map.Entry<String, Double>> nearestNeighbors = userSimilarities.entrySet()
.stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.limit(k)
.collect(Collectors.toList());
// 3. 生成推荐
Map<String, Double> itemScores = new HashMap<>();
Map<String, Double> itemScoreWeight = new HashMap<>();
for (Map.Entry<String, Double> neighbor : nearestNeighbors) {
String neighborUser = neighbor.getKey();
double similarity = neighbor.getValue();
Map<String, Double> neighborRatings = userRating.getUserRatings(neighborUser);
// 计算邻居用户的平均评分
double neighborAvg = neighborRatings.values().stream()
.mapToDouble(Double::doubleValue)
.average()
.orElse(3.0);
for (Map.Entry<String, Double> rating : neighborRatings.entrySet()) {
String itemId = rating.getKey();
double itemRating = rating.getValue();
// 只推荐用户没有评分的物品
if (!targetUserRatings.containsKey(itemId)) {
// 基于相似度和评分的加权平均
double weightedScore = similarity * (itemRating - neighborAvg);
itemScores.put(itemId,
itemScores.getOrDefault(itemId, 0.0) + weightedScore);
itemScoreWeight.put(itemId,
itemScoreWeight.getOrDefault(itemId, 0.0) + Math.abs(similarity));
}
}
}
// 4. 计算最终推荐分数
List<Recommendation> recommendations = new ArrayList<>();
for (Map.Entry<String, Double> entry : itemScores.entrySet()) {
String itemId = entry.getKey();
double weight = itemScoreWeight.getOrDefault(itemId, 0.0);
if (weight > 0) {
// 加上用户平均分作为基准
double userAvg = targetUserRatings.values().stream()
.mapToDouble(Double::doubleValue)
.average()
.orElse(3.0);
double score = userAvg + (entry.getValue() / weight);
recommendations.add(new Recommendation(itemId, score));
}
}
// 按得分排序,取前N个
return recommendations.stream()
.sorted(Comparator.reverseOrder())
.limit(topN)
.collect(Collectors.toList());
}
/**
* 获取与指定用户最相似的用户
*/
public List<String> getSimilarUsers(String userId, int k) {
Map<String, Double> targetUserRatings = userRating.getUserRatings(userId);
Map<String, Double> similarities = new HashMap<>();
for (Map.Entry<String, Map<String, Double>> entry :
userRating.getAllUserRatings().entrySet()) {
String otherUser = entry.getKey();
if (!otherUser.equals(userId)) {
double sim = SimilarityUtil.pearsonCorrelation(
targetUserRatings, entry.getValue());
similarities.put(otherUser, sim);
}
}
return similarities.entrySet().stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.limit(k)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
基于物品的协同过滤算法
package com.recommend.algorithm;
import com.recommend.model.Recommendation;
import com.recommend.model.UserRating;
import com.recommend.util.SimilarityUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* 基于物品的协同过滤算法
*/
public class ItemBasedCF {
private UserRating userRating;
private Map<String, Map<String, Double>> itemSimilarityCache;
public ItemBasedCF(UserRating userRating) {
this.userRating = userRating;
this.itemSimilarityCache = new HashMap<>();
}
/**
* 为用户生成推荐
* @param userId 目标用户
* @param topN 推荐数量
* @param k 相似物品数量
*/
public List<Recommendation> recommend(String userId, int topN, int k) {
Map<String, Double> userRatings = userRating.getUserRatings(userId);
Set<String> allItems = userRating.getAllItems();
// 计算用户平均评分
double userAvg = userRatings.values().stream()
.mapToDouble(Double::doubleValue)
.average()
.orElse(3.0);
// 对每个未评分的物品,预测评分
Map<String, Double> predictions = new HashMap<>();
for (String item : allItems) {
if (!userRatings.containsKey(item)) {
double predictedScore = predictRating(userId, item, k);
if (predictedScore > 0) {
predictions.put(item, predictedScore);
}
}
}
// 获取当前用户的评分物品列表
List<Map.Entry<String, Double>> ratedItems = new ArrayList<>(userRatings.entrySet());
// 生成推荐
List<Recommendation> recommendations = new ArrayList<>();
for (Map.Entry<String, Double> prediction : predictions.entrySet()) {
String targetItem = prediction.getKey();
double score = prediction.getValue();
// 可选:可以结合用户历史评分调整
recommendations.add(new Recommendation(targetItem, score));
}
// 按得分排序,取前N个
return recommendations.stream()
.sorted(Comparator.reverseOrder())
.limit(topN)
.collect(Collectors.toList());
}
/**
* 预测用户对物品的评分
*/
private double predictRating(String userId, String itemId, int k) {
Map<String, Double> userRatings = userRating.getUserRatings(userId);
// 找到与目标物品最相似的k个物品
List<Map.Entry<String, Double>> similarItems = getSimilarItems(itemId, k);
if (similarItems.isEmpty()) {
return 0.0;
}
double sum = 0.0;
double sumWeight = 0.0;
for (Map.Entry<String, Double> similarItem : similarItems) {
String similarItemId = similarItem.getKey();
double similarity = similarItem.getValue();
double itemRating = userRatings.getOrDefault(similarItemId, 0.0);
if (itemRating > 0) {
sum += similarity * itemRating;
sumWeight += similarity;
}
}
if (sumWeight == 0) {
return 0.0;
}
return sum / sumWeight;
}
/**
* 获取与指定物品最相似的物品列表
*/
public List<Map.Entry<String, Double>> getSimilarItems(String itemId, int k) {
if (itemSimilarityCache.containsKey(itemId)) {
Map<String, Double> cachedSims = itemSimilarityCache.get(itemId);
return cachedSims.entrySet().stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.limit(k)
.collect(Collectors.toList());
}
Map<String, Double> itemRatings = userRating.getItemRatings(itemId);
Set<String> allItems = userRating.getAllItems();
// 计算用户平均评分(用于修正余弦相似度)
Map<String, Double> userAvgRatings = new HashMap<>();
for (Map.Entry<String, Map<String, Double>> entry :
userRating.getAllUserRatings().entrySet()) {
double avg = entry.getValue().values().stream()
.mapToDouble(Double::doubleValue)
.average()
.orElse(3.0);
userAvgRatings.put(entry.getKey(), avg);
}
Map<String, Double> similarities = new HashMap<>();
for (String otherItem : allItems) {
if (!otherItem.equals(itemId)) {
Map<String, Double> otherItemRatings = userRating.getItemRatings(otherItem);
double sim = SimilarityUtil.adjustedCosineSimilarity(
itemRatings, otherItemRatings, userAvgRatings);
if (sim > 0) {
similarities.put(otherItem, sim);
}
}
}
// 缓存相似度
itemSimilarityCache.put(itemId, similarities);
// 返回top-k相似物品
return similarities.entrySet().stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.limit(k)
.collect(Collectors.toList());
}
/**
* 获取与指定物品最相似的物品
*/
public List<String> getMostSimilarItems(String itemId, int k) {
return getSimilarItems(itemId, k).stream()
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
推荐系统主类
package com.recommend;
import com.recommend.algorithm.ItemBasedCF;
import com.recommend.algorithm.UserBasedCF;
import com.recommend.model.Recommendation;
import com.recommend.model.UserRating;
import java.util.List;
import java.util.Scanner;
/**
* 推荐系统主类
*/
public class RecommendationSystem {
private UserRating userRating;
private UserBasedCF userBasedCF;
private ItemBasedCF itemBasedCF;
/**
* 初始化推荐系统
*/
public void init() {
// 加载模拟数据
loadTestData();
// 初始化算法
userBasedCF = new UserBasedCF(userRating);
itemBasedCF = new ItemBasedCF(userRating);
}
/**
* 加载测试数据
*/
private void loadTestData() {
userRating = new UserRating();
// 模拟用户评分数据 (5个用户, 6个物品)
// 用户1:喜欢书籍和音乐(评分1-5)
userRating.addRating("user1", "book1", 5.0);
userRating.addRating("user1", "book2", 4.0);
userRating.addRating("user1", "music1", 5.0);
userRating.addRating("user1", "movie1", 3.0);
userRating.addRating("user1", "sport1", 1.0);
userRating.addRating("user1", "food1", 2.0);
// 用户2:喜欢音乐
userRating.addRating("user2", "music1", 5.0);
userRating.addRating("user2", "music2", 4.0);
userRating.addRating("user2", "book1", 4.0);
userRating.addRating("user2", "movie2", 2.0);
userRating.addRating("user2", "food1", 3.0);
// 用户3:喜欢体育
userRating.addRating("user3", "sport1", 5.0);
userRating.addRating("user3", "sport2", 4.0);
userRating.addRating("user3", "book2", 2.0);
userRating.addRating("user3", "movie1", 1.0);
// 用户4:喜欢电影和书籍
userRating.addRating("user4", "movie1", 5.0);
userRating.addRating("user4", "movie2", 4.0);
userRating.addRating("user4", "book2", 4.0);
userRating.addRating("user4", "book1", 3.0);
userRating.addRating("user4", "music2", 2.0);
// 用户5:综合爱好者
userRating.addRating("user5", "book1", 4.0);
userRating.addRating("user5", "music1", 3.0);
userRating.addRating("user5", "sport2", 3.0);
userRating.addRating("user5", "food1", 4.0);
userRating.addRating("user5", "movie1", 3.0);
}
/**
* 获取数据统计信息
*/
public void printStatistics() {
System.out.println("========== 数据集统计 ==========");
System.out.println("用户数量: " + userRating.getAllUserRatings().size());
System.out.println("物品数量: " + userRating.getAllItems().size());
// 打印所有评分
System.out.println("\n评分矩阵:");
System.out.println("------------------------------------------------------------------------");
for (Map.Entry<String, Map<String, Double>> user :
userRating.getAllUserRatings().entrySet()) {
System.out.printf("%-10s", user.getKey() + ": ");
for (Map.Entry<String, Double> rating : user.getValue().entrySet()) {
System.out.printf("%s=%.1f ", rating.getKey(), rating.getValue());
}
System.out.println();
}
System.out.println("------------------------------------------------------------------------\n");
}
/**
* 运行基于用户的协同过滤推荐
* @param userId 目标用户
*/
public void runUserBasedCF(String userId, int topN, int k) {
System.out.println("\n基于用户的协同过滤推荐 (User-Based Collaborative Filtering)");
System.out.println("========================================");
List<Recommendation> recommendations = userBasedCF.recommend(userId, topN, k);
if (recommendations.isEmpty()) {
System.out.println("没有找到合适的推荐");
return;
}
System.out.printf("用户 %s 的 Top-%d 推荐:", userId, topN);
System.out.println("\n推荐排名:");
for (int i = 0; i < recommendations.size(); i++) {
Recommendation rec = recommendations.get(i);
System.out.printf("%d. 物品 %s, 预测评分: %.2f\n",
i+1, rec.getItemId(), rec.getScore());
}
}
/**
* 运行基于物品的协同过滤推荐
* @param userId 目标用户
*/
public void runItemBasedCF(String userId, int topN, int k) {
System.out.println("\n基于物品的协同过滤推荐 (Item-Based Collaborative Filtering)");
System.out.println("============================================");
List<Recommendation> recommendations = itemBasedCF.recommend(userId, topN, k);
if (recommendations.isEmpty()) {
System.out.println("没有找到合适的推荐");
return;
}
System.out.printf("用户 %s 的 Top-%d 推荐:", userId, topN);
System.out.println("\n推荐排名:");
for (int i = 0; i < recommendations.size(); i++) {
Recommendation rec = recommendations.get(i);
System.out.printf("%d. 物品 %s, 预测评分: %.2f\n",
i+1, rec.getItemId(), rec.getScore());
}
}
/**
* 显示相似用户
*/
public void showSimilarUsers(String userId, int k) {
System.out.println("\n相似用户 (" + userId + "):");
System.out.println("==============");
List<String> similarUsers = userBasedCF.getSimilarUsers(userId, k);
for (String similarUser : similarUsers) {
System.out.println("- " + similarUser);
}
}
/**
* 显示相似物品
*/
public void showSimilarItems(String itemId, int k) {
System.out.println("\n相似物品 (" + itemId + "):");
System.out.println("=============");
List<String> similarItems = itemBasedCF.getMostSimilarItems(itemId, k);
for (String similarItem : similarItems) {
System.out.println("- " + similarItem);
}
}
/**
* 简单交互界面
*/
public void interactiveMode() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n========== 协同过滤推荐系统 ==========");
System.out.println("1. 显示数据集统计");
System.out.println("2. 基于用户的协同过滤推荐");
System.out.println("3. 基于物品的协同过滤推荐");
System.out.println("4. 查看相似用户");
System.out.println("5. 查看相似物品");
System.out.println("6. 退出");
System.out.print("请选择操作: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
printStatistics();
break;
case 2:
System.out.print("请输入用户ID (user1-user5): ");
String userId = scanner.nextLine();
runUserBasedCF(userId, 5, 3);
break;
case 3:
System.out.print("请输入用户ID (user1-user5): ");
userId = scanner.nextLine();
runItemBasedCF(userId, 5, 3);
break;
case 4:
System.out.print("请输入用户ID (user1-user5): ");
userId = scanner.nextLine();
showSimilarUsers(userId, 2);
break;
case 5:
System.out.print("请输入物品ID: ");
String itemId = scanner.nextLine();
showSimilarItems(itemId, 3);
break;
case 6:
System.out.println("感谢使用,再见!");
return;
default:
System.out.println("无效选择,请重试!");
}
}
}
/**
* 主入口函数
*/
public static void main(String[] args) {
RecommendationSystem system = new RecommendationSystem();
// 1. 初始化推荐系统
system.init();
// 2. 显示数据统计
system.printStatistics();
// 3. 运行推荐示例
String testUser = "user1";
// 用户协同过滤
system.runUserBasedCF(testUser, 5, 3);
// 物品协同过滤
system.runItemBasedCF(testUser, 5, 3);
// 4. 显示相似用户和物品
system.showSimilarUsers(testUser, 3);
system.showSimilarItems("book1", 3);
// 5. 进入交互模式
system.interactiveMode();
}
}
Maven配置文件 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>recommendation-system</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 如果需要日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
测试代码
package com.recommend;
import com.recommend.model.Recommendation;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.*;
public class RecommendationSystemTest {
private RecommendationSystem system;
@Before
public void setUp() {
system = new RecommendationSystem();
system.init();
}
@Test
public void testUserBasedRecommendation() {
List<Recommendation> recommendations = system.userBasedCF.recommend("user1", 5, 3);
assertNotNull("推荐结果不应为空", recommendations);
assertFalse("推荐列表不应为空", recommendations.isEmpty());
assertTrue("推荐数量不应超过5", recommendations.size() <= 5);
// 验证推荐分数
for (Recommendation rec : recommendations) {
assertTrue("推荐分数应在1-5之间", rec.getScore() >= 1 && rec.getScore() <= 5);
}
}
@Test
public void testSimilarUserFound() {
List<String> similarUsers = system.userBasedCF.getSimilarUsers("user1", 3);
assertFalse("应找到相似用户", similarUsers.isEmpty());
assertFalse("不应该包含自己", similarUsers.contains("user1"));
}
@Test
public void testItemBasedRecommendation() {
List<Recommendation> recommendations = system.itemBasedCF.recommend("user1", 5, 3);
assertNotNull("推荐结果不应为空", recommendations);
assertFalse("推荐列表不应为空", recommendations.isEmpty());
}
}
使用说明
-
编译运行:
mvn clean compile mvn exec:java -Dexec.mainClass="com.recommend.RecommendationSystem"
-
功能特点:
- 基于用户的协同过滤(发现相似用户)
- 基于物品的协同过滤(发现相似物品)
- 两种算法结果对比
- 交互式命令行界面
-
数据说明:
- 5个用户对6个物品的评分
- 评分为1-5的整数
- 测试数据模拟了不同的用户兴趣
这个案例实现了完整的协同过滤推荐系统,包括数据模型、相似度计算、推荐算法和交互界面,可以直接运行测试。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播