python做时间序列分析详解

综述

时间序列分析是一种统计技术,用于分析按时间顺序排列的数据点。它在许多领域中都有应用,如经济学、气象学、金融学等。时间序列分析的目的是通过对历史数据的学习,来预测未来的趋势、季节性变化、周期性变化等。下面是时间序列分析中的一些核心数学原理和公式:
在这里插入图片描述
在这里插入图片描述

常用的包

在Python中,有几个流行的库可以用于时间序列分析。以下是一些主要的包以及它们在时间序列分析中的一些应用示例。

  1. pandas:
    Pandas是Python中处理时间序列数据的基础库。它提供了DateTimeIndex,可以轻松地将时间数据设置为序列的索引,并进行时间序列分析。

    示例代码:

    import pandas as pd
    
    # 创建时间序列数据
    dates = pd.date_range('20230101', periods=6)
    data = pd.Series([1, 3, 2, 5, 4, 6], index=dates)
    print(data)
    
  2. NumPy:
    NumPy提供了一些基础的数学函数,可以用来进行时间序列数据的数值计算。

    示例代码:

    import numpy as np
    
    # 计算移动平均
    window_size = 3
    moving_average = np.convolve(data, np.ones(window_size)/window_size, mode='valid')
    print(moving_average)
    
  3. statsmodels:
    Statsmodels是一个统计模型库,它提供了许多用于时间序列分析的模型,如ARIMA、季节性分解等。

    示例代码:

    import statsmodels.api as sm
    
    # ARIMA模型
    model = sm.tsa.ARIMA(data, order=(1, 1, 1))
    results = model.fit()
    print(results.summary())
    
  4. matplotlib:
    Matplotlib是一个绘图库,可以用来绘制时间序列数据和分析结果。

    示例代码:

    import matplotlib.pyplot as plt
    
    # 绘制时间序列数据
    plt.plot(data)
    plt.title('Time Series Data')
    plt.xlabel('Date')
    plt.ylabel('Value')
    plt.show()
    
  5. SciPy:
    SciPy库提供了信号处理工具,可以用来进行时间序列的平滑和其他操作。

    示例代码:

    from scipy.signal import savgol_filter
    
    # 使用Savitzky-Golay滤波器进行平滑
    filtered_data = savgol_filter(data, window_length=5, polyorder=2)
    print(filtered_data)
    
  6. scikit-learn:
    Scikit-learn是一个机器学习库,它提供了一些可以用来进行时间序列预测的模型。

    示例代码:

    from sklearn.linear_model import LinearRegression
    
    # 使用线性回归进行时间序列预测
    model = LinearRegression()
    model.fit(np.arange(len(data)).reshape(-1, 1), data)
    predictions = model.predict(np.arange(len(data), len(data) + 10).reshape(-1, 1))
    
  7. Prophet:
    Prophet是由Facebook开发的库,专门用于时间序列预测,它能够处理节假日效应和趋势变化。

    示例代码:

    from prophet import Prophet
    
    # 创建Prophet模型并拟合数据
    df = pd.DataFrame({'ds': dates, 'y': data})
    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(periods=10)
    forecast = m.predict(future)
    print(forecast[['ds', 'yhat']])
    
  8. tslearn:
    Tslearn是一个专门用于时间序列数据的机器学习库,提供了时间序列聚类、分类和回归算法。

    示例代码:

    from tslearn.clustering import TimeSeriesKMeans
    
    # 使用K-Means聚类时间序列数据
    model = TimeSeriesKMeans(n_clusters=2, max_iter=10)
    model.fit(data.values.reshape(-1, 1))
    print(model.predict(data.values.reshape(-1, 1)))
    

这些库可以单独使用,也可以结合使用,以满足不同的时间序列分析需求。在实际应用中,通常需要对数据进行预处理、模型选择、参数调优和结果评估等步骤。

判断是否具有季节性

import pandas as pd
df = pd.read_excel("D:\\PC-backups\\浏览器下载\\尽职调查.xlsx", skiprows=6)
df['月份'] = pd.to_datetime(df['月份'])
df = df[['业务分类','月份','销售额']]

import pandas as pd
import numpy as np


# 计算每个月份的平均销售额
mean_sales = df.groupby('月份')['销售额'].mean()

# 计算每个月份的季节性强度
df['季节性强度'] = df['销售额'] / df['月份'].map(mean_sales)

# 计算每个业务分类的季节性强度平均值
mean_seasonality = df.groupby('业务分类')['季节性强度'].mean()

# 计算每个业务分类的季节性指数
df['季节性指数'] = df['业务分类'].map(mean_seasonality)

# 判断季节性是否显著
df['季节性显著性'] = np.where(df['季节性指数'] > 1.5, '显著', '不显著')

# 输出结果
print(df)
df.to_excel("D:\\PC-backups\\浏览器下载\\try.xlsx")

季节性分解

import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose

df = data.dropna(subset=['sales(bulbs+kits)'])

# 季节性分解
result = seasonal_decompose(df['sales(bulbs+kits)'], model='additive', period=12) #additive  multiplicative

# 可视化分解结果
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(10,8))
result.observed.plot(ax=ax1)
ax1.set_ylabel('Observed')
result.trend.plot(ax=ax2)
ax2.set_ylabel('Trend')
result.seasonal.plot(ax=ax3)
ax3.set_ylabel('Seasonal')
result.resid.plot(ax=ax4)
ax4.set_ylabel('Residual')
plt.tight_layout()
plt.show

# 获取分解结果
df_result = pd.DataFrame({'Observed': result.observed,
                          'Trend': result.trend,
                          'Seasonal': result.seasonal,
                          'Residual': result.resid})

# 打印前几行
print(df_result)

df_result = df_result.dropna()

from sklearn.metrics import mean_squared_error
import numpy as np

# 计算MSE
mse = mean_squared_error(df_result['Observed'], df_result['Trend'] + df_result['Seasonal'] + df_result['Residual'])

print("MSE:", mse)

from sklearn.metrics import r2_score

r2 = r2_score(df_result['Observed'], df_result['Trend'] + df_result['Seasonal'] + df_result['Residual'])

print("R方值为:", r2)

from sklearn.metrics import mean_absolute_error
df_result.fillna(df_result.mean(), inplace=True)


# 计算季节性分解的MAE
mae = mean_absolute_error(df_result['Observed'], df_result['Trend'] + df_result['Seasonal'] + df_result['Residual'])
print('MAE:', mae)

from sklearn.metrics import mean_absolute_percentage_error

# 计算MAPE
mape_value = mean_absolute_percentage_error(df_result['Observed'], df_result['Trend'] + df_result['Seasonal'] + df_result['Residual'])

print("MAPE值为:", mape_value)

ARIMA建模

在这里插入图片描述

dff = dff.loc[:,['月份','sales_amount']]
dff = dff.set_index('月份')

import statsmodels.api as sm
# 单位根检验-ADF检验
print(sm.tsa.stattools.adfuller(dff['sales_amount']))

from statsmodels.stats.diagnostic import acorr_ljungbox
# 白噪声检验
acorr_ljungbox(dff, lags = [1,2,3,4,5,6,7],boxpierce=True)

# 计算ACF
acf=plot_acf(dff)
plt.title("sales_amount of ACF")
plt.show()

# PACF
pacf=plot_pacf(dff)
plt.title("sales_amount of PACF")
plt.show()

# 根据拖尾和截尾确定模型阶数
model = sm.tsa.arima.ARIMA(dff,order=(1,0,0))
arima_res=model.fit()
arima_res.summary()

# 根据AIC、BIC决定模型阶数
trend_evaluate = sm.tsa.arma_order_select_ic(dff, ic=['aic', 'bic'], trend='n', max_ar=20,
                                            max_ma=5)
print('train AIC', trend_evaluate.aic_min_order)
print('train BIC', trend_evaluate.bic_min_order)

# 模型预测
predict=arima_res.predict()
plt.plot(dff.index,dff)
plt.plot(dff.index,predict)
plt.legend(['y_true','y_pred'])
plt.show()
print('月份数:',len(predict))
# 模型评价
from sklearn.metrics import r2_score,mean_absolute_error
print(mean_absolute_error(dff,predict)

      # 模型评价
from sklearn.metrics import r2_score,mean_absolute_error
print(mean_absolute_error(dff,predict))

dff['predict'] = predict
dff['err'] = dff['predict'] - dff['sales_amount']
residual=list(dff['err'])
plt.plot(residual)

# 查看残差的均值
np.mean(residual)

# 查看残差的正态性检验
import seaborn as sns
from scipy import stats
plt.figure(figsize=(10,5))
ax=plt.subplot(1,2,1)
sns.distplot(residual,fit=stats.norm)
ax=plt.subplot(1,2,2)
res=stats.probplot(residual,plot=plt)
plt.show()

SARIMA建模

import pandas as pd
import numpy as np
import statsmodels.api as sm

# 读取时间序列数据
# 拟合SARIMA模型
df = data.dropna(subset=['sales(kits)'])

model = sm.tsa.statespace.SARIMAX(df['sales(kits)'], order=(1,1,0),seasonal_order=(0,0,0,12))
results = model.fit()

# 查看模型的统计信息
print(results.summary())

# 预测未来的时间序列
forecast = results.forecast(steps=12,dynamic=True)
print(forecast)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐木叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值