如何选择最多行实现列总和平衡?适配内存受限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
相关产品推荐
相关产品推荐

