Day55打卡 @浙大疏锦行

知识点回顾

  1. 序列预测介绍
    1. 单步预测
    2. 多步预测的2种方式
  2. 序列数据的处理:滑动窗口
  3. 多输入多输出任务的思路
  4. 经典机器学习在序列任务上的劣势;以随机森林为例
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import mean_squared_error
    
    # =============================================================
    # ===== 步骤1:数据准备 (与之前完全相同) =====
    # =============================================================
    
    # 生成合成时间序列
    x = np.linspace(0, 100, 1000)
    y = np.sin(x) + 0.1 * x + np.random.normal(0, 0.5, 1000)
    
    # 定义参数
    train_size = int(len(y) * 0.8)
    seq_length = 30
    
    # 正确的数据标准化
    train_data_raw = y[:train_size]
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaler.fit(train_data_raw.reshape(-1, 1))
    scaled_y = scaler.transform(y.reshape(-1, 1)).flatten()
    
    # 创建时序数据集函数
    def create_sequences(data, seq_length):
        X, y = [], []
        for i in range(len(data) - seq_length):
            X.append(data[i:i+seq_length])
            y.append(data[i+seq_length])
        return np.array(X), np.array(y)
    
    # 对完整数据应用滑动窗口
    all_X, all_y = create_sequences(scaled_y, seq_length)
    
    # 划分序列数据集
    split_idx = train_size - seq_length
    X_train_np = all_X[:split_idx]
    y_train_np = all_y[:split_idx]
    X_test_np = all_X[split_idx:]
    y_test_np = all_y[split_idx:]
    
    # =========================================================================
    # ===== 步骤2:为机器学习模型准备数据 (关键区别点!) =====
    # =========================================================================
    
    # 1. 调整X的形状
    # Scikit-learn的机器学习模型需要二维的输入: [样本数, 特征数]
    # RNN需要的是三维输入: [样本数, 时间步长, 特征数]
    # 我们需要将每个样本的 `seq_length` 个时间步“扁平化”成 `seq_length` 个特征。
    # 原始形状: (770, 30, 1) or (770, 30) -> 目标形状: (770, 30)
    
    # 获取样本数
    n_samples_train = X_train_np.shape[0]
    n_samples_test = X_test_np.shape[0]
    
    # 将三维或二维的X reshape为二维
    X_train_rf = X_train_np.reshape(n_samples_train, -1)
    X_test_rf = X_test_np.reshape(n_samples_test, -1)
    
    # y_train_np 和 y_test_np 已经是 (n_samples,) 的一维数组,可以直接使用。
    
    print("为随机森林准备的 X_train 形状:", X_train_rf.shape) # (770, 30)
    print("为随机森林准备的 y_train 形状:", y_train_np.shape)   # (770,)
    print("为随机森林准备的 X_test 形状:", X_test_rf.shape)    # (200, 30)
    
    # 注意:我们不再需要 PyTorch 的 Tensor, TensorDataset 和 DataLoader
    
    # =============================================================
    # ===== 步骤3:创建、训练和评估随机森林模型 =====
    # =============================================================
    
    # 1. 创建随机森林回归模型
    # n_estimators: 森林中树的数量
    # random_state: 保证每次运行结果一致,便于复现
    # n_jobs=-1: 使用所有可用的CPU核心进行并行计算,加快训练速度
    rf_model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
    
    # 2. 训练模型
    print("\n开始训练随机森林模型...")
    rf_model.fit(X_train_rf, y_train_np)
    print("模型训练完成!")
    
    # 3. 做出预测
    train_predict = rf_model.predict(X_train_rf)
    test_predict = rf_model.predict(X_test_rf)
    
    # 4. 反标准化预测结果,以便在原始尺度上进行比较
    # scaler.inverse_transform 需要二维输入,所以先 reshape
    train_predict = scaler.inverse_transform(train_predict.reshape(-1, 1))
    test_predict = scaler.inverse_transform(test_predict.reshape(-1, 1))
    
    # 原始标签也需要反标准化
    y_train_orig = scaler.inverse_transform(y_train_np.reshape(-1, 1))
    y_test_orig = scaler.inverse_transform(y_test_np.reshape(-1, 1))
    
    # 5. 计算均方根误差 (RMSE)
    train_rmse = np.sqrt(mean_squared_error(y_train_orig, train_predict))
    test_rmse = np.sqrt(mean_squared_error(y_test_orig, test_predict))
    print(f"\n训练集 RMSE: {train_rmse:.4f}")
    print(f"测试集 RMSE: {test_rmse:.4f}")
    
    
    # =============================================================
    # ===== 步骤4:可视化结果 =====
    # =============================================================
    
    plt.figure(figsize=(15, 7))
    plt.plot(y, label='原始数据', color='gray', alpha=0.5)
    
    # 绘制训练集的预测结果
    train_predict_plot = np.empty_like(y)
    train_predict_plot[:] = np.nan
    train_predict_plot[seq_length : len(train_predict) + seq_length] = train_predict.flatten()
    plt.plot(train_predict_plot, label='训练集预测值 (RF)', color='blue')
    
    # 绘制测试集的预测结果
    test_predict_plot = np.empty_like(y)
    test_predict_plot[:] = np.nan
    test_predict_plot[len(train_predict) + seq_length : len(y)] = test_predict.flatten()
    plt.plot(test_predict_plot, label='测试集预测值 (RF)', color='red')
    
    plt.title('时间序列预测结果对比 (随机森林)')
    plt.xlabel('时间步')
    plt.ylabel('值')
    plt.legend()
    plt.grid(True)
    plt.show()

 @浙大疏锦行

你可能感兴趣的:(python打卡shu,python)