You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Google Colab中处理超出RAM容量的大规模数据集的解决方案咨询(基于2.25亿条图书评论用户-物品交互数据集的协同过滤推荐系统开发场景)

在Google Colab中处理超出RAM容量的大规模数据集的解决方案咨询(基于2.25亿条图书评论用户-物品交互数据集的协同过滤推荐系统开发场景)

嘿,我太懂你碰到的这个头疼问题了——2.25亿条用户-物品交互数据直接用pd.read_json()加载,别说Colab的默认内存,就算是本地机器内存不够都得直接崩。下面给你几个实用的办法,一步步帮你搞定这个难题:

  • 分块读取JSON数据,避免一次性占满内存
    Pandas的read_json()其实自带分块加载的功能,不用硬把整个文件塞到内存里。你可以试试这样写:

    # 根据Colab的RAM调整分块大小,先试试100万条一块,不够再调小
    chunk_size = 1_000_000
    chunks = pd.read_json('/content/data/dataset.json', chunksize=chunk_size)
    
    # 遍历每个块,只保留协同过滤必需的列(比如用户ID、书籍ID、评分)
    processed_chunks = []
    for idx, chunk in enumerate(chunks):
        # 过滤掉不需要的列,大幅减少内存占用
        filtered_chunk = chunk[['user_id', 'book_id', 'rating']]
        processed_chunks.append(filtered_chunk)
        print(f"已处理第{idx+1}块,共{len(filtered_chunk)}条数据")
    
    # 如果合并后内存还够,就把块合并;不够的话后续就继续用分块方式处理
    df = pd.concat(processed_chunks, ignore_index=True)
    

    每次只加载一小部分数据,处理完就释放内存,不会一下子把RAM榨干。

  • 转成高效存储格式,后续加载更省心
    JSON是文本格式,本来就占内存大,不如先把数据转成列式存储的Parquet格式——它压缩率高、加载速度快,还能大幅节省存储空间。结合分块读取来操作:

    chunk_size = 1_000_000
    chunks = pd.read_json('/content/data/dataset.json', chunksize=chunk_size)
    
    # 逐块保存为Parquet文件
    for idx, chunk in enumerate(chunks):
        filtered_chunk = chunk[['user_id', 'book_id', 'rating']]
        filtered_chunk.to_parquet(f'/content/data/processed_chunk_{idx}.parquet')
        print(f"已保存第{idx+1}块Parquet文件")
    
    # 后续加载所有Parquet文件,速度会快很多
    import glob
    parquet_files = glob.glob('/content/data/processed_chunk_*.parquet')
    df = pd.concat([pd.read_parquet(file) for file in parquet_files], ignore_index=True)
    

    转成Parquet后,后续做协同过滤的预处理、模型训练都会顺畅不少。

  • 用Dask替代Pandas,专门处理大数据
    如果分块处理还是觉得麻烦,试试Dask吧——它是专门为大数据设计的库,API和Pandas几乎一模一样,但会自动把数据分成多个块,内存不够时就用磁盘缓存,完全不用担心溢出:

    import dask.dataframe as dd
    
    # Dask会自动分块读取JSON,不用手动设置chunksize
    ddf = dd.read_json('/content/data/dataset.json')
    
    # 只保留需要的列
    ddf = ddf[['user_id', 'book_id', 'rating']]
    
    # 做预处理直接用Dask的方法,比如统计每个用户的评分数量
    user_rating_count = ddf.groupby('user_id')['rating'].count().compute()
    
    # 训练协同过滤模型时,可以逐块喂数据,比如用Surprise库的话:
    for chunk in ddf.iterate_chunks():
        train_data = chunk.to_pandas()
        # 这里写你的模型训练代码,比如Surprise的Dataset.load_from_df()
    

    Dask会自动帮你管理内存和磁盘,不用自己操心分块的细节。

  • 升级Colab的RAM配置,临时扩容
    你还可以试试申请Colab的高RAM模式:点击右上角的“RAM/磁盘”图标,选择“请求更多RAM”,如果你的账号有资格,会切换到高RAM实例(一般有25GB左右)。另外,切换到GPU/TPU实例也会搭配更大的内存——在“运行时”->“更改运行时类型”里选择GPU或TPU,说不定能直接加载整个数据集(不过2.25亿条还是建议结合前面的方法)。

最后提一句,针对协同过滤的场景,其实不需要把整个数据集都放在内存里:比如基于邻域的方法可以分块计算相似度,隐式反馈模型(比如Implicit库)支持分块训练,矩阵分解用随机梯度下降的话,也可以逐批处理数据,不用一次性加载全部数据。

备注:内容来源于stack exchange,提问作者ayushhh_13

火山引擎 最新活动