解释每一句代码的功能。 import pandas as pd import numpy as np from sklearn.metrics.pairwise import cosine_similarity from sklearn.model_selection import train_test_split # 加载数据 ratings = pd.read_csv('D:/py_code/ml-latest-small/ml-latest-small/ratings.csv') movies = pd.read_csv('D:/py_code/ml-latest-small/ml-latest-small/movies.csv') # 划分训练集和测试集 train_ratings, test_ratings = train_test_split(ratings, test_size=0.2, stratify=ratings['userId'], random_state=42) # 创建训练矩阵(填充用户平均分) train_matrix = train_ratings.pivot_table(index='userId', columns='movieId', values='rating') user_means = train_matrix.mean(axis=1) train_matrix_filled = train_matrix.apply(lambda row: row.fillna(user_means[row.name]), axis=1) train_matrix_filled.fillna(0, inplace=True) # 计算用户相似度矩阵 user_similarity = cosine_similarity(train_matrix_filled) user_similarity_df = pd.DataFrame(user_similarity, index=train_matrix_filled.index, columns=train_matrix_filled.index) # 定义预测函数 def predict_rating(user_id, movie_id, k=20): try: user_index = train_matrix_filled.index.get_loc(user_id) except KeyError: return 0 # 用户不在训练集中 if movie_id not in train_matrix_filled.columns: return 0 # 电影不在训练集中 # 获取相似用户 sim_users = user_similarity_df[user_id].sort_values(ascending=False).index[1:k + 1] # 计算加权评分 weighted_sum = 0 sum_sim = 0 for sim_user in sim_users: sim = user_similarity_df.loc[user_id, sim_user] rating = train_matrix_filled.loc[sim_user, movie_id] if rating > 0: weighted_sum += sim * rating sum_sim += sim return weighted_sum / sum_sim if sum_sim != 0 else 0 # 评估模型 threshold = 4.0 top_n = 100 total_tp = total_fp = total_fn = 0 for user_id in test_ratings['userId'].unique(): # 获取测试集候选电影 user_test = test_ratings[(test_ratings['userId'] == user_id) & (test_ratings['rating'] >= threshold)] actual_positives = user_test['movieId'].tolist() # 生成推荐列表 rated_movies = train_ratings[train_ratings['userId'] == user_id]['movieId'] candidate_movies = test_ratings[test_ratings['userId'] == user_id]['movieId'] candidate_movies = candidate_movies[~candidate_movies.isin(rated_movies)] predictions = [] for movie_id in candidate_movies: pred = predict_rating(user_id, movie_id) predictions.append((movie_id, pred)) predictions.sort(key=lambda x: x[1], reverse=True) recommended = [x[0] for x in predictions[:top_n]] # 计算指标 tp = len(set(recommended) & set(actual_positives)) fp = len(recommended) - tp fn = len(actual_positives) - tp total_tp += tp total_fp += fp total_fn += fn # 计算全局指标 precision = total_tp / (total_tp + total_fp) if (total_tp + total_fp) > 0 else 0 recall = total_tp / (total_tp + total_fn) if (total_tp + total_fn) > 0 else 0 f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0 # 用户输入及推荐 def recommend_movies(user_id, top_n=100): rated = train_ratings[train_ratings['userId'] == user_id]['movieId'] all_movies = ratings['movieId'].unique() unrated = np.setdiff1d(all_movies, rated) predictions = [] for movie_id in unrated: pred = predict_rating(user_id, movie_id) predictions.append((movie_id, pred)) predictions.sort(key=lambda x: x[1], reverse=True) top_movies = [x[0] for x in predictions[:top_n]] return movies[movies['movieId'].isin(top_movies)]['title'].tolist() # 示例使用 user_id = int(input("请输入用户ID: ")) print("\n推荐电影列表:") print("\n".join(recommend_movies(user_id))) print("\n模型评估指标:") print(f"精确率: {precision:.4f}") print(f"召回率: {recall:.4f}") print(f"F1值: {f1:.4f}")
时间: 2025-07-15 11:34:41 浏览: 5
<think>好的,我现在需要解释这段代码的每一句功能。首先,我得通读整个代码,理解每一部分的作用。用户希望逐句解释,所以我得按顺序来,确保每个关键步骤都覆盖到。
首先,导入库的部分。看到pandas、numpy、cosine_similarity、train_test_split,这些应该是数据处理、相似度计算和数据划分用的。然后加载数据,ratings.csv和movies.csv,这应该是评分和电影信息的数据集。
接下来是划分训练集和测试集,使用train_test_split,test_size是0.2,stratify按userId分层抽样,保证分布一致。这里可能需要解释stratify的作用,保持用户分布均匀。
然后是创建训练矩阵,用pivot_table生成用户-电影评分矩阵,填充用户平均分。这里可能遇到NaN,所以用apply填充每行的平均值,之后用fillna(0)处理剩余缺失值,可能是没有评分的电影。
计算用户相似度矩阵,使用cosine_similarity计算用户之间的余弦相似度,转换成DataFrame,索引是用户ID,方便后续查询。
定义predict_rating函数,预测用户对某部电影的评分。这里需要处理用户或电影不在训练集中的情况,返回0。然后找到最相似的k个用户,计算加权评分,相似度乘以评分,再归一化。如果相似度总和为0,则返回0。
评估模型部分,设定阈值和top_n,初始化TP、FP、FN。遍历测试集中的每个用户,获取实际喜欢的电影(评分高于阈值),生成候选电影(排除已评分的),预测评分并排序,取top_n作为推荐。计算TP、FP、FN,累加后计算全局的精确率、召回率和F1值。
用户输入及推荐函数recommend_movies,找出用户未评分的电影,预测评分,返回最高分的top_n电影标题。
最后示例使用,输入用户ID,输出推荐列表和评估指标。
在解释过程中,需要注意技术细节,比如pivot_table的应用,填充方法,相似度计算的具体实现,评估指标的计算方式等。同时要确保用中文清晰表达,符合用户的要求。如果有不确定的地方,比如填充平均值的方法是否正确,或者相似用户是否排除自己,可能需要检查代码逻辑。比如在获取相似用户时,用了index[1:k+1],可能排除了第一个(自己),因为相似度排序后第一个是用户自己,相似度为1,所以需要跳过。这部分需要确认是否正确。
另外,评估部分,候选电影是从测试集中选取,并且排除已评分的,是否正确?可能用户已经评分过的在训练集中,测试集里的评分是未参与训练的。这里需要确保生成推荐时没有使用测试集中的评分数据,避免数据泄漏。
在predict函数中,如果用户或电影不在训练集,返回0是否合理?或者是否有其他处理方式?比如新用户的冷启动问题,这里可能直接返回0,但实际应用中可能需要其他策略。
最后,示例使用部分,用户输入ID后,调用推荐函数并展示结果,同时输出模型评估指标。整个过程是否完整,是否符合协同过滤的基本流程,比如基于用户的协同过滤,使用余弦相似度,预测评分,然后推荐。
总结下来,逐句解释需要覆盖每个代码块的功能,技术细节,以及可能的注意事项,确保用户能理解整个推荐系统的实现流程。</think>以下是代码逐句功能解释:
---
### 一、库导入
```python
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.model_selection import train_test_split
```
- `pandas`:数据处理库,用于读取CSV和创建数据矩阵
- `numpy`:数值计算库,处理数组操作
- `cosine_similarity`:计算用户之间的余弦相似度
- `train_test_split`:将数据集划分为训练集和测试集
---
### 二、数据加载
```python
ratings = pd.read_csv('D:/py_code/ml-latest-small/ml-latest-small/ratings.csv')
movies = pd.read_csv('D:/py_code/ml-latest-small/ml-latest-small/movies.csv')
```
- 读取用户评分数据(userId, movieId, rating)和电影元数据(movieId, title, genres)
---
### 三、数据集划分
```python
train_ratings, test_ratings = train_test_split(ratings, test_size=0.2, stratify=ratings['userId'], random_state=42)
```
- 按用户ID分层抽样,80%作为训练集,20%作为测试集
- `stratify`确保每个用户在训练集和测试集中分布一致
---
### 四、创建训练矩阵
```python
train_matrix = train_ratings.pivot_table(index='userId', columns='movieId', values='rating')
```
- 生成用户-电影评分矩阵(存在大量NaN值)
```python
user_means = train_matrix.mean(axis=1)
train_matrix_filled = train_matrix.apply(lambda row: row.fillna(user_means[row.name]), axis=1)
```
- 用每个用户的平均评分填充缺失值(处理未评分电影)
```python
train_matrix_filled.fillna(0, inplace=True)
```
- 剩余未填充的NaN(用户未评分且无平均分)填0
---
### 五、计算用户相似度
```python
user_similarity = cosine_similarity(train_matrix_filled)
user_similarity_df = pd.DataFrame(user_similarity, index=train_matrix_filled.index, columns=train_matrix_filled.index)
```
- 使用余弦相似度计算用户间相似性
- 将结果转换为DataFrame,索引和列均为用户ID
---
### 六、评分预测函数
```python
def predict_rating(user_id, movie_id, k=20):
# 异常处理:用户或电影不存在时返回0
# 获取相似度最高的k个用户(排除自己)
# 加权计算预测评分:相似度 * 评分 / 相似度总和
```
- 核心逻辑:基于相似用户的评分加权预测目标用户的评分
---
### 七、模型评估
```python
threshold = 4.0 # 定义高评分阈值
top_n = 100 # 推荐列表长度
# 遍历测试用户,计算TP/FP/FN
```
- 评估指标:
- **精确率**:推荐列表中正确的比例($Precision = \frac{TP}{TP+FP}$)
- **召回率**:实际高评分中被推荐的比例($Recall = \frac{TP}{TP+FN}$)
- **F1值**:精确率和召回率的调和平均($F1 = \frac{2 \times Precision \times Recall}{Precision + Recall}$)
---
### 八、推荐函数
```python
def recommend_movies(user_id, top_n=100):
# 找出用户未评分的电影
# 预测评分并排序返回Top-N
```
- 通过`np.setdiff1d`计算未评分电影
- 调用预测函数生成推荐列表
---
### 九、交互演示
```python
user_id = int(input("请输入用户ID: "))
print(recommend_movies(user_id))
print(f"精确率: {precision:.4f}")
```
- 接收用户输入,输出推荐结果和评估指标
---
### 代码特点
1. **冷启动处理**:对未知用户/电影返回0
2. **数据填充策略**:用用户平均分填补缺失值
3. **高效计算**:预计算用户相似度矩阵
4. **评估方法**:基于Top-N推荐的分类指标
需要改进的点:未处理新用户冷启动问题,可考虑加入流行度推荐作为fallback策略。
阅读全文
相关推荐



















