从入门到实践:使用Python探索MovieLens数据集的奥秘

张开发
2026/4/2 23:32:44 15 分钟阅读
从入门到实践:使用Python探索MovieLens数据集的奥秘
1. 初识MovieLens数据集推荐系统的Hello World如果你正在学习推荐系统或数据分析MovieLens数据集绝对是你的最佳起点。这个由GroupLens研究实验室维护的电影评分数据集就像编程界的Hello World一样经典。我第一次接触这个数据集时就被它干净的结构和丰富的维度所吸引——它包含了真实用户对电影的真实评分还有用户人口统计信息和电影元数据。目前最常用的版本是100k10万条评分和1M100万条评分数据集。100k数据集包含943位用户对1682部电影的评分而1M数据集则扩大到6040位用户对3900部电影的评分。每个数据集都包含三个核心文件评分数据用户ID、电影ID、评分、时间戳用户数据性别、年龄、职业、邮编电影数据电影ID、标题、类型import pandas as pd # 加载100k数据集中的评分数据 ratings pd.read_csv(ml-100k/u.data, sep\t, names[user_id, movie_id, rating, timestamp]) print(ratings.head())2. 数据加载与初步探索用Pandas打开数据宝箱2.1 正确加载数据文件的技巧MovieLens数据集的文件格式有些特殊很多新手在这里会踩坑。比如100k数据集中的u.data文件使用制表符分隔而1M数据集则使用双冒号(::)分隔。我第一次使用时没注意这点结果读出来的数据全乱套了。# 加载1M数据集的正确方式 ratings_1m pd.read_csv(ml-1m/ratings.dat, sep::, enginepython, names[user_id, movie_id, rating, timestamp])2.2 快速了解数据全貌加载数据后我习惯先用几个简单的Pandas操作快速了解数据shape查看数据规模head()查看前几行describe()查看统计摘要info()查看数据类型和缺失值print(f评分记录总数{ratings.shape[0]:,}) print(\n评分分布统计) print(ratings[rating].value_counts().sort_index())3. 深入理解数据字段挖掘每一列的价值3.1 评分数据的秘密评分数据看似简单但蕴含丰富信息。通过分析我发现评分是1-5的整数5分制很常见大多数用户倾向于打高分3-5分每个用户的评分数量差异很大虽然官方说至少20条# 绘制评分分布直方图 import matplotlib.pyplot as plt ratings[rating].hist(bins5) plt.title(电影评分分布) plt.xlabel(评分) plt.ylabel(数量) plt.show()3.2 用户画像分析用户数据文件包含性别、年龄、职业和邮编信息。这里有个实用技巧年龄字段已经是分组编码1-7代表不同年龄段而不是具体年龄值。我经常用groupby分析不同人群的评分偏好users pd.read_csv(ml-100k/u.user, sep|, names[user_id, age, gender, occupation, zip_code]) user_ratings pd.merge(ratings, users, onuser_id) # 不同性别用户的平均评分 print(user_ratings.groupby(gender)[rating].mean())4. 数据预处理实战从原始数据到分析就绪4.1 处理分类变量机器学习模型通常需要数值输入所以我们需要将性别、职业等分类变量转换为数值。这里我推荐使用Pandas的map方法比scikit-learn的LabelEncoder更直观# 性别映射 gender_map {M: 0, F: 1} users[gender] users[gender].map(gender_map) # 职业映射 occupations users[occupation].unique().tolist() occ_map {v:k for k,v in enumerate(occupations)} users[occupation] users[occupation].map(occ_map)4.2 特征工程小技巧邮编信息看起来杂乱但其实前三位通常代表地区。我们可以提取这个信息作为新的特征# 提取邮编前三位 users[zip_region] users[zip_code].str[:3] # 查看各地区用户数量 print(users[zip_region].value_counts().head())5. 电影数据分析发现类型趋势5.1 处理电影类型多值字段电影数据中最有趣的是genres字段一部电影可能属于多个类型用竖线分隔。这种多值字段需要特殊处理movies pd.read_csv(ml-100k/u.item, sep|, encodinglatin-1, names[movie_id, title, release_date, video_release_date, IMDb_URL, *[fgenre_{i} for i in range(19)]]) # 计算各类型电影数量 genre_columns [col for col in movies.columns if col.startswith(genre_)] genre_counts movies[genre_columns].sum().sort_values(ascendingFalse)5.2 电影流行度分析结合评分数据我们可以找出最受欢迎的电影。但要注意仅凭平均评分可能会偏向冷门电影评分人数少但分数高。更好的方法是使用贝叶斯平均# 计算电影评分统计 movie_stats ratings.groupby(movie_id)[rating].agg([count, mean]) movie_stats movie_stats.join(movies.set_index(movie_id)[title]) # 筛选至少100人评分的电影 popular_movies movie_stats[movie_stats[count] 100].sort_values(mean, ascendingFalse) print(popular_movies.head(10))6. 进阶分析思路为推荐系统做准备6.1 用户-电影评分矩阵构建推荐系统通常需要用户-物品评分矩阵。虽然实际应用中会用稀疏矩阵存储但用Pandas的pivot_table可以直观查看# 创建评分矩阵 rating_matrix ratings.pivot_table(indexuser_id, columnsmovie_id, valuesrating) print(rating_matrix.head())6.2 简单的协同过滤示例基于用户的协同过滤是推荐系统的经典算法。虽然实际实现会更复杂但我们可以用几行代码演示核心思想from sklearn.metrics.pairwise import cosine_similarity # 计算用户相似度示例使用前1000条数据加速 sample_matrix rating_matrix.fillna(0).iloc[:100,:100] user_sim cosine_similarity(sample_matrix) print(f用户相似度矩阵形状{user_sim.shape})7. 数据保存与后续使用处理好的数据应该保存起来供后续分析使用。我建议同时保存为CSV和Pickle格式# 保存为CSV可读性好 users.to_csv(processed_users.csv, indexFalse) # 保存为Pickle保留数据类型读写快 import pickle with open(processed_users.pkl, wb) as f: pickle.dump(users, f)在实际项目中我通常会创建一个数据处理管道把所有这些步骤封装成函数这样当数据更新时只需重新运行管道即可。MovieLens数据集虽然结构清晰但真实世界的数据往往混乱得多所以养成良好的数据处理习惯非常重要。

更多文章