You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARIMA模型预测汇率输出NaN问题排查及任务求助

问题排查与任务完成:卢布对埃及英镑汇率预测

任务目标

  • 基于交易日收盘数据构建俄罗斯卢布对埃及英镑的汇率走势图
  • 选择最优ARIMA模型预测后续汇率值
  • 将预测结果可视化并得出结论

现存问题

  • 运行代码输出预测值时出现NaN,已确认原始数据无缺失但无法解决
  • 当前代码错误处理**卢布对挪威克朗(NOK)**的数据,与任务要求的卢布对埃及英镑不符

问题排查与修正方案

1. 数据匹配错误修正

首先从数据文件中筛选**埃及英镑(EGP)**的对应数据,替换原代码中筛选NOK的逻辑:

# 原筛选NOK的代码替换为:
if row[0] == 'EGP':
    dates.append(pd.to_datetime(int(row[2]), format='%Y%m%d'))
    rub_to_egp.append(float(row[6]))

同时修改数据框列名,确保一致性:

data = pd.DataFrame({'Date': dates, 'RUB_to_EGP': rub_to_egp})

2. NaN预测值排查与解决

预测出现NaN的核心原因及修复方式:

  • 阶数选择不当:原代码直接使用(3,1,0)阶数,未通过数据特征确定最优参数。建议用pmdarima的auto_arima自动筛选:
    from pmdarima import auto_arima
    stepwise_fit = auto_arima(data['RUB_to_EGP'], trace=True, suppress_warnings=True)
    model = sm.tsa.ARIMA(data['RUB_to_EGP'], order=stepwise_fit.order)
    
  • 日期频率不匹配:原预测用freq='D'(自然日),但汇率数据仅包含交易日,应改用freq='B'(工作日频率):
    forecast_index = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=30, freq='B')
    
  • 模型收敛问题:若拟合时出现警告,可增加迭代次数:
    model_fit = model.fit(maxiter=500)
    

3. 可视化修正

修正图表标题、坐标轴标签,匹配任务主题:

plt.title('俄罗斯卢布对埃及英镑汇率走势及ARIMA预测')
plt.xlabel('日期')
plt.ylabel('1埃及英镑兑换卢布数')

完整修正代码

import matplotlib.pyplot as plt
import pandas as pd
import csv
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
from pmdarima import auto_arima

def tundra():
    print('1 - 显示图表')
    print('2 - 保存图表')
    oi = input('选择操作: ')
    if oi == '1':
        plt.show()
    elif oi == '2':
        po = input('输入保存文件名: ')
        plt.savefig(f'{po}.jpg')
        print(f'图表已保存为 {po}.jpg')
    else:
        print('输入无效,请重新选择')
        tundra()

dates = []
rub_to_egp = []

# 读取数据并筛选埃及英镑数据,跳过格式错误行
with open('D:\\Teleegram dw\\mfdexport_1month_01012014_30082024.csv', 'r') as csvfile:
    plots = csv.reader(csvfile, delimiter=';')
    next(plots)
    for row in plots:
        if row[0] == 'EGP':
            try:
                dates.append(pd.to_datetime(int(row[2]), format='%Y%m%d'))
                rub_to_egp.append(float(row[6]))
            except ValueError:
                continue

# 构建数据框并处理缺失值
data = pd.DataFrame({'Date': dates, 'RUB_to_EGP': rub_to_egp})
data.set_index('Date', inplace=True)
print("检查数据中的NaN:")
print(data.isnull().sum())
data.dropna(inplace=True)

print("\n数据信息:")
print(data.info())
print("\n数据前5行:")
print(data.head())

# 平稳性检验
result = adfuller(data['RUB_to_EGP'])
print('\nDickey-Fuller 平稳性检验结果:')
print('统计量: %f' % result[0])
print('p值: %f' % result[1])
print('临界值:')
for key, value in result[4].items():
    print(f'    {key}: {value}')

# 自动筛选最优ARIMA模型
print('\n自动筛选最优ARIMA模型...')
stepwise_fit = auto_arima(data['RUB_to_EGP'], trace=True, suppress_warnings=True, seasonal=False)
print('\n最优模型摘要:')
print(stepwise_fit.summary())

# 拟合模型并预测
model = sm.tsa.ARIMA(data['RUB_to_EGP'], order=stepwise_fit.order)
model_fit = model.fit(maxiter=500)
forecast = model_fit.forecast(steps=30)
forecast_index = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=30, freq='B')
forecast_df = pd.DataFrame(forecast, index=forecast_index, columns=['Forecast'])

print("\n预测结果:")
for index, row in forecast_df.iterrows():
    print(f"日期: {index.strftime('%Y-%m-%d')}, 预测汇率: {row['Forecast']:.4f}")

# 可视化
plt.figure(figsize=(25, 12), facecolor='grey')
plt.gca().set_facecolor('black')
plt.plot(data.index, data['RUB_to_EGP'], label='实际汇率 RUB/EGP', color='white', alpha=0.5, linewidth=2)
plt.plot(forecast_df.index, forecast_df['Forecast'], label='ARIMA预测值', color='blue', linewidth=2, linestyle='--')
plt.title('俄罗斯卢布对埃及英镑汇率走势及ARIMA预测')
plt.xlabel('日期')
plt.ylabel('1埃及英镑兑换卢布数')
plt.legend()
plt.grid(color='white', alpha=0.3)

tundra()

结论

  1. 数据匹配错误是核心问题之一,必须确保筛选EGP而非NOK的数据
  2. 使用auto_arima自动选择最优阶数,可避免手动选阶不当导致的预测NaN问题
  3. 预测日期使用工作日频率(freq='B')更符合汇率交易日规律,减少模型适配误差
  4. 增加格式错误行的跳过逻辑,可提升数据质量,避免模型拟合失败

内容的提问来源于stack exchange,提问作者Faded Deer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:48:14