Scikit-learn线性回归触发Scipy MatReadWarning问题排查
Scipy读取.mat文件触发MatReadWarning的问题解析
环境与问题现象
使用版本:scikit-learn 1.2.2,scipy 1.10.1
运行代码时触发如下警告:
packages\scipy\io\matlab_mio.py:227: MatReadWarning: Duplicate variable name "None" in stream - replacing previous with new Consider mio5.varmats_from_mat to split file into single variable files
matfile_dict = MR.get_variables(variable_names)
但.mat文件中不存在名为None的变量,且测试发现:
- 注释掉sklearn的
LinearRegression调用代码后,警告完全消失 - 启用
time.sleep(1)时,每个循环都会触发警告 - 注释
sleep后,警告出现时机随机,多集中在多次循环后
核心疑问解答
1. 为何调用sklearn会影响Scipy读取.mat文件?
这是内存污染/内存重叠导致的:
- scipy读取.mat文件依赖底层C扩展库(如libmatio),会使用临时内存缓冲区存储文件解析的中间数据
- sklearn的
LinearRegression训练过程会进行大量内存分配、释放操作(矩阵运算、参数存储等),如果内存出现碎片或野指针,可能会覆盖scipy的临时缓冲区,导致解析时把内存中的垃圾数据误识别为变量名None - numpy作为两者共同依赖的库,数组操作的内存共享机制也可能间接引发内存区域意外重叠,加剧这个问题
2. 警告为何不在加载时触发?
因为scipy的loadmat采用延迟解析机制:
- 调用
loadmat时仅读取文件头信息,不会立刻解析所有变量内容 - 只有当实际访问变量(如
mat['x'])或内部调用get_variables时,才会完整解析文件流 - 而sklearn的代码执行在
loadmat之后,此时内存状态已被改变,scipy后续解析时才触发警告
3. 为何警告提示使用已废弃的mio5.varmats_from_mat方法?
这是scipy版本迭代的历史遗留问题:
mio5是scipy旧版本中处理.mat文件的模块,varmats_from_mat原本用于拆分多变量.mat文件,解决重复变量名问题- 在scipy 1.10.x版本中,该模块已被标记为废弃,替换为更高效的新解析逻辑,但警告信息未同步更新,依然保留了旧方法的提示
内容的提问来源于stack exchange,提问作者Chemistpp
相关产品推荐
相关产品推荐

