用springboot写一个协同过滤推荐接口,全部写在接口里, 接口使用mysql数据源
时间: 2023-06-26 08:09:24 浏览: 110
好的,下面是一个简单的协同过滤推荐接口的实现,使用Spring Boot和MySQL数据源:
首先,我们需要定义一个RecommendationController类来处理HTTP请求,并实现协同过滤算法:
```java
@RestController
@RequestMapping("/recommendation")
public class RecommendationController {
@Autowired
private DataSource dataSource;
@GetMapping("/{userId}")
public List<Integer> recommend(@PathVariable("userId") int userId) throws SQLException {
List<Integer> result = new ArrayList<>();
// 获取用户评分数据
Map<Integer, Map<Integer, Double>> userRatings = getUserRatings(userId);
// 计算相似度
Map<Integer, Double> similarityScores = new HashMap<>();
for (int otherUserId : userRatings.keySet()) {
if (otherUserId == userId) continue;
double similarity = calculateSimilarity(userRatings.get(userId), userRatings.get(otherUserId));
similarityScores.put(otherUserId, similarity);
}
// 获取推荐结果
for (int itemId : getUnratedItems(userId)) {
double score = 0;
double totalSimilarity = 0;
for (int otherUserId : userRatings.keySet()) {
if (otherUserId == userId) continue;
Map<Integer, Double> otherUserRatings = userRatings.get(otherUserId);
if (otherUserRatings.containsKey(itemId)) {
double similarity = similarityScores.get(otherUserId);
score += similarity * otherUserRatings.get(itemId);
totalSimilarity += similarity;
}
}
if (totalSimilarity > 0) {
result.add(itemId);
}
}
return result;
}
private Map<Integer, Map<Integer, Double>> getUserRatings(int userId) throws SQLException {
Map<Integer, Map<Integer, Double>> result = new HashMap<>();
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT item_id, rating FROM ratings WHERE user_id = ?")) {
stmt.setInt(1, userId);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int itemId = rs.getInt("item_id");
double rating = rs.getDouble("rating");
if (!result.containsKey(userId)) {
result.put(userId, new HashMap<>());
}
result.get(userId).put(itemId, rating);
}
}
}
return result;
}
private List<Integer> getUnratedItems(int userId) throws SQLException {
List<Integer> result = new ArrayList<>();
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT DISTINCT item_id FROM ratings WHERE user_id <> ? AND item_id NOT IN (SELECT item_id FROM ratings WHERE user_id = ?)")) {
stmt.setInt(1, userId);
stmt.setInt(2, userId);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int itemId = rs.getInt("item_id");
result.add(itemId);
}
}
}
return result;
}
private double calculateSimilarity(Map<Integer, Double> ratings1, Map<Integer, Double> ratings2) {
double dotProduct = 0;
double norm1 = 0;
double norm2 = 0;
for (int itemId : ratings1.keySet()) {
if (ratings2.containsKey(itemId)) {
dotProduct += ratings1.get(itemId) * ratings2.get(itemId);
}
norm1 += Math.pow(ratings1.get(itemId), 2);
}
for (int itemId : ratings2.keySet()) {
norm2 += Math.pow(ratings2.get(itemId), 2);
}
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
}
```
上面的代码中,我们使用了Spring Boot的@RestController注解来标识RecommendationController类是一个处理HTTP请求的控制器。其中,@RequestMapping("/recommendation")注解表示这个控制器处理以/recommendation开头的请求。
在recommend()方法中,我们首先获取指定用户的评分数据,然后计算该用户与其他用户的相似度,并为每个未评分的物品计算一个推荐得分。最后,我们返回推荐得分最高的物品列表。
getUserRatings()方法用于从数据库中获取指定用户的评分数据。getUnratedItems()方法用于获取所有未评分的物品。calculateSimilarity()方法用于计算两个用户之间的相似度。
注意,上面的代码中我们使用了Spring Boot的自动装配特性来注入dataSource对象,以便于我们直接从数据库中获取数据。但是,在实际的应用中,我们应该将数据访问逻辑封装到DAO类中,以便于我们更好地管理数据访问逻辑。
最后,我们需要在application.properties文件中配置MySQL数据源:
```
spring.datasource.url=jdbc:mysql://localhost:3306/recommendation
spring.datasource.username=root
spring.datasource.password=
```
上面的配置表示使用localhost上的MySQL服务器,并连接到recommendation数据库。用户名和密码分别为root和空。
注意,在使用上面的配置之前,我们需要先创建recommendation数据库,并在其中创建ratings表,以存储用户评分数据。ratings表的结构如下:
```
CREATE TABLE ratings (
user_id INT NOT NULL,
item_id INT NOT NULL,
rating DOUBLE NOT NULL,
PRIMARY KEY (user_id, item_id)
);
```
上面的表结构表示ratings表包含三个字段:user_id、item_id和rating。其中,user_id和item_id字段用于标识评分记录的用户和物品,rating字段用于存储用户对物品的评分。PRIMARY KEY约束用于保证每个评分记录的唯一性。
现在,我们就可以启动应用程序,并访问http://localhost:8080/recommendation/{userId}来获取指定用户的推荐结果了。注意,上面的{userId}应该替换为实际的用户ID。
阅读全文