数据分析中,如何使用回归模型进行预测?如何评估模型的预测效果?
2026/7/1 20:32:34 网站建设 项目流程

回归模型预测与效果评估

一、回归预测全流程

原始数据 ↓ 1. 理解业务 → 明确目标变量和特征 ↓ 2. 数据预处理 → 缺失值/异常值/编码/标准化 ↓ 3. 探索性分析 → 相关性/分布/散点图 ↓ 4. 特征工程 → 筛选/构造/转换 ↓ 5. 划分数据集 → 训练集 / 验证集 / 测试集 ↓ 6. 选择模型 → 训练 → 调参 ↓ 7. 评估模型 → 多维度指标 ↓ 8. 模型上线 → 持续监控

二、常用回归模型

模型特点适用场景
线性回归简单可解释,假设强线性关系、需解释性
Ridge/Lasso正则化防过拟合多特征、需特征选择
决策树回归非线性,可解释非线性、混合类型特征
随机森林集成,鲁棒强通用,默认选择
XGBoost/LightGBM集成,精度高表格数据竞赛级首选
SVR核函数非线性小样本非线性
神经网络任意非线性大样本复杂关系

实战:训练多个回归模型

importpandasaspdimportnumpyasnpfromsklearn.model_selectionimporttrain_test_split,cross_val_scorefromsklearn.preprocessingimportStandardScalerfromsklearn.linear_modelimportLinearRegression,Ridge,Lassofromsklearn.ensembleimportRandomForestRegressor,GradientBoostingRegressorfromsklearn.metricsimportmean_squared_error,mean_absolute_error,r2_score# 1. 数据准备X=df.drop('target',axis=1)y=df['target']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# 2. 标准化(线性模型需要,树模型不需要)scaler=StandardScaler()X_train_scaled=scaler.fit_transform(X_train)X_test_scaled=scaler.transform(X_test)# 3. 训练多个模型models={'Linear':LinearRegression(),'Ridge':Ridge(alpha=1.0),'Lasso':Lasso(alpha=0.01),'RF':RandomForestRegressor(n_estimators=200,random_state=42),'GBR':GradientBoostingRegressor(n_estimators=200,random_state=42),}results={}forname,modelinmodels.items():ifnamein['Linear','Ridge','Lasso']:model.fit(X_train_scaled,y_train)y_pred=model.predict(X_test_scaled)else:model.fit(X_train,y_train)y_pred=model.predict(X_test)results[name]={'RMSE':np.sqrt(mean_squared_error(y_test,y_pred)),'MAE':mean_absolute_error(y_test,y_pred),'R²':r2_score(y_test,y_pred),}pd.DataFrame(results).T.sort_values('RMSE')

三、模型评估指标

1. 回归核心指标

指标公式含义越好
MAE(1/n)Σ|yᵢ - ŷᵢ|平均绝对误差
MSE(1/n)Σ(yᵢ - ŷᵢ)²均方误差
RMSE√MSE均方根误差
1 - SS_res/SS_tot解释方差比例
MAPE(1/n)Σ|yᵢ - ŷᵢ|/yᵢ × 100%平均绝对百分比误差
Adjusted R²R²校正版校正特征数的R²
fromsklearn.metricsimportmean_squared_error,mean_absolute_error,r2_score y_pred=model.predict(X_test)rmse=np.sqrt(mean_squared_error(y_test,y_pred))mae=mean_absolute_error(y_test,y_pred)r2=r2_score(y_test,y_pred)mape=np.mean(np.abs((y_test-y_pred)/y_test))*100print(f"RMSE:{rmse:.4f}")print(f"MAE:{mae:.4f}")print(f"R²:{r2:.4f}")print(f"MAPE:{mape:.2f}%")

2. 各指标选择逻辑

RMSE — 最常用,对大误差敏感(惩罚力度大) 适合:大误差代价高的场景(如金融预测) MAE — 对异常值鲁棒,直觉可解释 适合:存在异常值、需业务解释的场景 R² — 模型解释力,0.8 = 解释了80%的方差 适合:比较不同模型的相对表现 MAPE — 相对误差,与量纲无关 适合:不同量纲目标变量的跨场景比较 注意:y 接近 0 时会爆炸 Adjusted R² — 对加特征自动惩罚 适合:多特征模型比较,防止过拟合假象

3. R² 的解读与陷阱

R² = 0.90 → 模型解释了 90% 的方差 R² = 0.50 → 模型解释了 50%,另一半由未捕捉的因素决定 R² < 0 → 模型比直接用均值预测还差(严重过拟合/模型错误) 陷阱: - 特征越多 R² 一定越高(哪怕是噪声特征)→ 用 Adjusted R² - R² 高不等于预测准(可能只是训练集上高,测试集低) - 不同数据分布下的 R² 不可直接比较

四、交叉验证 — 更可靠的评估

单次 train/test split 有随机性,交叉验证更稳健。

K折交叉验证

fromsklearn.model_selectionimportcross_val_score,KFold model=RandomForestRegressor(n_estimators=200,random_state=42)# 5折交叉验证kf=KFold(n_splits=5,shuffle=True,random_state=42)# 默认返回 R²scores_r2=cross_val_score(model,X,y,cv=kf,scoring='r2')print(f"R²:{scores_r2.mean():.4f}±{scores_r2.std():.4f}")# 换成 RMSEscores_rmse=cross_val_score(model,X,y,cv=kf,scoring='neg_root_mean_squared_error')print(f"RMSE:{-scores_rmse.mean():.4f}±{scores_rmse.std():.4f}")# 换成 MAEscores_mae=cross_val_score(model,X,y,cv=kf,scoring='neg_mean_absolute_error')print(f"MAE:{-scores_mae.mean():.4f}±{-scores_mae.std():.4f}")

学习曲线 — 诊断过拟合/欠拟合

fromsklearn.model_selectionimportlearning_curveimportmatplotlib.pyplotasplt train_sizes,train_scores,val_scores=learning_curve(model,X,y,cv=5,train_sizes=np.linspace(0.1,1.0,10),scoring='neg_root_mean_squared_error',random_state=42)train_rmse=-train_scores.mean(axis=1)val_rmse=-val_scores.mean(axis=1)plt.plot(train_sizes,train_rmse,label='Train RMSE')plt.plot(train_sizes,val_rmse,label='Val RMSE')plt.xlabel('Training Size')plt.ylabel('RMSE')plt.legend()plt.show()# 诊断:# Train低 Val高 且差距大 → 过拟合(加正则/减特征/加数据)# Train高 Val高 且都高 → 欠拟合(加特征/换更强模型)# 两者接近且低 → 理想

五、残差分析 — 深度诊断

残差 = y_true - y_pred,是模型"没学到的部分"。

residuals=y_test-y_pred# 1. 残差 vs 预测值散点图plt.scatter(y_pred,residuals,alpha=0.5)plt.axhline(y=0,color='r',linestyle='--')plt.xlabel('Predicted')plt.ylabel('Residual')plt.title('Residual Plot')plt.show()# 健康残差:随机散布在0附近,无明显图案# 问题信号:# 漏斗形 → 方差不等,需对 y 做变换(log)# 曲线形 → 遗漏了非线性关系,加多项式特征# 聚簇 → 某个子群体模型表现差,需分层建模
# 2. 残差正态性检验(线性回归假设)importscipy.statsasstats stats.probplot(residuals,plot=plt)plt.show()# Shapiro-Wilk 检验stat,p=stats.shapiro(residuals)print(f"残差正态性 p ={p:.4f}")# p > 0.05 → 近似正态
# 3. 预测值 vs 真实值散点图plt.scatter(y_test,y_pred,alpha=0.5)plt.plot([y_test.min(),y_test.max()],[y_test.min(),y_test.max()],'r--')plt.xlabel('Actual')plt.ylabel('Predicted')plt.title('Actual vs Predicted')plt.show()# 理想:点沿对角线密集分布# 偏离对角线 → 系统性偏差

六、超参数调优

fromsklearn.model_selectionimportGridSearchCV,RandomizedSearchCV# Grid Search — 精确但慢param_grid={'n_estimators':[100,200,500],'max_depth':[5,10,20,None],'min_samples_split':[2,5,10],'learning_rate':[0.01,0.05,0.1],}gbr=GradientBoostingRegressor(random_state=42)grid=GridSearchCV(gbr,param_grid,cv=5,scoring='neg_root_mean_squared_error',n_jobs=-1)grid.fit(X_train,y_train)print(f"最优参数:{grid.best_params_}")print(f"最优 RMSE:{-grid.best_score_:.4f}")# Random Search — 快速近似fromscipy.statsimportrandint,uniform param_dist={'n_estimators':randint(100,1000),'max_depth':randint(3,30),'learning_rate':uniform(0.01,0.2),}random_search=RandomizedSearchCV(gbr,param_dist,n_iter=50,cv=5,scoring='neg_root_mean_squared_error',random_state=42,n_jobs=-1)random_search.fit(X_train,y_train)

七、完整实战模板

importpandasaspdimportnumpyasnpfromsklearn.model_selectionimporttrain_test_split,cross_val_score,KFoldfromsklearn.preprocessingimportStandardScalerfromsklearn.linear_modelimportRidgefromsklearn.ensembleimportGradientBoostingRegressorfromsklearn.metricsimportmean_squared_error,mean_absolute_error,r2_scoreimportmatplotlib.pyplotaspltimportscipy.statsasstats# ===== 1. 数据准备 =====X=df.drop('price',axis=1)y=df['price']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# ===== 2. 预处理 =====scaler=StandardScaler()X_train_s=scaler.fit_transform(X_train)X_test_s=scaler.transform(X_test)# ===== 3. 训练模型 =====model=GradientBoostingRegressor(n_estimators=300,max_depth=5,learning_rate=0.05,random_state=42)model.fit(X_train,y_train)# ===== 4. 预测 =====y_pred=model.predict(X_test)# ===== 5. 评估指标 =====print(f"RMSE:{np.sqrt(mean_squared_error(y_test,y_pred)):.4f}")print(f"MAE:{mean_absolute_error(y_test,y_pred):.4f}")print(f"R²:{r2_score(y_test,y_pred):.4f}")print(f"MAPE:{np.mean(np.abs((y_test-y_pred)/y_test))*100:.2f}%")# ===== 6. 交叉验证 =====kf=KFold(n_splits=5,shuffle=True,random_state=42)cv_scores=cross_val_score(model,X,y,cv=kf,scoring='r2')print(f"CV R²:{cv_scores.mean():.4f}±{cv_scores.std():.4f}")# ===== 7. 残差诊断 =====residuals=y_test-y_pred fig,axes=plt.subplots(1,3,figsize=(18,5))# 残差散点axes[0].scatter(y_pred,residuals,alpha=0.5)axes[0].axhline(0,color='r',ls='--')axes[0].set(xlabel='Predicted',ylabel='Residual',title='Residual Plot')# 正态Q-Qstats.probplot(residuals,plot=axes[1])axes[1].set_title('Q-Q Plot')# 实际 vs 预测axes[2].scatter(y_test,y_pred,alpha=0.5)lims=[min(y_test.min(),y_pred.min()),max(y_test.max(),y_pred.max())]axes[2].plot(lims,lims,'r--')axes[2].set(xlabel='Actual',ylabel='Predicted',title='Actual vs Predicted')plt.tight_layout()plt.show()# ===== 8. 特征重要性 =====imp=pd.Series(model.feature_importances_,index=X.columns).sort_values(ascending=True)imp.plot.barh(title='Feature Importance')plt.show()

速查总结

回归预测四步法: 1. 训练:选模型 → fit → predict 2. 评估: RMSE — 总体误差(惩罚大偏差) MAE — 平均偏差(鲁棒) R² — 解释力 MAPE — 相对误差 3. 诊断: 学习曲线 → 欠拟合/过拟合 残差图 → 遗漏的非线性/异方差 Q-Q图 → 正态性假设 4. 优化: 交叉验证 → 稳健评估 超参数搜索 → 最优配置 特征工程 → 补充信息 一句话:RMSE看误差,R²看解释力, 残差图查遗漏,交叉验证防过拟合。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询