XAU_1d_data_2004_to_2024-09-20
In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
# 加载数据集(假设数据文件是CSV格式)
data = pd.read_csv('XAU_1d_data_2004_to_2024-09-20.csv')
# 查看数据的前几行
data.head()
Out[1]:
| Date | Time | Open | High | Low | Close | Volume | |
|---|---|---|---|---|---|---|---|
| 0 | 2004.06.11 | 00:00 | 384.0 | 384.8 | 382.8 | 384.1 | 272 |
| 1 | 2004.06.14 | 00:00 | 384.3 | 385.8 | 381.8 | 382.8 | 1902 |
| 2 | 2004.06.15 | 00:00 | 382.8 | 388.8 | 381.1 | 388.6 | 1951 |
| 3 | 2004.06.16 | 00:00 | 387.1 | 389.8 | 382.6 | 383.8 | 2014 |
| 4 | 2004.06.17 | 00:00 | 383.6 | 389.3 | 383.0 | 387.6 | 1568 |
In [2]:
# 去除缺失值
data.dropna(inplace=True)
# 选择收盘价进行预测
data = data[['Date', 'Close']]
# 转换日期格式为datetime
data['Date'] = pd.to_datetime(data['Date'])
# 设定日期为索引
data.set_index('Date', inplace=True)
# 归一化处理
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data[['Close']])
# 创建训练集和测试集的时间步长
train_size = int(len(data) * 0.8)
train_data, test_data = scaled_data[:train_size], scaled_data[train_size:]
黄金价格波动规律分析¶
In [3]:
# 描述性统计
data['Close'].describe()
# 自相关和偏自相关分析
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plt.figure(figsize=(12, 6))
# 绘制ACF图
plt.subplot(121)
plot_acf(data['Close'], lags=50, ax=plt.gca())
plt.title('ACF - Autocorrelation')
# 绘制PACF图
plt.subplot(122)
plot_pacf(data['Close'], lags=50, ax=plt.gca())
plt.title('PACF - Partial Autocorrelation')
plt.tight_layout()
plt.show()
LSTM¶
In [4]:
def create_dataset(data, time_step=60):
X, y = [], []
for i in range(len(data) - time_step - 1):
X.append(data[i:(i + time_step), 0])
y.append(data[i + time_step, 0])
return np.array(X), np.array(y)
# 创建训练集和测试集的数据
time_step = 60 # 使用前60天的数据预测下一天
X_train, y_train = create_dataset(train_data, time_step)
X_test, y_test = create_dataset(test_data, time_step)
# 将数据reshape为LSTM所需的格式 [样本数量, 时间步长, 特征数量]
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)
In [5]:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
# 构建LSTM模型
model = Sequential()
# 添加LSTM层,return_sequences=True表示返回完整的序列用于堆叠更多LSTM层
model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
model.add(Dropout(0.2)) # 添加Dropout层防止过拟合
# 添加第二层LSTM
model.add(LSTM(units=50, return_sequences=False))
model.add(Dropout(0.2))
# 添加全连接层
model.add(Dense(units=1))
# 编译模型
model.compile(optimizer='adam', loss='mean_squared_error')
# 训练模型
model.fit(X_train, y_train, epochs=10, batch_size=32)
--------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) Cell In[5], line 1 ----> 1 from tensorflow.keras.models import Sequential 2 from tensorflow.keras.layers import LSTM, Dense, Dropout 4 # 构建LSTM模型 File d:\Python310\lib\site-packages\tensorflow\__init__.py:38 35 import sys as _sys 36 import typing as _typing ---> 38 from tensorflow.python.tools import module_util as _module_util 39 from tensorflow.python.util.lazy_loader import LazyLoader as _LazyLoader 41 # Make sure code inside the TensorFlow codebase can use tf2.enabled() at import. File d:\Python310\lib\site-packages\tensorflow\python\__init__.py:43 38 # pylint: enable=wildcard-import 39 40 # from tensorflow.python import keras 41 # from tensorflow.python.layers import layers 42 from tensorflow.python.saved_model import saved_model ---> 43 from tensorflow.python.tpu import api 45 # Sub-package for performing i/o directly instead of via ops in a graph. 46 from tensorflow.python.lib.io import python_io File d:\Python310\lib\site-packages\tensorflow\python\tpu\api.py:23 21 # pylint: disable=unused-import 22 from tensorflow.python.tpu import bfloat16 ---> 23 from tensorflow.python.tpu import feature_column_v2 24 from tensorflow.python.tpu import tpu 25 from tensorflow.python.tpu import tpu_embedding File d:\Python310\lib\site-packages\tensorflow\python\tpu\feature_column_v2.py:19 17 import enum 18 import math ---> 19 from tensorflow.python.feature_column import feature_column as fc 20 from tensorflow.python.feature_column import feature_column_lib as fc_lib 21 from tensorflow.python.framework import dtypes File d:\Python310\lib\site-packages\tensorflow\python\feature_column\feature_column.py:143 141 from tensorflow.python.framework import sparse_tensor as sparse_tensor_lib 142 from tensorflow.python.framework import tensor_shape --> 143 from tensorflow.python.layers import base 144 from tensorflow.python.ops import array_ops 145 from tensorflow.python.ops import array_ops_stack File d:\Python310\lib\site-packages\tensorflow\python\layers\base.py:16 1 # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); (...) 13 # limitations under the License. 14 # ============================================================================= 15 """Contains the base Layer class, from which all layers inherit.""" ---> 16 from tensorflow.python.keras.legacy_tf_layers import base 18 InputSpec = base.InputSpec 20 keras_style_scope = base.keras_style_scope File d:\Python310\lib\site-packages\tensorflow\python\keras\__init__.py:25 22 from tensorflow.python.keras import distribute 24 # See b/110718070#comment18 for more details about this import. ---> 25 from tensorflow.python.keras import models 27 from tensorflow.python.keras.engine.input_layer import Input 28 from tensorflow.python.keras.engine.sequential import Sequential File d:\Python310\lib\site-packages\tensorflow\python\keras\models.py:22 20 from tensorflow.python.keras import metrics as metrics_module 21 from tensorflow.python.keras import optimizer_v1 ---> 22 from tensorflow.python.keras.engine import functional 23 from tensorflow.python.keras.engine import sequential 24 from tensorflow.python.keras.engine import training File d:\Python310\lib\site-packages\tensorflow\python\keras\engine\functional.py:33 31 from tensorflow.python.keras.engine import input_spec 32 from tensorflow.python.keras.engine import node as node_module ---> 33 from tensorflow.python.keras.engine import training as training_lib 34 from tensorflow.python.keras.engine import training_utils 35 from tensorflow.python.keras.saving.saved_model import network_serialization File d:\Python310\lib\site-packages\tensorflow\python\keras\engine\training.py:44 42 from tensorflow.python.framework import tensor_shape 43 from tensorflow.python.keras import backend ---> 44 from tensorflow.python.keras import callbacks as callbacks_module 45 from tensorflow.python.keras import optimizer_v1 46 from tensorflow.python.keras import optimizers File d:\Python310\lib\site-packages\tensorflow\python\keras\callbacks.py:68 65 from tensorflow.tools.docs import doc_controls 67 try: ---> 68 import requests 69 except ImportError: 70 requests = None File d:\Python310\lib\site-packages\requests\__init__.py:43 6 """ 7 Requests HTTP Library 8 ~~~~~~~~~~~~~~~~~~~~~ (...) 38 :license: Apache 2.0, see LICENSE for more details. 39 """ 41 import warnings ---> 43 import urllib3 45 from .exceptions import RequestsDependencyWarning 47 try: File d:\Python310\lib\site-packages\urllib3\__init__.py:13 11 from . import exceptions 12 from ._version import __version__ ---> 13 from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url 14 from .filepost import encode_multipart_formdata 15 from .poolmanager import PoolManager, ProxyManager, proxy_from_url File d:\Python310\lib\site-packages\urllib3\connectionpool.py:11 8 from socket import error as SocketError 9 from socket import timeout as SocketTimeout ---> 11 from .connection import ( 12 BaseSSLError, 13 BrokenPipeError, 14 DummyConnection, 15 HTTPConnection, 16 HTTPException, 17 HTTPSConnection, 18 VerifiedHTTPSConnection, 19 port_by_scheme, 20 ) 21 from .exceptions import ( 22 ClosedPoolError, 23 EmptyPoolError, (...) 34 TimeoutError, 35 ) 36 from .packages import six File d:\Python310\lib\site-packages\urllib3\connection.py:15 13 from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection 14 from .packages.six.moves.http_client import HTTPException # noqa: F401 ---> 15 from .util.proxy import create_proxy_ssl_context 17 try: # Compiled with SSL? 18 import ssl File d:\Python310\lib\site-packages\urllib3\util\__init__.py:4 1 from __future__ import absolute_import 3 # For backwards compatibility, provide imports that used to be here. ----> 4 from .connection import is_connection_dropped 5 from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers 6 from .response import is_fp_closed File d:\Python310\lib\site-packages\urllib3\util\connection.py:7 3 import socket 5 from urllib3.exceptions import LocationParseError ----> 7 from ..contrib import _appengine_environ 8 from ..packages import six 9 from .wait import NoWayToWaitForSocketError, wait_for_read File <frozen importlib._bootstrap>:1027, in _find_and_load(name, import_) File <frozen importlib._bootstrap>:1002, in _find_and_load_unlocked(name, import_) File <frozen importlib._bootstrap>:945, in _find_spec(name, path, target) File <frozen importlib._bootstrap_external>:1439, in find_spec(cls, fullname, path, target) File <frozen importlib._bootstrap_external>:1411, in _get_spec(cls, fullname, path, target) File <frozen importlib._bootstrap_external>:1544, in find_spec(self, fullname, target) File <frozen importlib._bootstrap_external>:147, in _path_stat(path) KeyboardInterrupt:
In [ ]:
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np
# 预测结果
y_pred = model.predict(X_test)
# 反归一化预测值
y_pred = scaler.inverse_transform(y_pred)
# 反归一化实际值
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))
# 计算RMSE
rmse = np.sqrt(mean_squared_error(y_test_actual, y_pred))
print(f'RMSE: {rmse}')
# 计算MAE
mae = mean_absolute_error(y_test_actual, y_pred)
print(f'MAE: {mae}')
# 计算MAPE
mape = np.mean(np.abs((y_test_actual - y_pred) / y_test_actual)) * 100
print(f'MAPE: {mape}%')
# 计算R²
r2 = r2_score(y_test_actual, y_pred)
print(f'R²: {r2}')
# 可视化实际值与预测值
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(y_test_actual, color='blue', label='Actual Price')
plt.plot(y_pred, color='red', label='Predicted Price')
plt.title('Gold Price Prediction')
plt.xlabel('Date')
plt.ylabel('Gold Price')
plt.legend()
plt.show()
31/31 [==============================] - 0s 10ms/step RMSE: 33.56104053165467 MAE: 26.455290258290812 MAPE: 1.3875205257740362% R²: 0.9723460902530205
严格按照研究方案¶
Gold Price (2013-2022)
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_percentage_error, mean_squared_error, r2_score, explained_variance_score
from keras import Model
from keras.layers import Input, Dense, Dropout, LSTM
from keras.callbacks import EarlyStopping
import warnings
warnings.filterwarnings('ignore')
# === 数据收集与预处理 ===
df = pd.read_csv('Gold Price (2013-2022).csv')
# 1. 数据清洗:去除无关列(如交易量和百分比变化),确保数据质量
df.drop(['Vol.', 'Change %'], axis=1, inplace=True)
# 2. 日期格式转换与排序
df['Date'] = pd.to_datetime(df['Date'])
df.sort_values(by='Date', ascending=True, inplace=True)
df.reset_index(drop=True, inplace=True)
# 3. 去除“,”符号并转换为float类型
NumCols = df.columns.drop(['Date'])
df[NumCols] = df[NumCols].replace({',': ''}, regex=True).astype('float64')
# 4. 缺失值检查
if df.isnull().sum().sum() > 0:
print("数据中存在缺失值!请检查。")
else:
print("数据无缺失值。")
# === 数据波动规律分析 ===
# 使用描述性统计方法分析黄金价格波动特性
print(f"黄金价格数据的均值:\n{df['Price'].mean()}")
print(f"黄金价格数据的标准差:\n{df['Price'].std()}")
print(f"黄金价格数据的变异系数:\n{df['Price'].std() / df['Price'].mean()}")
# 自相关函数与偏自相关函数分析 (ACF 和 PACF)
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(df['Price'], lags=50)
plt.title('自相关函数 (ACF) 分析')
plt.show()
plot_pacf(df['Price'], lags=50)
plt.title('偏自相关函数 (PACF) 分析')
plt.show()
# === 可视化黄金价格 ===
fig = px.line(y=df['Price'], x=df['Date'], title="Gold Price History Data")
fig.update_traces(line_color='black')
fig.update_layout(plot_bgcolor='rgba(255,223,0,0.8)', xaxis_title="Date", yaxis_title="Scaled Price")
fig.show()
# === 数据预处理:标准化与归一化 ===
scaler = MinMaxScaler()
scaler.fit(df['Price'].values.reshape(-1, 1))
# 训练数据与测试数据切分,测试数据包含2022年的数据
test_size = df[df['Date'].dt.year == 2022].shape[0]
train_data = scaler.transform(df['Price'][:-test_size].values.reshape(-1, 1))
test_data = scaler.transform(df['Price'][-test_size - 60:].values.reshape(-1, 1))
# 滑动窗口构造特征和标签
window_size = 60
X_train, y_train, X_test, y_test = [], [], [], []
# 训练数据
for i in range(window_size, len(train_data)):
X_train.append(train_data[i - window_size:i, 0])
y_train.append(train_data[i, 0])
# 测试数据
for i in range(window_size, len(test_data)):
X_test.append(test_data[i - window_size:i, 0])
y_test.append(test_data[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_test, y_test = np.array(X_test), np.array(y_test)
# 调整数据形状以适应LSTM输入
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
y_train = y_train.reshape((-1, 1))
y_test = y_test.reshape((-1, 1))
# === 基于LSTM的黄金价格预测 ===
def define_model():
input1 = Input(shape=(window_size, 1))
x = LSTM(units=64, return_sequences=True)(input1)
x = Dropout(0.2)(x)
x = LSTM(units=32)(x) # 使用较少的LSTM单元以减少过拟合
x = Dropout(0.2)(x)
dnn_output = Dense(1)(x) # 输出层为线性激活函数
model = Model(inputs=input1, outputs=[dnn_output])
model.compile(loss='mean_squared_error', optimizer='Adam') # 使用Adam优化器进行回归任务
return model
model = define_model()
# 训练模型
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
history = model.fit(X_train, y_train, epochs=100, batch_size=32, validation_split=0.2,
callbacks=[early_stopping], verbose=1)
# === 可视化结果 ===
y_pred = model.predict(X_test)
y_test_true = scaler.inverse_transform(y_test)
y_test_pred = scaler.inverse_transform(y_pred)
# 训练数据与预测结果可视化
plt.figure(figsize=(15, 6))
plt.plot(df['Date'].iloc[:-test_size], scaler.inverse_transform(train_data), color='black', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_true, color='blue', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_pred, color='red', lw=2)
plt.title('Model Performance on Gold Price Prediction', fontsize=15)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price', fontsize=12)
plt.legend(['Training Data', 'Actual Test Data', 'Predicted Test Data'], loc='upper left', prop={'size': 15})
plt.grid(color='white')
plt.show()
# === 结果评价 ===
MAPE = mean_absolute_percentage_error(y_test, y_pred)
MSE = mean_squared_error(y_test, y_pred)
RMSE = np.sqrt(MSE)
MAE = np.mean(np.abs(y_test - y_pred))
R2 = r2_score(y_test, y_pred)
SMAPE = np.mean(2 * np.abs(y_test - y_pred) / (np.abs(y_test) + np.abs(y_pred))) * 100
EVS = explained_variance_score(y_test, y_pred)
print(f"MAPE: {MAPE * 100:.2f}%")
print(f"RMSE: {RMSE:.2f}")
print(f"MAE: {MAE:.2f}")
print(f"R² Score: {R2:.2f}")
print(f"SMAPE: {SMAPE:.2f}%")
print(f"Explained Variance Score: {EVS:.2f}")
# 残差分布
residuals = y_test - y_pred
plt.figure(figsize=(10, 5))
plt.hist(residuals, bins=50, color='purple', alpha=0.7)
plt.title('Residual Distribution')
plt.xlabel('Residuals')
plt.ylabel('Frequency')
plt.show()
数据无缺失值。 黄金价格数据的均值: 1440.3264421215642 黄金价格数据的标准差: 257.33828198407844 黄金价格数据的变异系数: 0.1786666372694135
Epoch 1/100 57/57 [==============================] - 4s 35ms/step - loss: 0.0075 - val_loss: 0.0046 Epoch 2/100 57/57 [==============================] - 1s 26ms/step - loss: 0.0018 - val_loss: 0.0022 Epoch 3/100 57/57 [==============================] - 1s 25ms/step - loss: 0.0015 - val_loss: 0.0014 Epoch 4/100 57/57 [==============================] - 1s 25ms/step - loss: 0.0015 - val_loss: 0.0014 Epoch 5/100 57/57 [==============================] - 1s 24ms/step - loss: 0.0014 - val_loss: 0.0015 Epoch 6/100 57/57 [==============================] - 1s 24ms/step - loss: 0.0013 - val_loss: 0.0029 Epoch 7/100 57/57 [==============================] - 1s 25ms/step - loss: 0.0013 - val_loss: 0.0011 Epoch 8/100 57/57 [==============================] - 1s 25ms/step - loss: 0.0011 - val_loss: 0.0013 Epoch 9/100 57/57 [==============================] - 1s 24ms/step - loss: 0.0012 - val_loss: 0.0012 Epoch 10/100 57/57 [==============================] - 1s 25ms/step - loss: 0.0010 - val_loss: 0.0012 Epoch 11/100 57/57 [==============================] - 1s 25ms/step - loss: 9.9622e-04 - val_loss: 0.0028 Epoch 12/100 57/57 [==============================] - 1s 24ms/step - loss: 0.0010 - val_loss: 0.0026 Epoch 13/100 57/57 [==============================] - 1s 24ms/step - loss: 9.8131e-04 - val_loss: 7.8318e-04 Epoch 14/100 57/57 [==============================] - 1s 24ms/step - loss: 9.4093e-04 - val_loss: 0.0017 Epoch 15/100 57/57 [==============================] - 1s 24ms/step - loss: 9.1817e-04 - val_loss: 0.0030 Epoch 16/100 57/57 [==============================] - 1s 24ms/step - loss: 7.7232e-04 - val_loss: 0.0040 Epoch 17/100 57/57 [==============================] - 1s 24ms/step - loss: 8.5649e-04 - val_loss: 0.0057 Epoch 18/100 57/57 [==============================] - 1s 24ms/step - loss: 7.9660e-04 - val_loss: 0.0023 Epoch 19/100 57/57 [==============================] - 1s 24ms/step - loss: 7.2614e-04 - val_loss: 7.3998e-04 Epoch 20/100 57/57 [==============================] - 1s 24ms/step - loss: 7.7055e-04 - val_loss: 9.8563e-04 Epoch 21/100 57/57 [==============================] - 1s 24ms/step - loss: 7.4846e-04 - val_loss: 7.8183e-04 Epoch 22/100 57/57 [==============================] - 1s 25ms/step - loss: 6.6214e-04 - val_loss: 7.0805e-04 Epoch 23/100 57/57 [==============================] - 1s 24ms/step - loss: 7.4924e-04 - val_loss: 8.8543e-04 Epoch 24/100 57/57 [==============================] - 1s 24ms/step - loss: 6.3022e-04 - val_loss: 6.9866e-04 Epoch 25/100 57/57 [==============================] - 1s 24ms/step - loss: 6.5548e-04 - val_loss: 7.5690e-04 Epoch 26/100 57/57 [==============================] - 1s 24ms/step - loss: 6.6375e-04 - val_loss: 0.0023 Epoch 27/100 57/57 [==============================] - 1s 24ms/step - loss: 5.4792e-04 - val_loss: 0.0018 Epoch 28/100 57/57 [==============================] - 1s 24ms/step - loss: 5.3269e-04 - val_loss: 7.5264e-04 Epoch 29/100 57/57 [==============================] - 1s 24ms/step - loss: 5.8640e-04 - val_loss: 0.0045 Epoch 30/100 57/57 [==============================] - 1s 24ms/step - loss: 5.7447e-04 - val_loss: 0.0021 Epoch 31/100 57/57 [==============================] - 1s 24ms/step - loss: 5.1459e-04 - val_loss: 0.0013 Epoch 32/100 57/57 [==============================] - 1s 24ms/step - loss: 5.3560e-04 - val_loss: 5.6316e-04 Epoch 33/100 57/57 [==============================] - 1s 25ms/step - loss: 4.7259e-04 - val_loss: 0.0011 Epoch 34/100 57/57 [==============================] - 1s 24ms/step - loss: 4.5514e-04 - val_loss: 0.0013 Epoch 35/100 57/57 [==============================] - 1s 24ms/step - loss: 4.0443e-04 - val_loss: 7.4367e-04 Epoch 36/100 57/57 [==============================] - 1s 25ms/step - loss: 4.5628e-04 - val_loss: 0.0016 Epoch 37/100 57/57 [==============================] - 1s 24ms/step - loss: 4.3711e-04 - val_loss: 6.6347e-04 Epoch 38/100 57/57 [==============================] - 1s 24ms/step - loss: 4.1139e-04 - val_loss: 0.0012 Epoch 39/100 57/57 [==============================] - 1s 24ms/step - loss: 4.5513e-04 - val_loss: 8.2772e-04 Epoch 40/100 57/57 [==============================] - 1s 24ms/step - loss: 4.8564e-04 - val_loss: 0.0010 Epoch 41/100 57/57 [==============================] - 1s 24ms/step - loss: 4.3262e-04 - val_loss: 0.0022 Epoch 42/100 57/57 [==============================] - 1s 24ms/step - loss: 4.2805e-04 - val_loss: 7.7834e-04 9/9 [==============================] - 1s 7ms/step
MAPE: 2.13% RMSE: 0.02 MAE: 0.02 R² Score: 0.95 SMAPE: 2.14% Explained Variance Score: 0.95
合并数据-这个不行!¶
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_percentage_error, mean_squared_error, r2_score, explained_variance_score
from keras import Model
from keras.layers import Input, Dense, Dropout, LSTM
from keras.callbacks import EarlyStopping
import warnings
warnings.filterwarnings('ignore')
# === 数据收集与预处理 ===
df = pd.read_csv('combined_data.csv')
# 1. 数据清洗:去除无关列(如交易量和百分比变化),确保数据质量
df.drop(['Vol.', 'Change %'], axis=1, inplace=True)
# 2. 日期格式转换与排序
df['Date'] = pd.to_datetime(df['Date'])
df.sort_values(by='Date', ascending=True, inplace=True)
df.reset_index(drop=True, inplace=True)
# 3. 去除“,”符号并转换为float类型
NumCols = df.columns.drop(['Date'])
df[NumCols] = df[NumCols].replace({',': ''}, regex=True).astype('float64')
# === 截取数据到2022.12.30 ===
df_filtered = df[df['Date'] <= '2022-12-30']
# === 数据波动规律分析 ===
# 使用描述性统计方法分析黄金价格波动特性
print(f"黄金价格数据的均值:\n{df_filtered['Price'].mean()}")
print(f"黄金价格数据的标准差:\n{df_filtered['Price'].std()}")
print(f"黄金价格数据的变异系数:\n{df_filtered['Price'].std() / df_filtered['Price'].mean()}")
# 自相关函数与偏自相关函数分析 (ACF 和 PACF)
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(df_filtered['Price'], lags=50)
plt.title('自相关函数 (ACF) 分析')
plt.show()
plot_pacf(df_filtered['Price'], lags=50)
plt.title('偏自相关函数 (PACF) 分析')
plt.show()
plot_pacf(df['Price'], lags=50)
plt.title('偏自相关函数 (PACF) 分析')
plt.show()
# === 可视化黄金价格 ===
fig = px.line(y=df['Price'], x=df['Date'], title="Gold Price History Data")
fig.update_traces(line_color='black')
fig.update_layout(plot_bgcolor='rgba(255,223,0,0.8)', xaxis_title="Date", yaxis_title="Scaled Price")
fig.show()
# === 数据预处理:标准化与归一化 ===
scaler = MinMaxScaler()
scaler.fit(df['Price'].values.reshape(-1, 1))
# 训练数据与测试数据切分,测试数据包含2022年的数据
test_size = df[df['Date'].dt.year == 2022].shape[0]
train_data = scaler.transform(df['Price'][:-test_size].values.reshape(-1, 1))
test_data = scaler.transform(df['Price'][-test_size - 60:].values.reshape(-1, 1))
# 滑动窗口构造特征和标签
window_size = 60
X_train, y_train, X_test, y_test = [], [], [], []
# 训练数据
for i in range(window_size, len(train_data)):
X_train.append(train_data[i - window_size:i, 0])
y_train.append(train_data[i, 0])
# 测试数据
for i in range(window_size, len(test_data)):
X_test.append(test_data[i - window_size:i, 0])
y_test.append(test_data[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_test, y_test = np.array(X_test), np.array(y_test)
# 调整数据形状以适应LSTM输入
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
y_train = y_train.reshape((-1, 1))
y_test = y_test.reshape((-1, 1))
# === 基于LSTM的黄金价格预测 ===
def define_model():
input1 = Input(shape=(window_size, 1))
x = LSTM(units=64, return_sequences=True)(input1)
x = Dropout(0.2)(x)
x = LSTM(units=32)(x) # 使用较少的LSTM单元以减少过拟合
x = Dropout(0.2)(x)
dnn_output = Dense(1)(x) # 输出层为线性激活函数
model = Model(inputs=input1, outputs=[dnn_output])
model.compile(loss='mean_squared_error', optimizer='Adam') # 使用Adam优化器进行回归任务
return model
model = define_model()
# 训练模型
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
history = model.fit(X_train, y_train, epochs=100, batch_size=32, validation_split=0.2,
callbacks=[early_stopping], verbose=1)
# === 可视化结果 ===
y_pred = model.predict(X_test)
y_test_true = scaler.inverse_transform(y_test)
y_test_pred = scaler.inverse_transform(y_pred)
# 训练数据与预测结果可视化
plt.figure(figsize=(15, 6))
plt.plot(df['Date'].iloc[:-test_size], scaler.inverse_transform(train_data), color='black', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_true, color='blue', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_pred, color='red', lw=2)
plt.title('Model Performance on Gold Price Prediction', fontsize=15)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price', fontsize=12)
plt.legend(['Training Data', 'Actual Test Data', 'Predicted Test Data'], loc='upper left', prop={'size': 15})
plt.grid(color='white')
plt.show()
# === 结果评价 ===
MAPE = mean_absolute_percentage_error(y_test, y_pred)
MSE = mean_squared_error(y_test, y_pred)
RMSE = np.sqrt(MSE)
MAE = np.mean(np.abs(y_test - y_pred))
R2 = r2_score(y_test, y_pred)
SMAPE = np.mean(2 * np.abs(y_test - y_pred) / (np.abs(y_test) + np.abs(y_pred))) * 100
EVS = explained_variance_score(y_test, y_pred)
print(f"MAPE: {MAPE * 100:.2f}%")
print(f"RMSE: {RMSE:.2f}")
print(f"MAE: {MAE:.2f}")
print(f"R² Score: {R2:.2f}")
print(f"SMAPE: {SMAPE:.2f}%")
print(f"Explained Variance Score: {EVS:.2f}")
# 残差分布
residuals = y_test - y_pred
plt.figure(figsize=(10, 5))
plt.hist(residuals, bins=50, color='purple', alpha=0.7)
plt.title('Residual Distribution')
plt.xlabel('Residuals')
plt.ylabel('Frequency')
plt.show()
黄金价格数据的均值: 1440.3264421215642 黄金价格数据的标准差: 257.33828198407844 黄金价格数据的变异系数: 0.1786666372694135
Epoch 1/100 68/68 [==============================] - 4s 31ms/step - loss: 0.0238 - val_loss: 0.0140 Epoch 2/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0060 - val_loss: 0.0093 Epoch 3/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0052 - val_loss: 0.0086 Epoch 4/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0048 - val_loss: 0.0091 Epoch 5/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0045 - val_loss: 0.0092 Epoch 6/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0043 - val_loss: 0.0088 Epoch 7/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0042 - val_loss: 0.0089 Epoch 8/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0038 - val_loss: 0.0085 Epoch 9/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0044 - val_loss: 0.0084 Epoch 10/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0038 - val_loss: 0.0084 Epoch 11/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0035 - val_loss: 0.0086 Epoch 12/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0034 - val_loss: 0.0092 Epoch 13/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0034 - val_loss: 0.0087 Epoch 14/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0034 - val_loss: 0.0103 Epoch 15/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0030 - val_loss: 0.0084 Epoch 16/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0027 - val_loss: 0.0086 Epoch 17/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0028 - val_loss: 0.0086 Epoch 18/100 68/68 [==============================] - 2s 24ms/step - loss: 0.0031 - val_loss: 0.0084 Epoch 19/100 68/68 [==============================] - 2s 25ms/step - loss: 0.0027 - val_loss: 0.0084 9/9 [==============================] - 0s 8ms/step
MAPE: 17342643411353600.00% RMSE: 0.04 MAE: 0.04 R² Score: 0.00 SMAPE: 200.00% Explained Variance Score: 1.00
有一个调整后的收盘价(调整后的黄金收盘价,考虑了股票分割、股息等调整。)
In [7]:
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 使用测试集进行预测
predictions = model.predict(X_test)
# 反归一化预测值和实际值
predictions = scaler.inverse_transform(predictions)
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))
# 计算RMSE和MAE
rmse = np.sqrt(mean_squared_error(y_test_actual, predictions))
mae = mean_absolute_error(y_test_actual, predictions)
print(f'RMSE: {rmse}')
print(f'MAE: {mae}')
# 可视化实际值与预测值
plt.figure(figsize=(12, 6))
plt.plot(y_test_actual, color='blue', label='Actual Price')
plt.plot(predictions, color='red', label='Predicted Price')
plt.title('Gold Price Prediction')
plt.xlabel('Date')
plt.ylabel('Gold Price')
plt.legend()
plt.show()
31/31 [==============================] - 0s 9ms/step RMSE: 33.56104053165467 MAE: 26.455290258290812
按照Adj合并数据
In [6]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_percentage_error, mean_squared_error, r2_score, explained_variance_score
from keras import Model
from keras.layers import Input, Dense, Dropout, LSTM
from keras.callbacks import EarlyStopping
import warnings
warnings.filterwarnings('ignore')
# === 数据收集与预处理 ===
df = pd.read_csv('merged_data.csv')
# 1. 数据清洗:去除无关列(如交易量和百分比变化),确保数据质量
df.drop(['Vol.', 'Change %'], axis=1, inplace=True)
# 2. 日期格式转换与排序
df['Date'] = pd.to_datetime(df['Date'])
df.sort_values(by='Date', ascending=True, inplace=True)
df.reset_index(drop=True, inplace=True)
# 3. 去除“,”符号并转换为float类型
NumCols = df.columns.drop(['Date'])
df[NumCols] = df[NumCols].replace({',': ''}, regex=True).astype('float64')
# === 截取数据到2022.12.30 ===
df_filtered = df[df['Date'] <= '2022-12-30']
# === 数据波动规律分析 ===
# 使用描述性统计方法分析黄金价格波动特性
print(f"黄金价格数据的均值:\n{df_filtered['Price'].mean()}")
print(f"黄金价格数据的标准差:\n{df_filtered['Price'].std()}")
print(f"黄金价格数据的变异系数:\n{df_filtered['Price'].std() / df_filtered['Price'].mean()}")
# 自相关函数与偏自相关函数分析 (ACF 和 PACF)
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(df_filtered['Price'], lags=50)
plt.title('自相关函数 (ACF) 分析')
plt.show()
plot_pacf(df_filtered['Price'], lags=50)
plt.title('偏自相关函数 (PACF) 分析')
plt.show()
plot_pacf(df['Price'], lags=50)
plt.title('偏自相关函数 (PACF) 分析')
plt.show()
# === 可视化黄金价格 ===
fig = px.line(y=df['Price'], x=df['Date'], title="Gold Price History Data")
fig.update_traces(line_color='black')
fig.update_layout(plot_bgcolor='rgba(255,223,0,0.8)', xaxis_title="Date", yaxis_title="Scaled Price")
fig.show()
# === 数据预处理:标准化与归一化 ===
scaler = MinMaxScaler()
scaler.fit(df['Price'].values.reshape(-1, 1))
# 训练数据与测试数据切分,测试数据包含2022年的数据
test_size = df[df['Date'].dt.year == 2022].shape[0]
train_data = scaler.transform(df['Price'][:-test_size].values.reshape(-1, 1))
test_data = scaler.transform(df['Price'][-test_size - 60:].values.reshape(-1, 1))
# 滑动窗口构造特征和标签
window_size = 60
X_train, y_train, X_test, y_test = [], [], [], []
# 训练数据
for i in range(window_size, len(train_data)):
X_train.append(train_data[i - window_size:i, 0])
y_train.append(train_data[i, 0])
# 测试数据
for i in range(window_size, len(test_data)):
X_test.append(test_data[i - window_size:i, 0])
y_test.append(test_data[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_test, y_test = np.array(X_test), np.array(y_test)
# 调整数据形状以适应LSTM输入
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
y_train = y_train.reshape((-1, 1))
y_test = y_test.reshape((-1, 1))
# === 基于LSTM的黄金价格预测 ===
def define_model():
input1 = Input(shape=(window_size, 1))
x = LSTM(units=64, return_sequences=True)(input1)
x = Dropout(0.2)(x)
x = LSTM(units=32)(x) # 使用较少的LSTM单元以减少过拟合
x = Dropout(0.2)(x)
dnn_output = Dense(1)(x) # 输出层为线性激活函数
model = Model(inputs=input1, outputs=[dnn_output])
model.compile(loss='mean_squared_error', optimizer='Adam') # 使用Adam优化器进行回归任务
return model
model = define_model()
# 训练模型
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
history = model.fit(X_train, y_train, epochs=100, batch_size=32, validation_split=0.2,
callbacks=[early_stopping], verbose=1)
# === 可视化结果 ===
y_pred = model.predict(X_test)
y_test_true = scaler.inverse_transform(y_test)
y_test_pred = scaler.inverse_transform(y_pred)
# 训练数据与预测结果可视化
plt.figure(figsize=(15, 6))
plt.plot(df['Date'].iloc[:-test_size], scaler.inverse_transform(train_data), color='black', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_true, color='blue', lw=2)
plt.plot(df['Date'].iloc[-test_size:], y_test_pred, color='red', lw=2)
plt.title('Model Performance on Gold Price Prediction', fontsize=15)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price', fontsize=12)
plt.legend(['Training Data', 'Actual Test Data', 'Predicted Test Data'], loc='upper left', prop={'size': 15})
plt.grid(color='white')
plt.show()
# === 结果评价 ===
MAPE = mean_absolute_percentage_error(y_test, y_pred)
MSE = mean_squared_error(y_test, y_pred)
RMSE = np.sqrt(MSE)
MAE = np.mean(np.abs(y_test - y_pred))
R2 = r2_score(y_test, y_pred)
SMAPE = np.mean(2 * np.abs(y_test - y_pred) / (np.abs(y_test) + np.abs(y_pred))) * 100
EVS = explained_variance_score(y_test, y_pred)
print(f"MAPE: {MAPE * 100:.2f}%")
print(f"RMSE: {RMSE:.2f}")
print(f"MAE: {MAE:.2f}")
print(f"R² Score: {R2:.2f}")
print(f"SMAPE: {SMAPE:.2f}%")
print(f"Explained Variance Score: {EVS:.2f}")
# 残差分布
residuals = y_test - y_pred
plt.figure(figsize=(10, 5))
plt.hist(residuals, bins=50, color='purple', alpha=0.7)
plt.title('Residual Distribution')
plt.xlabel('Residuals')
plt.ylabel('Frequency')
plt.show()
黄金价格数据的均值: 1070.8906493856173 黄金价格数据的标准差: 511.38204678654887 黄金价格数据的变异系数: 0.47752965914861134
Epoch 1/100 144/144 [==============================] - 8s 33ms/step - loss: 0.0041 - val_loss: 5.1289e-04 Epoch 2/100 144/144 [==============================] - 4s 29ms/step - loss: 0.0012 - val_loss: 4.4126e-04 Epoch 3/100 144/144 [==============================] - 4s 30ms/step - loss: 0.0011 - val_loss: 3.7056e-04 Epoch 4/100 144/144 [==============================] - 4s 29ms/step - loss: 9.5583e-04 - val_loss: 2.2716e-04 Epoch 5/100 144/144 [==============================] - 4s 29ms/step - loss: 9.1601e-04 - val_loss: 2.9180e-04 Epoch 6/100 144/144 [==============================] - 5s 32ms/step - loss: 7.8637e-04 - val_loss: 2.9216e-04 Epoch 7/100 144/144 [==============================] - 4s 30ms/step - loss: 7.4767e-04 - val_loss: 1.8399e-04 Epoch 8/100 144/144 [==============================] - 4s 30ms/step - loss: 6.2432e-04 - val_loss: 3.9897e-04 Epoch 9/100 144/144 [==============================] - 4s 28ms/step - loss: 6.0587e-04 - val_loss: 2.1108e-04 Epoch 10/100 144/144 [==============================] - 4s 29ms/step - loss: 5.5234e-04 - val_loss: 1.6850e-04 Epoch 11/100 144/144 [==============================] - 4s 28ms/step - loss: 5.6949e-04 - val_loss: 3.5206e-04 Epoch 12/100 144/144 [==============================] - 4s 28ms/step - loss: 4.9762e-04 - val_loss: 1.8793e-04 Epoch 13/100 144/144 [==============================] - 4s 28ms/step - loss: 5.1400e-04 - val_loss: 3.4036e-04 Epoch 14/100 144/144 [==============================] - 4s 28ms/step - loss: 4.4875e-04 - val_loss: 1.7524e-04 Epoch 15/100 144/144 [==============================] - 4s 28ms/step - loss: 4.6534e-04 - val_loss: 1.5972e-04 Epoch 16/100 144/144 [==============================] - 4s 28ms/step - loss: 4.3271e-04 - val_loss: 2.3068e-04 Epoch 17/100 144/144 [==============================] - 4s 28ms/step - loss: 4.0546e-04 - val_loss: 1.4577e-04 Epoch 18/100 144/144 [==============================] - 4s 28ms/step - loss: 4.1853e-04 - val_loss: 1.4301e-04 Epoch 19/100 144/144 [==============================] - 4s 28ms/step - loss: 3.9021e-04 - val_loss: 2.9579e-04 Epoch 20/100 144/144 [==============================] - 4s 28ms/step - loss: 4.1008e-04 - val_loss: 2.5090e-04 Epoch 21/100 144/144 [==============================] - 4s 28ms/step - loss: 3.8460e-04 - val_loss: 1.4882e-04 Epoch 22/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7996e-04 - val_loss: 2.0039e-04 Epoch 23/100 144/144 [==============================] - 4s 28ms/step - loss: 3.9975e-04 - val_loss: 7.4763e-04 Epoch 24/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7810e-04 - val_loss: 1.5359e-04 Epoch 25/100 144/144 [==============================] - 4s 29ms/step - loss: 3.8939e-04 - val_loss: 3.2852e-04 Epoch 26/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7534e-04 - val_loss: 3.3058e-04 Epoch 27/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4825e-04 - val_loss: 1.3605e-04 Epoch 28/100 144/144 [==============================] - 4s 29ms/step - loss: 3.5979e-04 - val_loss: 1.3253e-04 Epoch 29/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6403e-04 - val_loss: 1.8999e-04 Epoch 30/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7899e-04 - val_loss: 1.8807e-04 Epoch 31/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6341e-04 - val_loss: 1.1519e-04 Epoch 32/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6887e-04 - val_loss: 1.2464e-04 Epoch 33/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6220e-04 - val_loss: 3.6573e-04 Epoch 34/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7045e-04 - val_loss: 1.6377e-04 Epoch 35/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6401e-04 - val_loss: 1.0666e-04 Epoch 36/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6597e-04 - val_loss: 1.0687e-04 Epoch 37/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6820e-04 - val_loss: 1.9977e-04 Epoch 38/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7420e-04 - val_loss: 1.4378e-04 Epoch 39/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7782e-04 - val_loss: 1.0803e-04 Epoch 40/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6484e-04 - val_loss: 1.0473e-04 Epoch 41/100 144/144 [==============================] - 4s 28ms/step - loss: 3.5015e-04 - val_loss: 2.0848e-04 Epoch 42/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7649e-04 - val_loss: 6.8819e-04 Epoch 43/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6170e-04 - val_loss: 1.2957e-04 Epoch 44/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7590e-04 - val_loss: 1.7945e-04 Epoch 45/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4852e-04 - val_loss: 3.8849e-04 Epoch 46/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4151e-04 - val_loss: 1.1588e-04 Epoch 47/100 144/144 [==============================] - 4s 31ms/step - loss: 3.4326e-04 - val_loss: 2.5046e-04 Epoch 48/100 144/144 [==============================] - 4s 31ms/step - loss: 3.5488e-04 - val_loss: 1.9809e-04 Epoch 49/100 144/144 [==============================] - 4s 31ms/step - loss: 3.6603e-04 - val_loss: 1.0956e-04 Epoch 50/100 144/144 [==============================] - 4s 31ms/step - loss: 3.6098e-04 - val_loss: 8.9350e-05 Epoch 51/100 144/144 [==============================] - 4s 31ms/step - loss: 3.5511e-04 - val_loss: 2.0698e-04 Epoch 52/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4740e-04 - val_loss: 9.2492e-05 Epoch 53/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4476e-04 - val_loss: 3.4439e-04 Epoch 54/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6430e-04 - val_loss: 2.2575e-04 Epoch 55/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4790e-04 - val_loss: 8.2480e-05 Epoch 56/100 144/144 [==============================] - 4s 28ms/step - loss: 3.7089e-04 - val_loss: 8.7028e-05 Epoch 57/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6931e-04 - val_loss: 1.0444e-04 Epoch 58/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4114e-04 - val_loss: 1.7301e-04 Epoch 59/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6395e-04 - val_loss: 2.1453e-04 Epoch 60/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3824e-04 - val_loss: 7.7794e-05 Epoch 61/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4789e-04 - val_loss: 1.7016e-04 Epoch 62/100 144/144 [==============================] - 4s 28ms/step - loss: 3.2862e-04 - val_loss: 1.1347e-04 Epoch 63/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3887e-04 - val_loss: 8.3907e-05 Epoch 64/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3142e-04 - val_loss: 9.1713e-05 Epoch 65/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3652e-04 - val_loss: 1.0033e-04 Epoch 66/100 144/144 [==============================] - 4s 28ms/step - loss: 3.5593e-04 - val_loss: 7.5379e-05 Epoch 67/100 144/144 [==============================] - 4s 28ms/step - loss: 3.8038e-04 - val_loss: 7.6659e-05 Epoch 68/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3520e-04 - val_loss: 9.2858e-05 Epoch 69/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3597e-04 - val_loss: 7.6740e-05 Epoch 70/100 144/144 [==============================] - 4s 28ms/step - loss: 3.6585e-04 - val_loss: 7.4616e-05 Epoch 71/100 144/144 [==============================] - 4s 30ms/step - loss: 3.3089e-04 - val_loss: 7.3575e-05 Epoch 72/100 144/144 [==============================] - 5s 31ms/step - loss: 3.4902e-04 - val_loss: 1.2665e-04 Epoch 73/100 144/144 [==============================] - 5s 33ms/step - loss: 3.2670e-04 - val_loss: 3.5741e-04 Epoch 74/100 144/144 [==============================] - 5s 31ms/step - loss: 3.4959e-04 - val_loss: 9.4258e-05 Epoch 75/100 144/144 [==============================] - 5s 31ms/step - loss: 3.5039e-04 - val_loss: 2.2427e-04 Epoch 76/100 144/144 [==============================] - 4s 31ms/step - loss: 3.5300e-04 - val_loss: 6.8933e-05 Epoch 77/100 144/144 [==============================] - 5s 31ms/step - loss: 3.2814e-04 - val_loss: 8.4866e-05 Epoch 78/100 144/144 [==============================] - 4s 30ms/step - loss: 3.5295e-04 - val_loss: 7.2376e-05 Epoch 79/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3669e-04 - val_loss: 7.1520e-05 Epoch 80/100 144/144 [==============================] - 4s 28ms/step - loss: 3.1658e-04 - val_loss: 1.8147e-04 Epoch 81/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3660e-04 - val_loss: 1.3083e-04 Epoch 82/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3517e-04 - val_loss: 1.2722e-04 Epoch 83/100 144/144 [==============================] - 4s 29ms/step - loss: 3.3877e-04 - val_loss: 5.0633e-04 Epoch 84/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4144e-04 - val_loss: 1.9960e-04 Epoch 85/100 144/144 [==============================] - 4s 28ms/step - loss: 3.3836e-04 - val_loss: 7.6488e-05 Epoch 86/100 144/144 [==============================] - 4s 28ms/step - loss: 3.4101e-04 - val_loss: 2.9194e-04 8/8 [==============================] - 1s 10ms/step
MAPE: 1.29% RMSE: 0.01 MAE: 0.01 R² Score: 0.98 SMAPE: 1.30% Explained Variance Score: 0.99
In [7]:
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 使用测试集进行预测
predictions = model.predict(X_test)
# 反归一化预测值和实际值
predictions = scaler.inverse_transform(predictions)
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))
# 计算RMSE和MAE
rmse = np.sqrt(mean_squared_error(y_test_actual, predictions))
mae = mean_absolute_error(y_test_actual, predictions)
print(f'RMSE: {rmse}')
print(f'MAE: {mae}')
# 可视化实际值与预测值
plt.figure(figsize=(12, 6))
plt.plot(y_test_actual, color='blue', label='Actual Price')
plt.plot(predictions, color='red', label='Predicted Price')
plt.title('Gold Price Prediction')
plt.xlabel('Date')
plt.ylabel('Gold Price')
plt.legend()
plt.show()
8/8 [==============================] - 0s 9ms/step RMSE: 33.28963527997025 MAE: 27.057600167268436
In [ ]: