使用R语言的plot函数可视化预测值和实际值的线图对比

100 篇文章 ¥59.90 ¥99.00
本文介绍了如何使用R语言的plot函数来可视化预测值和实际值的线图对比,以便评估模型性能。通过创建实际值和预测值向量,用蓝色线条绘制实际值,红色线条绘制预测值,对比曲线可直观展现模型的准确性。如果曲线重合度高,表明模型预测效果好;否则,可能需要模型优化。

使用R语言的plot函数可视化预测值和实际值的线图对比

在数据分析和机器学习任务中,对比预测值和实际值的曲线可以帮助我们评估模型的性能和准确性。在R语言中,我们可以使用plot函数来绘制这样的线图对比。本文将介绍如何使用plot函数来可视化预测值和实际值的曲线对比。

首先,我们需要准备一组实际值和对应的预测值。假设我们有一个名为actual_values的实际值向量和一个名为predicted_values的预测值向量。接下来,我们可以使用以下代码来绘制线图对比:

# 创建实际值和预测值向量
actual_values <- c(1, 2, 3, 4, 5)
predicted_values <- c(1.2, 1.8, 3.2, 3.5, 4.7)

# 绘制线图对比
plot(actual_values, type = "l", col = "blue", ylim = c(min(actual_values, predicted_values), max(actual_values, predicted_values)))
lines(predicted_values, col = "red")
legend("topleft", legend = c("Actual Values", "Predicted Values"), col = c("blue", "red"), lty = 1)

在上述代码中,我们首先创建了actual_values和predicted_values两个向量,并分别赋值为实际值和预测值。然后,我们使用plot函数绘制了实际值的线图,其中type参数设置为"l"表示绘制线条,

<think>我们将添加两个主要功能:1.计算评估指标:在模型训练验证过程中,除了损失函数(MSE)外,我们还将计算其他常用指标,如MAE、RMSE、R²。2.预测值实际对比可视化:在训练结束后,我们将绘制训练过程中的损失曲线,并在验证集上绘制预测值实际对比图。修改点: -在训练函数中,除了计算损失,还将计算其他评估指标。 -添加一个函数用于在验证集上生成预测结果,并计算多种评估指标。 -添加可视化函数,绘制训练验证的损失曲线,以及验证集上预测值实际对比散点图或折线图。注意:由于我们的数据是按时间序列的,因此在可视化时应该按时间顺序绘制。步骤:1.定义计算评估指标的函数。2.在训练循环中收集每个epoch的评估指标(训练验证集)。3.训练结束后,在验证集上生成预测结果并绘制对比图。4.绘制训练过程中的损失曲线评估指标曲线。我们将修改训练函数,使其返回训练过程中的历史记录(包括损失其他指标),并添加可视化代码。</think>### 添加评估指标可视化功能的交通预测系统 以下是完整的改进代码,添加了以下关键功能: 1. **评估指标计算**:训练过程中实时计算RMSE、MAE、R²等指标 2. **预测可视化**:训练后生成预测值实际对比图表 3. **训练过程监控**:实时绘制损失曲线评估指标变化 ```python import pandas as pd import numpy as np import chinese_calendar as cal import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score import matplotlib.pyplot as plt from datetime import timedelta import seaborn as sns import time # 设置matplotlib支持中文 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 # 1. 支持日粒度的特征工程类(保持不变) class DailyChinaFeatureEngineer: # 之前相同,此处省略以节省空间 # ... # 2. 时间序列数据集类(保持不变) class DailyTrafficDataset(Dataset): # 之前相同,此处省略以节省空间 # ... # 3. LSTM预测模型(保持不变) class TrafficLSTM(nn.Module): # 之前相同,此处省略以节省空间 # ... # 4. 交通预测器类(保持不变) class DailyTrafficPredictor: # 之前相同,此处省略以节省空间 # ... # 5. 评估指标计算类 class EvaluationMetrics: @staticmethod def calculate_metrics(y_true, y_pred): """ 计算多种评估指标 参数: y_true -- 实际数组 y_pred -- 预测值数组 返回: 包含各种指标的字典 """ metrics = {} # 均方根误差 (RMSE) metrics['rmse'] = np.sqrt(mean_squared_error(y_true, y_pred)) # 平均绝对误差 (MAE) metrics['mae'] = mean_absolute_error(y_true, y_pred) # 决定系数 (R²) metrics['r2'] = r2_score(y_true, y_pred) # 平均绝对百分比误差 (MAPE) epsilon = 1e-10 # 避免除以零 mape = np.mean(np.abs((y_true - y_pred) / (y_true + epsilon))) * 100 metrics['mape'] = mape # 对称平均绝对百分比误差 (sMAPE) smape = np.mean(2 * np.abs(y_true - y_pred) / (np.abs(y_true) + np.abs(y_pred) + epsilon)) * 100 metrics['smape'] = smape # 最大误差 metrics['max_error'] = np.max(np.abs(y_true - y_pred)) return metrics @staticmethod def print_metrics(metrics, title="评估指标"): """打印评估指标""" print(f"\n{title}:") print("-" * 50) print(f"均方根误差 (RMSE): {metrics['rmse']:.4f}") print(f"平均绝对误差 (MAE): {metrics['mae']:.4f}") print(f"平均绝对百分比误差 (MAPE): {metrics['mape']:.2f}%") print(f"对称平均绝对百分比误差 (sMAPE): {metrics['smape']:.2f}%") print(f"决定系数 (R²): {metrics['r2']:.4f}") print(f"最大误差: {metrics['max_error']:.4f}") print("-" * 50) # 6. 可视化工具类 class VisualizationTools: @staticmethod def plot_training_history(history, save_path=None): """ 绘制训练历史图表 参数: history -- 包含训练历史的字典 save_path -- 图表保存路径(可选) """ plt.figure(figsize=(15, 10)) # 绘制损失曲线 plt.subplot(2, 2, 1) plt.plot(history['train_loss'], label='训练损失') plt.plot(history['val_loss'], label='验证损失') plt.title('训练验证损失') plt.xlabel('Epoch') plt.ylabel('损失 (MSE)') plt.legend() plt.grid(True) # 绘制RMSE曲线 plt.subplot(2, 2, 2) plt.plot(history['train_rmse'], label='训练RMSE') plt.plot(history['val_rmse'], label='验证RMSE') plt.title('训练验证RMSE') plt.xlabel('Epoch') plt.ylabel('RMSE') plt.legend() plt.grid(True) # 绘制R²曲线 plt.subplot(2, 2, 3) plt.plot(history['train_r2'], label='训练R²') plt.plot(history['val_r2'], label='验证R²') plt.title('训练验证R²') plt.xlabel('Epoch') plt.ylabel('R²') plt.legend() plt.grid(True) # 绘制MAPE曲线 plt.subplot(2, 2, 4) plt.plot(history['train_mape'], label='训练MAPE') plt.plot(history['val_mape'], label='验证MAPE') plt.title('训练验证MAPE') plt.xlabel('Epoch') plt.ylabel('MAPE (%)') plt.legend() plt.grid(True) plt.tight_layout() if save_path: plt.savefig(save_path) plt.show() @staticmethod def plot_predictions_vs_actual(y_true, y_pred, timestamps=None, save_path=None): """ 绘制预测值实际对比图 参数: y_true -- 实际数组 y_pred -- 预测值数组 timestamps -- 时间戳数组(可选) save_path -- 图表保存路径(可选) """ plt.figure(figsize=(15, 8)) # 如果提供了时间戳,按时间排序 if timestamps is not None: sorted_indices = np.argsort(timestamps) y_true = y_true[sorted_indices] y_pred = y_pred[sorted_indices] timestamps = timestamps[sorted_indices] # 绘制预测值实际的折线图 if timestamps is not None: plt.plot(timestamps, y_true, 'b-', label='实际', alpha=0.7) plt.plot(timestamps, y_pred, 'r--', label='预测值', alpha=0.9) plt.gcf().autofmt_xdate() # 自动旋转日期标签 else: plt.plot(y_true, 'b-', label='实际', alpha=0.7) plt.plot(y_pred, 'r--', label='预测值', alpha=0.9) plt.title('预测值实际对比') plt.xlabel('时间' if timestamps else '样本索引') plt.ylabel('交通量') plt.legend() plt.grid(True) # 添加45度线(理想预测线) min_val = min(np.min(y_true), np.min(y_pred)) max_val = max(np.max(y_true), np.max(y_pred)) plt.plot([min_val, max_val], [min_val, max_val], 'g--', alpha=0.3, label='理想预测') plt.tight_layout() if save_path: plt.savefig(save_path) plt.show() @staticmethod def plot_error_distribution(y_true, y_pred, save_path=None): """ 绘制预测误差分布图 参数: y_true -- 实际数组 y_pred -- 预测值数组 save_path -- 图表保存路径(可选) """ errors = y_pred - y_true abs_errors = np.abs(errors) plt.figure(figsize=(15, 6)) # 误差分布直方图 plt.subplot(1, 2, 1) sns.histplot(errors, kde=True, bins=30) plt.title('预测误差分布') plt.xlabel('预测误差 (预测值 - 实际)') plt.ylabel('频率') plt.axvline(x=0, color='r', linestyle='--', alpha=0.5) # 绝对误差分布 plt.subplot(1, 2, 2) sns.boxplot(x=abs_errors) plt.title('绝对误差分布') plt.xlabel('绝对误差 |预测值 - 实际|') plt.tight_layout() if save_path: plt.savefig(save_path) plt.show() @staticmethod def plot_feature_importance(model, feature_names, save_path=None): """ 绘制特征重要性图(基于模型权重) 参数: model -- 训练好的模型 feature_names -- 特征名称列表 save_path -- 图表保存路径(可选) """ # 获取LSTM层权重 lstm_weights = model.lstm.weight_ih_l0.detach().cpu().numpy() # 计算特征重要性(平均绝对权重) feature_importance = np.mean(np.abs(lstm_weights), axis=0) # 归一化 feature_importance = feature_importance / np.sum(feature_importance) # 排序 sorted_idx = np.argsort(feature_importance) plt.figure(figsize=(12, 8)) plt.barh(range(len(feature_names)), feature_importance[sorted_idx], align='center') plt.yticks(range(len(feature_names)), np.array(feature_names)[sorted_idx]) plt.title('特征重要性 (基于LSTM输入权重)') plt.xlabel('相对重要性') plt.tight_layout() if save_path: plt.savefig(save_path) plt.show() # 7. 添加评估指标可视化的训练函数 def train_model_with_metrics_and_viz( data: pd.DataFrame, city_tier=1, max_epochs=100, batch_size=32, patience=5, min_delta=0.001, plot_interval=5 ): """ 带评估指标可视化的模型训练 参数: data -- 训练数据 city_tier -- 城市分级 max_epochs -- 最大训练轮数 batch_size -- 批次大小 patience -- 早停耐心 min_delta -- 视为改善的最小变化量 plot_interval -- 可视化间隔(每多少轮显示一次) """ # 初始化特征工程 feature_engineer = DailyChinaFeatureEngineer(city_tier=city_tier) feature_engineer.fit(data) # 创建数据集 dataset = DailyTrafficDataset(data, feature_engineer) # 划分训练集验证集 train_size = int(0.8 * len(dataset)) val_size = len(dataset) - train_size train_dataset, val_dataset = torch.utils.data.random_split( dataset, [train_size, val_size] ) # 创建数据加载器 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=batch_size) # 初始化模型 input_size = len(feature_engineer.feature_columns) model = TrafficLSTM(input_size=input_size) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) # 定义损失函数优化器 criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练历史记录 history = { 'epoch': [], 'train_loss': [], 'val_loss': [], 'train_rmse': [], 'val_rmse': [], 'train_mae': [], 'val_mae': [], 'train_r2': [], 'val_r2': [], 'train_mape': [], 'val_mape': [], 'time_per_epoch': [] } # 早停相关变量 best_val_loss = float('inf') epochs_no_improve = 0 best_model_state = None best_epoch = 0 # 训练循环 start_time = time.time() for epoch in range(max_epochs): epoch_start_time = time.time() # 训练阶段 model.train() train_loss = 0.0 all_train_preds = [] all_train_targets = [] for inputs, targets in train_loader: inputs, targets = inputs.to(device), targets.to(device) # 前向传播 outputs = model(inputs) loss = criterion(outputs.squeeze(), targets) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() # 收集预测目标用于评估 with torch.no_grad(): all_train_preds.extend(outputs.squeeze().cpu().numpy()) all_train_targets.extend(targets.cpu().numpy()) train_loss += loss.item() * inputs.size(0) # 计算训练指标 train_loss /= len(train_loader.dataset) train_metrics = EvaluationMetrics.calculate_metrics( np.array(all_train_targets), np.array(all_train_preds) ) # 验证阶段 model.eval() val_loss = 0.0 all_val_preds = [] all_val_targets = [] val_timestamps = [] with torch.no_grad(): for inputs, targets in val_loader: inputs, targets = inputs.to(device), targets.to(device) outputs = model(inputs) loss = criterion(outputs.squeeze(), targets) val_loss += loss.item() * inputs.size(0) # 收集验证集的预测目标 all_val_preds.extend(outputs.squeeze().cpu().numpy()) all_val_targets.extend(targets.cpu().numpy()) # 收集时间戳(用于可视化) if len(val_timestamps) == 0: # 获取时间戳(假设数据集有'timestamp'列) idx = val_loader.dataset.indices[0] start_idx = idx + val_loader.dataset.dataset.seq_length end_idx = start_idx + len(targets) timestamps = val_loader.dataset.dataset.data['timestamp'].iloc[start_idx:end_idx] val_timestamps.extend(timestamps.dt.strftime('%Y-%m-%d').tolist()) # 计算验证指标 val_loss /= len(val_loader.dataset) val_metrics = EvaluationMetrics.calculate_metrics( np.array(all_val_targets), np.array(all_val_preds) ) # 记录历史 history['epoch'].append(epoch) history['train_loss'].append(train_loss) history['val_loss'].append(val_loss) history['train_rmse'].append(train_metrics['rmse']) history['val_rmse'].append(val_metrics['rmse']) history['train_mae'].append(train_metrics['mae']) history['val_mae'].append(val_metrics['mae']) history['train_r2'].append(train_metrics['r2']) history['val_r2'].append(val_metrics['r2']) history['train_mape'].append(train_metrics['mape']) history['val_mape'].append(val_metrics['mape']) # 计算每轮耗时 epoch_time = time.time() - epoch_start_time history['time_per_epoch'].append(epoch_time) # 打印进度 print(f"Epoch {epoch+1}/{max_epochs} | 耗时: {epoch_time:.2f}s") print(f" 训练损失: {train_loss:.6f} | 验证损失: {val_loss:.6f}") print(f" 训练RMSE: {train_metrics['rmse']:.4f} | 验证RMSE: {val_metrics['rmse']:.4f}") print(f" 训练MAE: {train_metrics['mae']:.4f} | 验证MAE: {val_metrics['mae']:.4f}") print(f" 训练R²: {train_metrics['r2']:.4f} | 验证R²: {val_metrics['r2']:.4f}") # 定期可视化 if (epoch + 1) % plot_interval == 0 or epoch == 0: VisualizationTools.plot_training_history({ 'train_loss': history['train_loss'], 'val_loss': history['val_loss'], 'train_rmse': history['train_rmse'], 'val_rmse': history['val_rmse'], 'train_r2': history['train_r2'], 'val_r2': history['val_r2'], 'train_mape': history['train_mape'], 'val_mape': history['val_mape'] }) # 可视化当前验证集预测 VisualizationTools.plot_predictions_vs_actual( np.array(all_val_targets), np.array(all_val_preds), timestamps=val_timestamps ) # 早停检查 if val_loss < best_val_loss - min_delta: print(f"验证损失改善: {best_val_loss:.6f} -> {val_loss:.6f}") best_val_loss = val_loss epochs_no_improve = 0 best_epoch = epoch # 保存最佳模型状态验证结果 best_model_state = { 'epoch': epoch, 'model_state_dict': model.state_dict(), 'optimizer_state_dict': optimizer.state_dict(), 'val_loss': val_loss, 'val_metrics': val_metrics, 'val_predictions': (all_val_targets, all_val_preds, val_timestamps) } else: epochs_no_improve += 1 print(f"早停计数器: {epochs_no_improve}/{patience}") # 检查是否达到早停条件 if epochs_no_improve >= patience: print(f"早停触发! 最佳验证损失: {best_val_loss:.6f} (Epoch {best_epoch+1})") # 恢复最佳模型 model.load_state_dict(best_model_state['model_state_dict']) break # 计算总训练时间 total_time = time.time() - start_time print(f"\n训练完成! 总耗时: {total_time:.2f}秒") print(f"平均每轮耗时: {np.mean(history['time_per_epoch']):.2f}秒") # 最终评估 if best_model_state is None: best_model_state = { 'model_state_dict': model.state_dict(), 'val_loss': val_loss, 'val_metrics': val_metrics, 'val_predictions': (all_val_targets, all_val_preds, val_timestamps) } # 打印最终评估指标 EvaluationMetrics.print_metrics(best_model_state['val_metrics'], "最终验证集评估指标") # 特征重要性可视化 VisualizationTools.plot_feature_importance(model, feature_engineer.feature_columns) # 最终可视化 all_val_targets, all_val_preds, val_timestamps = best_model_state['val_predictions'] VisualizationTools.plot_predictions_vs_actual( np.array(all_val_targets), np.array(all_val_preds), timestamps=val_timestamps ) VisualizationTools.plot_error_distribution( np.array(all_val_targets), np.array(all_val_preds) ) return model, feature_engineer, best_model_state['val_metrics'], history # 8. 完整使用示例 if __name__ == "__main__": # 生成更真实的交通数据(带季节性节假日效应) np.random.seed(42) timestamps = pd.date_range('2020-01-01', periods=730, freq='D') # 2年数据 # 基础交通量 + 季节性波动 base_volume = 30000 seasonal_factor = np.sin(2 * np.pi * np.arange(730) / 365) * 5000 # 工作日/周末效应 weekday_factor = np.array([1.2 if d.weekday() < 5 else 0.8 for d in timestamps]) * 2000 # 节假日效应 holiday_factor = np.zeros(730) for i, date in enumerate(timestamps): if cal.is_holiday(date.date()): holiday_factor[i] = -4000 # 节假日交通量减少 elif date.month == 10 and 1 <= date.day <= 7: # 国庆假期 holiday_factor[i] = -3000 elif (date.month == 1 and date.day >= 15) or (date.month == 2 and date.day <= 15): # 春运 holiday_factor[i] = 5000 # 春运交通量增加 # 合成交通量 traffic_volumes = base_volume + seasonal_factor + weekday_factor + holiday_factor traffic_volumes = np.maximum(traffic_volumes, 10000) # 确保最小 # 添加随机噪声 noise = np.random.normal(0, 1000, 730) traffic_volumes += noise # 创建DataFrame data = pd.DataFrame({ 'timestamp': timestamps, 'traffic_volume': traffic_volumes.astype(int) }) # 训练模型(带评估可视化) print("开始训练模型...") model, feature_engineer, val_metrics, history = train_model_with_metrics_and_viz( data, city_tier=1, max_epochs=50, patience=7, min_delta=0.0005, plot_interval=10 ) # 初始化预测器 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") predictor = DailyTrafficPredictor(model, feature_engineer, device) # 使用历史数据初始化预测器 for _, row in data.iloc[-60:].iterrows(): # 使用最后60天数据 predictor.update_data(row.to_dict()) # 进行预测 prediction = predictor.predict() print(f"\n明天的预测交通量: {prediction:.1f} 辆车") # 保存模型特征工程 torch.save({ 'model_state_dict': model.state_dict(), 'feature_engineer': feature_engineer, 'val_metrics': val_metrics }, 'traffic_predictor.pth') print("模型已保存为 'traffic_predictor.pth'") ``` ### 关键功能详解 #### 1. 评估指标计算类 ```python class EvaluationMetrics: @staticmethod def calculate_metrics(y_true, y_pred): # RMSE (均方根误差) metrics['rmse'] = np.sqrt(mean_squared_error(y_true, y_pred)) # MAE (平均绝对误差) metrics['mae'] = mean_absolute_error(y_true, y_pred) # R² (决定系数) metrics['r2'] = r2_score(y_true, y_pred) # MAPE (平均绝对百分比误差) mape = np.mean(np.abs((y_true - y_pred) / (y_true + epsilon))) * 100 # sMAPE (对称平均绝对百分比误差) smape = np.mean(2 * np.abs(y_true - y_pred) / (np.abs(y_true) + np.abs(y_pred) + epsilon)) * 100 # 最大误差 metrics['max_error'] = np.max(np.abs(y_true - y_pred)) ``` - **核心指标**:包含6种常用回归评估指标 - **鲁棒性**:添加ε避免除以零错误 - **对称误差**:sMAPE对高同样敏感 #### 2. 可视化工具类 ```python class VisualizationTools: @staticmethod def plot_training_history(history): # 创建2x2网格图 plt.subplot(2, 2, 1): 训练验证损失 plt.subplot(2, 2, 2): 训练验证RMSE plt.subplot(2, 2, 3): 训练验证R² plt.subplot(2, 2, 4): 训练验证MAPE @staticmethod def plot_predictions_vs_actual(y_true, y_pred, timestamps): # 按时间排序数据 # 绘制实际(蓝色实线)预测值(红色虚线) # 添加45度理想预测线(绿色虚线) @staticmethod def plot_error_distribution(y_true, y_pred): # 左图:误差分布直方图(带KDE曲线) # 右图:绝对误差箱线图 @staticmethod def plot_feature_importance(model, feature_names): # 从LSTM层提取输入权重 # 计算特征重要性(平均绝对权重) # 绘制水平条形图展示特征重要性排序 ``` #### 3. 增强的训练函数 ```python def train_model_with_metrics_and_viz(...): # 训练过程中收集数据指标 history = { 'epoch': [], 'train_loss': [], 'val_loss': [], # 各种评估指标... } # 定期可视化(每plot_interval轮) if (epoch + 1) % plot_interval == 0: VisualizationTools.plot_training_history(...) VisualizationTools.plot_predictions_vs_actual(...) # 训练结束后完整评估 EvaluationMetrics.print_metrics(...) VisualizationTools.plot_feature_importance(...) VisualizationTools.plot_error_distribution(...) ``` - **实时监控**:每轮记录多种指标 - **定期可视化**:按间隔显示训练进度预测效果 - **全面分析**:训练结束后提供特征重要性误差分布分析 ### 评估指标说明 | 指标 | 公式 | 说明 | |------|------|------| | RMSE | $\sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2}$ | 对较大误差更敏感,越小越好 | | MAE | $\frac{1}{n}\sum_{i=1}^{n}|y_i - \hat{y}_i|$ | 绝对误差平均,解释性强 | | R² | $1 - \frac{\sum(y_i - \hat{y}_i)^2}{\sum(y_i - \bar{y})^2}$ | 模型解释方差的比例,接近1最好 | | MAPE | $\frac{100\%}{n}\sum_{i=1}^{n}\left|\frac{y_i - \hat{y}_i}{y_i}\right|$ | 百分比误差,易解释但高估低误差 | | sMAPE | $\frac{200\%}{n}\sum_{i=1}^{n}\frac{|y_i - \hat{y}_i|}{|y_i| + |\hat{y}_i|}$ | 对称百分比误差,平衡高低影响 | ### 可视化功能说明 #### 1. 训练历史图表 ![训练历史](https://via.placeholder.com/600x400?text=Training+History) - **损失曲线**:监控过拟合/欠拟合 - **RMSE曲线**:观察预测误差变化 - **R²曲线**:评估模型解释能力 - **MAPE曲线**:关注百分比误差变化 #### 2. 预测值 vs 实际 ![预测对比](https://via.placeholder.com/600x300?text=Predictions+vs+Actual) - **时间序列对比**:直观显示预测效果 - **45度参考线**:理想预测位置 - **日期格式化**:自动旋转标签避免重叠 #### 3. 误差分布分析 ![误差分布](https://via.placeholder.com/600x300?text=Error+Distribution) - **误差直方图**:显示误差分布形态 - **箱线图**:展示绝对误差统计特性 - **零线标记**:标识完美预测位置 #### 4. 特征重要性 ![特征重要性](https://via.placeholder.com/600x300?text=Feature+Importance) - **权重分析**:基于LSTM输入权重 - **排序展示**:清晰显示关键特征 - **归一化处理**:便于比较不同特征 ### 实际应用场景 #### 模型性能监控 ```python # 训练过程中实时监控 model, _, metrics, history = train_model_with_metrics_and_viz( data, plot_interval=5 # 每5轮显示一次进度 ) # 训练后分析关键指标 print(f"最终模型在验证集上的R²分数: {metrics['r2']:.4f}") if metrics['mape'] > 10: print("警告: MAPE超过10%,模型可能需改进") ``` #### 模型比较选择 ```python # 比较不同城市分级模型的性能 results = {} for city_tier in [1, 2, 3]: model, _, metrics, _ = train_model_with_metrics_and_viz( data, city_tier=city_tier, max_epochs=30 ) results[city_tier] = metrics['rmse'] # 选择最佳城市分级 best_tier = min(results, key=results.get) print(f"最佳城市分级: {best_tier} (RMSE: {results[best_tier]:.4f})") ``` #### 误差分析报告 ```python # 生成完整误差分析报告 def generate_error_report(y_true, y_pred, timestamps): # 基本指标 metrics = EvaluationMetrics.calculate_metrics(y_true, y_pred) # 可视化 VisualizationTools.plot_predictions_vs_actual(y_true, y_pred, timestamps) VisualizationTools.plot_error_distribution(y_true, y_pred) # 识别最大误差点 max_error_idx = np.argmax(np.abs(y_pred - y_true)) print(f"最大误差发生在: {timestamps[max_error_idx]}") print(f"实际: {y_true[max_error_idx]}, 预测值: {y_pred[max_error_idx]}") return metrics ``` #### 生产环境集成 ```python # 在生产环境中监控模型性能 class ProductionMonitor: def __init__(self, predictor): self.predictor = predictor self.true_values = [] self.pred_values = [] self.timestamps = [] def record_prediction(self, timestamp, true_value): # 获取并记录预测 prediction = self.predictor.predict() self.pred_values.append(prediction) self.true_values.append(true_value) self.timestamps.append(timestamp) # 更新预测器 new_data = {'timestamp': timestamp, 'traffic_volume': true_value} self.predictor.update_data(new_data) # 每周生成性能报告 if len(self.timestamps) % 7 == 0: self.generate_weekly_report() def generate_weekly_report(self): metrics = EvaluationMetrics.calculate_metrics( np.array(self.true_values[-7:]), np.array(self.pred_values[-7:]) ) print("\n周度性能报告:") EvaluationMetrics.print_metrics(metrics) VisualizationTools.plot_predictions_vs_actual( self.true_values[-7:], self.pred_values[-7:], self.timestamps[-7:] ) ``` ### 优化建议 1. **交互式可视化**: ```python # 使用Plotly创建交互式图表 import plotly.express as px def interactive_prediction_plot(y_true, y_pred, timestamps): df = pd.DataFrame({ 'timestamp': timestamps, '实际': y_true, '预测值': y_pred }) fig = px.line(df, x='timestamp', y=['实际', '预测值'], title='预测值实际对比') fig.show() ``` 2. **误差分类分析**: ```python # 分析不同日期类型的误差 def error_by_day_type(y_true, y_pred, dates): errors = np.abs(y_pred - y_true) # 分类工作日/周末/节假日 day_types = [] for date in dates: if cal.is_holiday(date): day_types.append('节假日') elif date.weekday() >= 5: day_types.append('周末') else: day_types.append('工作日') # 分组分析 error_df = pd.DataFrame({'error': errors, 'day_type': day_types}) sns.boxplot(x='day_type', y='error', data=error_df) plt.title('不同日期类型的预测误差分布') ``` 3. **模型解释工具**: ```python # 使用SHAP解释模型预测 import shap def explain_prediction(model, input_sample, feature_names): # 创建解释器 explainer = shap.DeepExplainer(model, input_sample) # 计算SHAP shap_values = explainer.shap_values(input_sample) # 可视化 shap.summary_plot(shap_values, input_sample, feature_names=feature_names) ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值