首页 > 解决方案 > 为模型训练和预测加密货币价格获取数据的问题

问题描述

我正在尝试使用 Facebook 的 Prophet 模型和来自 Yahoo Finance 的加密货币价格数据来预测未来价格。我已经导入了所有库,定义了从 Yahoo Finance 获取历史数据的函数,但是在获取数据并训练模型后,当我尝试运行代码以可视化数据时,我得到一个 ValueError: ValueError: All arguments should have the same长度。参数的长度y是 4,而前面的参数 ['ds'] 的长度是 398。我将把整个代码放在下面。请帮我。

from tqdm import tqdm
import pandas as pd
from prophet import Prophet
import yfinance as yf
from datetime import datetime, timedelta
import plotly.express as px
import numpy as np

def getData(ticker, window, ma_period):
    """
    Grabs price data from a given ticker. Retrieves prices based on the given time window; from now
    to N days ago.  Sets the moving average period for prediction. Returns a preprocessed DF
    formatted for FB Prophet.
    """
    # Time periods
    now = datetime.now()

    # How far back to retrieve tweets
    ago = now - timedelta(days=window)

    # Designating the Ticker
    crypto = yf.Ticker(ticker)

    # Getting price history
    df = crypto.history(start=ago.strftime("%Y-%m-%d"), end=now.strftime("%Y-%m-%d"), interval="1d")
    
    # Handling missing data from yahoo finance
    df = df.reindex(
        [df.index.min()+pd.offsets.Day(i) for i in range(df.shape[0])],
        fill_value=None
    ).fillna(method='ffill')
    
    # Getting the N Day Moving Average and rounding the values
    df['MA'] = df[['Open']].rolling(window=ma_period).mean().apply(lambda x: round(x, 2))

    # Dropping the NaNs
    df.dropna(inplace=True)

    # Formatted for FB Prophet
    df = df.reset_index().rename(columns={"Date": "ds", "MA": "y"})
    
    return df



def fbpTrainPredict(df, forecast_period):
    """
    Uses FB Prophet and fits to a appropriately formatted DF. Makes a prediction N days into 
    the future based on given forecast period. Returns predicted values as a DF.
    """
    # Setting up prophet
    m = Prophet(
        daily_seasonality=True, 
        yearly_seasonality=True, 
        weekly_seasonality=True
    )
    
    # Fitting to the prices
    m.fit(df[['ds', 'y']])
    
    # Future DF
    future = m.make_future_dataframe(periods=forecast_period)
        
    # Predicting values
    forecast = m.predict(future)

    # Returning a set of predicted values
    return forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']]

def visFBP(df, forecast):
    """
    Given two dataframes: before training df and a forecast df, returns
    a visual chart of the predicted values and actual values.
    """
    # Visual DF
    vis_df = df[['ds','Open']].append(forecast).rename(
        columns={'yhat': 'Prediction',
                 'yhat_upper': "Predicted High",
                 'yhat_lower': "Predicted Low"}
    )

    # Visualizing results
    fig = px.line(
        vis_df,
        x='ds',
        y=['Open', 'Prediction', 'Predicted High', 'Predicted Low'],
        title='Crypto Forecast',
        labels={'value':'Price',
                'ds': 'Date'}
    )

    # Adding a slider
    fig.update_xaxes(
        rangeselector=dict(
            buttons=list([
                dict(count=1, label="1m", step="month", stepmode="backward"),
                dict(count=3, label="3m", step="month", stepmode="backward"),
                dict(count=6, label="6m", step="month", stepmode="backward"),
                dict(count=1, label="YTD", step="year", stepmode="todate"),
                dict(count=1, label="1y", step="year", stepmode="backward"),
                dict(step="all")
            ])
        )
    )

    return fig.show()

 
# Getting and Formatting Data
df = getData("SHIB-USD", window=730, ma_period=5)
# Training and Predicting Data
forecast = fbpTrainPredict(df, forecast_period=90)
# Visualizing Data
visFBP(df, forecast)

标签: pythonpython-3.xpandasnumpyfacebook-prophet

解决方案


我使用 plotly 的图形对象单独添加每条图形线。确保包含 graph_objects:import plotly.graph_objects as go

然后代替:

# Visualizing results
fig = px.line(
    vis_df,
    x='ds',
    y=['Open', 'Prediction', 'Predicted High', 'Predicted Low'],
    title='Crypto Forecast',
    labels={'value':'Price',
            'ds': 'Date'}
)

您创建空图并将每个数据列添加为“散点图”:

# Visualizing results
fig = go.Figure()
fig.add_scatter(x=vis_df['ds'], y=vis_df['Open'],mode='lines', name="Open")
fig.add_scatter(x=vis_df['ds'], y=vis_df['Prediction'],mode='lines', name="Prediction")
fig.add_scatter(x=vis_df['ds'], y=vis_df['Predicted Low'],mode='lines', name="Predicted Low")
fig.add_scatter(x=vis_df['ds'], y=vis_df['Predicted High'],mode='lines', name="Predicted High")
fig.update_layout(
    title="Crypto Forecast",
    xaxis_title="Date",
    yaxis_title="Price",
)

您的预测似乎仍然存在问题,但我将不得不将其留给其他人。


推荐阅读