Sklearn RandomForestRegressor预测结果全为相同值问题排查
Random Forest Regressor 全量预测固定值异常排查
问题现象
基于DataFrame存储的约600万条数据构建随机森林回归模型时,所有预测结果均返回同一固定值,结果不符合预期。在多台不同计算机运行完全相同的代码,仅1台设备运行正常,其余设备均复现该异常,初步判断为模型未完成有效数据拟合导致预测值无差异,但未定位根因与修复方法。
数据集样例
本次使用的建模数据集共87684行×25列,样例如下:
1-M_AE_nT SYM/H_INDEX_nT Sec CLat SLat SLon Height STime DipLat MagLon ... DenUncertainty NuminBin NuminBinThrusters AveDragCoef year month day hour minute second 1 250.0 -10.0 20.0 -27.0 -26.01869 91.17059 485.397 6.0800 -37.49094 159.49559 ... 2.525557e-14 3.0 0.0 2.985 2003 10 1 0 1 0 2 267.0 -10.0 70.0 -30.0 -29.21327 91.03207 486.025 6.0846 -40.90827 158.48730 ... 2.581399e-14 5.0 0.0 2.997 2003 10 1 0 2 0 3 268.0 -10.0 142.5 -33.0 -33.84216 90.83946 487.036 6.0919 -45.80439 156.77887 ... 2.583156e-14 4.0 0.0 3.022 2003 10 1 0 3 0 4 259.0 -10.0 212.5 -39.0 -38.30748 90.66537 488.104 6.0998 -50.44992 154.80710 ... 2.503691e-14 6.0 3.0 3.043 2003 10 1 0 4 0 5 252.0 -10.0 287.5 -42.0 -43.08716 90.49610 489.312 6.1093 -55.31874 152.26286 ... 2.665537e-14 2.0 2.0 3.066 2003 10 1 0 5 0 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 87835 391.0 -22.0 86055.0 -60.0 -59.68290 25.61019 514.969 1.6079 -58.43060 73.24151 ... 3.849055e-14 7.0 0.0 3.190 2003 11 30 23 55 0 87836 377.0 -22.0 86155.0 -66.0 -65.98446 25.71737 516.534 1.6428 -62.40535 67.35048 ... 4.443331e-14 9.0 0.0 3.247 2003 11 30 23 56 0 87837 351.0 -22.0 86202.5 -69.0 -68.97452 25.87007 517.088 1.6662 -64.30795 64.06817 ... 4.598777e-14 10.0 0.0 3.274 2003 11 30 23 57 0 87838 337.0 -22.0 86250.0 -72.0 -71.96241 26.13300 517.510 1.6969 -66.20866 60.33311 ... 4.745023e-14 9.0 0.0 3.304 2003 11 30 23 58 0 87839 319.0 -22.0 86297.5 -75.0 -74.94779 26.57178 517.795 1.7394 -68.08806 56.00031 ... 4.916760e-14 10.0 0.0 3.336 2003 11 30 23 59 0 87684 rows × 25 columns
原始实现代码
target = np.array(merged_df["400kmDensity"]) merged_df = merged_df.drop("400kmDensity", axis = 1) features_list = list(merged_df.columns) #df = np.array(merged_df) #Set training and testing groups train_features, test_features, train_target, test_target = train_test_split(merged_df, target, test_size = 0.2, random_state = 16) #Train model rf = RandomForestRegressor(n_estimators = 150, random_state = 16) rf.fit(train_features, train_target) #Make predictions and calculate error predictions = rf.predict(test_features) print(predictions)
异常输出
模型预测结果全为同一固定值,输出如下:
array([3.43048358e-12, 3.43048358e-12, 3.43048358e-12, ..., 3.43048358e-12, 3.43048358e-12, 3.43048358e-12])
根因定位
该固定值本质是训练集目标列的均值,说明模型完全没有完成有效特征分裂,所有决策树都退化为返回训练集均值,结合多设备运行结果不一致的特征,核心诱因有三类:
- 依赖版本不兼容:异常设备安装的scikit-learn、numpy版本存在已知bug,在处理含缺失值、无穷值或非数值类型特征时不会抛出显式报错,直接导致树分裂逻辑失效;仅正常运行的设备安装了无该问题的版本。
- 数据类型识别异常:异常设备上读取数据时,部分数值列被错误识别为
object类型(比如列中混入字符串格式的空值、异常特殊字符),模型无法基于非数值特征计算分裂阈值,导致拟合失效。 - 数据异常未清洗:特征或目标列存在大量NaN、inf值,旧版模型不会主动拦截这类异常输入,直接导致分裂失败。
修复方案
按以下步骤逐步排查修复:
- 先验证固定值是否为训练集均值,确认故障类型
# 输出值如果和预测固定值完全一致,即可确认模型退化为返回均值 print(train_target.mean()) - 全量排查数据异常
运行以下代码检查数据质量,对发现的缺失值、无穷值做填充或删除,对非数值列做类型转换、清洗异常字符:# 统计缺失值、无穷值数量 print("特征缺失值总数:", merged_df.isna().sum().sum()) print("特征无穷值总数:", np.isinf(merged_df.select_dtypes(include=np.number)).sum().sum()) print("目标列缺失/无穷值总数:", np.isnan(target).sum() + np.isinf(target).sum()) # 检查所有列的数据类型,排查是否存在object类型的数值列 print(merged_df.dtypes) - 统一跨设备依赖版本
查看正常运行设备的scikit-learn、numpy、pandas版本,在异常设备上安装完全匹配的版本,查看版本命令如下:import sklearn, numpy, pandas print(f"sklearn: {sklearn.__version__}, numpy: {numpy.__version__}, pandas: {pandas.__version__}") - 显式转换数据格式避免识别错误
不要直接传入pandas DataFrame对象给模型,先显式转换为float64格式的numpy数组,修改数据拆分部分代码:# 显式转换为纯数值数组 X = merged_df.to_numpy(dtype=np.float64) y = target.astype(np.float64) train_features, test_features, train_target, test_target = train_test_split(X, y, test_size = 0.2, random_state = 16) - 拟合后校验模型有效性
训练完成后检查决策树深度,如果所有树深度都≤1,说明分裂仍然失效,回到前面步骤重新排查:# 打印前5棵树的深度,正常拟合的树深度应该远大于1 print([tree.get_depth() for tree in rf.estimators_[:5]])
内容的提问来源于stack exchange,提问作者collegestudent8
相关产品推荐
相关产品推荐

