You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何选择最多行实现列总和平衡?适配内存受限ML数据集

问题解答

有没有现成函数直接实现?

没有完全匹配场景的开箱即用函数。你的需求本质是带约束的组合优化问题:要在“三类正样本总和平衡(带容差)”的约束下,最大化选中的行数(或总样本量),这类问题没有通用的现成工具库函数,需要结合场景自定义实现。

基于Python常用库的实现思路(适配内存受限场景)

因为数据集无法全量载入内存,核心思路是分块处理+贪心/启发式策略(精确的组合优化算法对大数据集不现实,贪心是效率和效果平衡的选择),以下是具体方案:


1. 先明确平衡判断逻辑

先定义容差的量化规则,比如:

  • 设容差参数t(0 < t ≤ 1),要求三类总和的最大值与最小值的比例 ≤ 1 + t
  • 或者要求三类总和都围绕目标值(比如总样本量的1/3)在±t%的范围内

示例判断函数:

def is_balanced(sum1, sum2, sum3, tolerance=0.1):
    min_sum = min(sum1, sum2, sum3)
    max_sum = max(sum1, sum2, sum3)
    if min_sum == 0:
        # 避免除以0,仅当三类总和全为0时判定平衡
        return sum1 == sum2 == sum3 == 0
    return max_sum / min_sum <= 1 + tolerance

2. 分块统计全局总量

先扫一遍数据集(分块读取),计算三类正样本的全局总数量,方便后续设定平衡目标:

import pandas as pd

def calculate_global_totals(file_path, chunksize=10000):
    total1 = total2 = total3 = 0
    for chunk in pd.read_csv(file_path, chunksize=chunksize):
        total1 += chunk['n_positive_class1'].sum()
        total2 += chunk['n_positive_class2'].sum()
        total3 += chunk['n_positive_class3'].sum()
    return total1, total2, total3

3. 分块贪心筛选

边读取数据边筛选,优先保留能让三类总和更接近平衡的行,同时避免超出容差范围:

def balanced_selection(file_path, tolerance=0.1, chunksize=10000):
    # 先获取全局总量,确定平衡目标基准
    total1, total2, total3 = calculate_global_totals(file_path, chunksize)
    # 以全局最小类的总量为基准,留容差余量
    target_cap = min(total1, total2, total3) * (1 + tolerance)
    
    current1 = current2 = current3 = 0
    selected_ids = []
    # 可选:直接将选中行写入新文件,避免内存存储所有数据
    with open('selected_rows.csv', 'w') as f_out:
        f_out.write('Id,n_positive_class1,n_positive_class2,n_positive_class3\n')
    
    for chunk in pd.read_csv(file_path, chunksize=chunksize):
        for _, row in chunk.iterrows():
            # 模拟加入当前行后的总和
            new1 = current1 + row['n_positive_class1']
            new2 = current2 + row['n_positive_class2']
            new3 = current3 + row['n_positive_class3']
            
            # 满足平衡条件,或加入后未超出目标上限则保留
            if is_balanced(new1, new2, new3, tolerance) or max(new1, new2, new3) <= target_cap:
                selected_ids.append(row['Id'])
                current1, current2, current3 = new1, new2, new3
                # 直接写入文件,减少内存占用
                with open('selected_rows.csv', 'a') as f_out:
                    f_out.write(f"{row['Id']},{row['n_positive_class1']},{row['n_positive_class2']},{row['n_positive_class3']}\n")
    
    return selected_ids, current1, current2, current3

4. 优化方向(可选)

  • 偏差优先筛选:如果当前某类总和远低于其他类,优先选择该类正样本数多的行,加快平衡速度
  • Dask替代Pandas:如果数据集极大,用Dask替代Pandas分块,支持并行处理和更大规模数据的内存友好操作
  • 迭代调整:如果内存允许存储少量选中行的信息,可在筛选后期剔除部分导致失衡的行,进一步优化平衡度

内容的提问来源于stack exchange,提问作者user11696358

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:35:36