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

使用.dropna()后数据集尺寸不一致的处理方案咨询

解决训练/测试集DropNA后尺寸不一致及后续报错问题

核心问题分析

你遇到的两个报错,根源主要有三点:

  1. 训练集与测试集独立DropNA导致样本量不匹配:单独对训练集和测试集执行df.dropna(inplace=True),会因两边缺失值分布不同,导致最终样本数差异,后续绘图和模型调用时出现维度冲突。
  2. 绘图代码中数组维度不匹配:x1是一维数组((48571,)),而xmodel是二维特征矩阵((48470,9)),直接np.hstack会因维度不一致触发ValueError。
  3. OLS模型使用逻辑错误:你直接用未拟合的reg_model调用predict,且用测试集训练模型再预测测试集的逻辑不符合机器学习流程(应该用训练集训练,测试集评估)。

分步解决方案

1. 统一处理缺失值,保证特征维度一致

不要分别对训练集和测试集执行DropNA,推荐两种合理的处理方式:

方案A(优先推荐:保留有效测试样本)

先处理训练集的缺失值,再单独过滤测试集中的缺失样本,保证两者特征维度一致:

# 处理训练集:DropNA并同步标签
X_train_clean = X_train.dropna()
y_train_clean = y_train.loc[X_train_clean.index]

# 处理测试集:仅保留无缺失值的样本
X_test_clean = X_test.dropna()
y_test_clean = y_test.loc[X_test_clean.index]

# 验证特征维度(列数必须一致)
print(f"训练集形状:{X_train_clean.shape}")
print(f"测试集形状:{X_test_clean.shape}")

这种方式不会强制对齐训练/测试集的样本数,而是保留各自的有效样本,符合机器学习评估的逻辑。

方案B(合并后统一清理)

如果希望尽量保留样本,可先合并训练和测试集,统一DropNA后再拆分回原分组:

# 给数据集打标签,方便后续拆分
X_train['data_type'] = 'train'
X_test['data_type'] = 'test'
y_train['data_type'] = 'train'
y_test['data_type'] = 'test'

# 合并数据
X_combined = pd.concat([X_train, X_test])
y_combined = pd.concat([y_train, y_test])

# 统一DropNA
X_combined_clean = X_combined.dropna()
y_combined_clean = y_combined.loc[X_combined_clean.index]

# 拆分回训练/测试集
X_train_clean = X_combined_clean[X_combined_clean['data_type'] == 'train'].drop('data_type', axis=1)
y_train_clean = y_combined_clean[y_combined_clean['data_type'] == 'train'].drop('data_type', axis=1)
X_test_clean = X_combined_clean[X_combined_clean['data_type'] == 'test'].drop('data_type', axis=1)
y_test_clean = y_combined_clean[y_combined_clean['data_type'] == 'test'].drop('data_type', axis=1)

2. 修正绘图代码,解决维度不匹配问题

想要绘制类似statsmodels示例的拟合/预测图,需要将所有绘图用的数组统一为一维,同时区分训练集和测试集的展示范围:

import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

# 生成训练集和测试集的x轴变量(用连续区间区分)
x_train = np.linspace(0, 1, len(X_train_clean))
x_test = np.linspace(1, 2, len(X_test_clean))

# 训练OLS模型(注意添加截距项,statsmodels默认不含)
X_train_with_intercept = sm.add_constant(X_train_clean)
model = sm.OLS(y_train_clean, X_train_with_intercept)
results = model.fit()

# 得到训练集拟合值和测试集预测值
y_train_pred = results.predict(X_train_with_intercept)
X_test_with_intercept = sm.add_constant(X_test_clean)
y_test_pred = results.predict(X_test_with_intercept)

# 绘图
fig, ax = plt.subplots(figsize=(10,6))
ax.plot(x_train, y_train_clean, 'o', alpha=0.5, label="Training Data")
ax.plot(x_train, y_train_pred, 'b-', label="OLS Fit (Training)")
ax.plot(x_test, y_test_clean, 's', alpha=0.5, label="Test Data")
ax.plot(x_test, y_test_pred, 'r-', label="OLS Prediction (Test)")
ax.legend(loc="best")
ax.set_xlabel("Sample Range")
ax.set_ylabel("Target Value");

3. 修正OLS模型评估代码,计算RMSE

你需要用训练好的模型预测测试集,再计算评估指标,代码逻辑如下:

from sklearn.metrics import mean_squared_error

# 用训练好的模型预测测试集
y_test_pred = results.predict(X_test_with_intercept)

# 计算RMSE(squared=False返回RMSE,True返回MSE)
ols_rmse = mean_squared_error(y_test_clean, y_test_pred, squared=False)
print(f"OLS RMSE on Test Set: {ols_rmse:.4f}")

这样就能得到OLS模型在测试集上的RMSE,方便和logit/lasso/SVC等模型的评估结果对比。

额外注意事项

  • 禁止在测试集上训练模型:你的原代码中用测试集训练reg_test是错误的,完全失去了模型评估的意义,必须用训练集训练模型,测试集仅用于评估。
  • 缺失值处理的一致性:如果选择填充缺失值(而非DropNA),必须用训练集的统计量(均值/中位数)填充测试集,避免数据泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:37:19