创建2700000×18000矩阵遇MemoryError,求解决方案
解决Netflix Prize数据集矩阵分解的内存错误与形状问题
问题本质
- 直接构建
(2700000, 18000)的稠密矩阵内存需求远超常规机器上限:float64类型需362GiB,即使压缩到uint8也需约45GiB。 - 你碰到的形状错误,核心原因是原始用户/电影ID不连续:Netflix数据集的ID并非从1开始连续编号,直接用原始ID作为矩阵索引会错误放大矩阵维度。
可行解决方案
1. 用稀疏矩阵存储(首选)
Netflix数据集极度稀疏(仅约0.2%的位置有评分),稀疏矩阵只存储非零评分,内存占用可降至几百MB级别:
import numpy as np from scipy.sparse import csr_matrix # 假设已读取到user_ids, movie_ids, ratings三个数组 # 第一步:将非连续ID映射为连续索引 unique_users = np.unique(user_ids) unique_movies = np.unique(movie_ids) user_idx_map = {u: idx for idx, u in enumerate(unique_users)} movie_idx_map = {m: idx for idx, m in enumerate(unique_movies)} # 转换为连续索引 user_indices = np.array([user_idx_map[u] for u in user_ids]) movie_indices = np.array([movie_idx_map[m] for m in movie_ids]) # 创建CSR稀疏矩阵(适合矩阵运算) sparse_rating_matrix = csr_matrix( (ratings, (user_indices, movie_indices)), shape=(len(unique_users), len(unique_movies)), dtype=np.uint8 )
2. 用专门的推荐算法库处理(无需手动构建矩阵)
主流推荐算法库已内置稀疏数据支持,无需自己折腾矩阵:
- implicit库(适合隐式反馈):
from implicit.als import AlternatingLeastSquares # implicit默认处理物品-用户矩阵,需转置输入 als_model = AlternatingLeastSquares(factors=64, regularization=0.01) als_model.fit(sparse_rating_matrix.T) - surprise库(适合显式评分):
from surprise import Dataset, SVD, Reader from surprise.model_selection import train_test_split # 加载数据(your_dataframe需包含user_id, movie_id, rating三列) reader = Reader(rating_scale=(1, 5)) data = Dataset.load_from_df(your_dataframe[['user_id', 'movie_id', 'rating']], reader) trainset, testset = train_test_split(data, test_size=0.2) # 训练SVD矩阵分解模型 svd_model = SVD() svd_model.fit(trainset)
3. 若必须用稠密矩阵(仅适用于大内存机器)
先完成ID映射修正维度,再构建矩阵:
# 基于前面的ID映射,创建对应维度的稠密矩阵 dense_matrix = np.zeros((len(unique_users), len(unique_movies)), dtype=np.uint8) # 填充评分数据 dense_matrix[user_indices, movie_indices] = ratings
内容的提问来源于stack exchange,提问作者Education 4Fun
相关产品推荐
相关产品推荐

