当前位置: 首页 > news >正文

机器学习时间序列算法进行随机划分数据是不合适的!

问题代码:数据集划分方式不适合时间序列,会导致评估结果不可靠。

  • 代码在整体流程上是合理的,但针对时间序列数据,存在一个关键问题:使用train_test_split进行随机划分是不合适的。
  • 时间序列的特殊性
    • 风速数据属于时间序列数据,其核心特点是数据具有时间依赖性(即未来的数据与历史数据存在时间上的先后关联)。而train_test_split的默认行为是随机划分数据(即使设置了random_state,本质还是随机抽样),这会导致:

      • 测试集中可能包含 “时间上早于训练集” 的数据
      • 模型在训练时可能 “见过” 未来的数据,造成数据泄露
      • 最终的评估结果(如 RMSE、R²)不能真实反映模型对 “未来数据” 的预测能力(这是时间序列预测的核心目标)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler# 1. 加载数据
data1 = pd.read_csv(r'data.csv')# 2. 确保 date_time 列是 datetime 类型
data1['date_time'] = pd.to_datetime(data1['date_time'], format='%Y/%m/%d %H:%M')# 3. 定义时间范围并筛选数据
start_time = '2023-07-01 00:00:00'
end_time = '2024-06-30 18:00:00'
data1 = data1[(data1['date_time'] >= start_time) & (data1['date_time'] <= end_time)]# 4. 提取特征和目标列
X = data1[['ecmwf_wind']]  # 特征列
y = data1['wind_obs']  # 目标列# 5. 数据集划分(训练集和测试集)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)# 6. 数据归一化(最大最小归一化)
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# 7. 训练简单线性回归模型
model = LinearRegression()
model.fit(X_train_scaled, y_train)# 8. 预测
y_pred = model.predict(X_test_scaled)# 9. 计算评价指标
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
mae = mean_absolute_error(y_test, y_pred)
mbe = np.mean(y_test - y_pred)  # 平均偏差误差
r2 = r2_score(y_test, y_pred)# 10. 输出评价指标
print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"MBE: {mbe:.4f}")
print(f"R²: {r2:.4f}")# 11. 数据可视化
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5, label='Predicted vs Observed')
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--', label='Ideal Line')
plt.xlabel('Observed Wind Speed')
plt.ylabel('Predicted Wind Speed')
plt.title('Observed vs Predicted Wind Speed')
plt.legend()
plt.grid(True)
plt.show()

改进建议(针对时间序列划分)

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler# 1. 加载数据
data1 = pd.read_csv(r'data.csv')# 2. 确保 date_time 列是 datetime 类型
data1['date_time'] = pd.to_datetime(data1['date_time'], format='%Y/%m/%d %H:%M')# 3. 定义时间范围并筛选数据
start_time = '2023-07-01 00:00:00'
end_time = '2024-06-30 18:00:00'
data1 = data1[(data1['date_time'] >= start_time) & (data1['date_time'] <= end_time)]# 4. 按时间排序(时间序列分析的重要步骤)
data1 = data1.sort_values('date_time').reset_index(drop=True)# 5. 提取特征和目标列
X = data1[['ecmwf_wind']]  # 特征列
y = data1['wind_obs']      # 目标列# 6. 时间序列数据集划分(按时间顺序,前75%训练,后25%测试)
split_ratio = 0.75
split_idx = int(len(data1) * split_ratio)X_train, X_test = X.iloc[:split_idx], X.iloc[split_idx:]
y_train, y_test = y.iloc[:split_idx], y.iloc[split_idx:]# 7. 数据归一化(最大最小归一化)
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# 8. 训练简单线性回归模型
model = LinearRegression()
model.fit(X_train_scaled, y_train)# 9. 预测
y_pred = model.predict(X_test_scaled)# 10. 计算评价指标
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
mae = mean_absolute_error(y_test, y_pred)
mbe = np.mean(y_test - y_pred)  # 平均偏差误差
r2 = r2_score(y_test, y_pred)# 11. 输出评价指标
print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"MBE: {mbe:.4f}")
print(f"R²: {r2:.4f}")# 12. 预测值与观测值对比可视化(带时间维度)
plt.figure(figsize=(12, 6))
plt.plot(data1['date_time'].iloc[split_idx:], y_test, label='观测风速', alpha=0.7)
plt.plot(data1['date_time'].iloc[split_idx:], y_pred, label='预测风速', linestyle='--')
plt.xlabel('时间')
plt.ylabel('风速')
plt.title('测试集风速预测对比')
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()# 13. 散点图可视化(预测值 vs 观测值)
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5, label='预测值 vs 观测值')
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--', label='理想线')
plt.xlabel('观测风速')
plt.ylabel('预测风速')
plt.title('观测值与预测值对比')
plt.legend()
plt.grid(True)
plt.show()

绘图展示中文显示不了,设置matplotlib设置中文字体。

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScalerimport matplotlib as mpl# 设置中文字体 - 根据您的系统选择
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体,Windows
# plt.rcParams['font.sans-serif'] = ['Heiti TC']  # 黑体-繁,Mac
# plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']  # 文泉驿正黑,Linux# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False# 或者使用全局设置
mpl.rc('font', family='SimHei')  # Windows
# mpl.rc('font', family='Arial Unicode MS')  # Mac# 1. 加载数据
data1 = pd.read_csv(r'data.csv')# 2. 确保 date_time 列是 datetime 类型
data1['date_time'] = pd.to_datetime(data1['date_time'], format='%Y/%m/%d %H:%M')# 3. 定义时间范围并筛选数据
start_time = '2023-07-01 00:00:00'
end_time = '2024-06-30 18:00:00'
data1 = data1[(data1['date_time'] >= start_time) & (data1['date_time'] <= end_time)]# 4. 按时间排序(时间序列分析的重要步骤)
data1 = data1.sort_values('date_time').reset_index(drop=True)# 5. 提取特征和目标列
X = data1[['ecmwf_wind']]  # 特征列
y = data1['wind_obs']      # 目标列# 6. 时间序列数据集划分(按时间顺序,前75%训练,后25%测试)
split_ratio = 0.75
split_idx = int(len(data1) * split_ratio)X_train, X_test = X.iloc[:split_idx], X.iloc[split_idx:]
y_train, y_test = y.iloc[:split_idx], y.iloc[split_idx:]# 7. 数据归一化(最大最小归一化)
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# 8. 训练简单线性回归模型
model = LinearRegression()
model.fit(X_train_scaled, y_train)# 9. 预测
y_pred = model.predict(X_test_scaled)# 10. 计算评价指标
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
mae = mean_absolute_error(y_test, y_pred)
mbe = np.mean(y_test - y_pred)  # 平均偏差误差
r2 = r2_score(y_test, y_pred)# 11. 输出评价指标
print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"MBE: {mbe:.4f}")
print(f"R²: {r2:.4f}")# 12. 预测值与观测值对比可视化(带时间维度)
plt.figure(figsize=(12, 6))
plt.plot(data1['date_time'].iloc[split_idx:], y_test, label='观测风速', alpha=0.7)
plt.plot(data1['date_time'].iloc[split_idx:], y_pred, label='预测风速', linestyle='--')
plt.xlabel('时间')
plt.ylabel('风速')
plt.title('测试集风速预测对比')
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()# 13. 散点图可视化(预测值 vs 观测值)
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5, label='预测值 vs 观测值')
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--', label='理想线')
plt.xlabel('观测风速')
plt.ylabel('预测风速')
plt.title('观测值与预测值对比')
plt.legend()
plt.grid(True)
plt.show()
http://www.dtcms.com/a/358523.html

相关文章:

  • 一键掌控三线资源:极简 Shell 脚本实现 CPU·磁盘·内存可视化巡检
  • 鸿蒙ArkTS 核心篇-14-条件表达式(三目运算符)
  • ans1语法的一个例子nt5inf.cat
  • openEuler2403安装部署PostgreSQL17
  • 开发中使用——鸿蒙CoreSpeechKit让文字发声
  • 118、【OS】【Nuttx】【周边】效果呈现方案解析:作用域?
  • python pyqt5开发DoIP上位机【源码】
  • Spring代理的特点
  • Photoshop - Ps Camera Raw 滤镜
  • 【Python+requests】解决Python requests中的ProxyError:SSL版本错误问题详解
  • C++中的临时对象与移动语义——深入理解与实践
  • 消费 $83,用Claude 实现临床护理系统记录单(所见即所得版)
  • 拦截器Intercepter
  • 基于单片机智能垃圾桶/垃圾分类/语音垃圾桶
  • Spring MVC 参数绑定的默认行为解析
  • MySQL错误1449: The user specified as a definer (‘root‘@‘%‘) does not exist
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 1: MapReduce
  • JC系列串口通信说明
  • day45-Ansible流程控制
  • 同步/异步日志库
  • 佳易王钟表维修养护管理系统:开启钟表维修高效管理新篇章​就#软件操作教程
  • Compare With Java And Python
  • springboot 实现不同接口指定上传文件大小
  • Linux 定时器:工作原理与实现机制深入分析
  • AI公司是怎样对权重和损失函数做处理的?
  • Oracle下载安装(学习版)
  • 向华为学习——解读73页业务迁移基本流程设计与华为迁移方案【附全文阅读】
  • 计算机三级嵌入式填空题——真题库(26)原题附答案速记
  • Java学习历程17——利用泛型优化自定义动态数组
  • 深度学习入门,基于python的理论与实现