Package: pydlm
PyDLMWelcome topydlm, a flexible time series modeling library for python. This library is based on the Bayesian dynamic linear model (Harrison and West, 1999) and optimized for fast model fitting and inference.Updates in the github versionA temporary fix on thepredict()complexity bug (due to incorrect self-referencing, thanks romainjln@ and buhbuhtig@!). The fixedpredict()complxity is O(n). The goal is to make it O(1).A lite versionpydlm-litehas been created where dependencies onmatplotlibwas removed. Going forward, most code refactoring on improving multi-threading and online learning will be done on thepydlm-litepackage. The development onpydlmpackage will primarily focus on supporting broader model classes and more advanced sampling algorithms.Version 0.1.1.11 released on PyPI.InstallationYou can get the package (current version 0.1.1.11) frompypiby$ pip install pydlmYou can also get the latest fromgithub$ git clone git@github.com:wwrechard/pydlm.git pydlm
  $ cd pydlm
  $ sudo python setup.py installpydlmdepends on the following modules,numpy(for core functionality)matplotlib(for plotting results)Sphinx(for generating documentation)unittest(for testing)Google data science post exampleWe use the example from theGoogle data science postas an example to show howpydlmcould be used to analyze the real world data. The code and data is placed underexamples/unemployment_insurance/.... The dataset contains weekly counts of initial claims for unemployment during 2004 - 2012 and is available from the R packagebsts(which is a popular R package for time series modeling). The raw data is shown below (left)We see strong annual pattern and some local trend from the data.A simple modelFollowing the Google's post, we first build a simple model with only local linear trend and seasonality component.frompydlmimportdlm,trend,seasonality# A linear trendlinear_trend=trend(degree=1,discount=0.95,name='linear_trend',w=10)# A seasonalityseasonal52=seasonality(period=52,discount=0.99,name='seasonal52',w=10)# Build a simple dlmsimple_dlm=dlm(time_series)+linear_trend+seasonal52In the actual code, the time series data is scored in the variabletime_series.degree=1indicates the trend is linear (2 stands for quadratic) andperiod=52means the seasonality has a periodicy of 52. Since the seasonality is generally more stable, we set its discount factor to 0.99. For local linear trend, we use 0.95 to allow for some flexibility.w=10is the prior guess on the variance of each component, the larger number the more uncertain. For actual meaning of these parameters, please refer to theuser manual. After the model built, we can fit the model and plot the result (shown above, right figure)# Fit the modelsimple_dlm.fit()# Plot the fitted resultssimple_dlm.turnOff('data points')simple_dlm.plot()The blue curve is the forward filtering result, the green curve is the one-day ahead prediction and the red curve is the backward smoothed result. The light-colored ribbon around the curve is the confidence interval (you might need to zoom-in to see it). The one-day ahead prediction shows this simple model captures the time series somewhat good but loses accuracy around the peak crisis at Week 280 (which is between year 2008 - 2009). The one-day-ahead mean squared prediction error is0.173which can be obtained by callingsimple_dlm.getMSE()We can decompose the time series into each of its components# Plot each component (attribute the time series to each component)simple_dlm.turnOff('predict plot')simple_dlm.turnOff('filtered plot')simple_dlm.plot('linear_trend')simple_dlm.plot('seasonal52')Most of the time series shape is attributed to the local linear trend and the strong seasonality pattern is easily seen. To further verify the performance, we use this simple model for long-term forecasting. In particular, we use the previous351 week's data to forecast the next200 weeksand the previous251 week's data to forecast the next200 weeks. We lay the predicted results on top of the real data# Plot the prediction give the first 351 weeks and forcast the next 200 weeks.simple_dlm.plotPredictN(date=350,N=200)# Plot the prediction give the first 251 weeks and forcast the next 200 weeks.simple_dlm.plotPredictN(date=250,N=200)From the figure we see that after the crisis peak around 2008 - 2009 (Week 280), the simple model can accurately forecast the next 200 weeks (left figure) given the first 351 weeks. However, the model fails to capture the change near the peak if the forecasting start before Week 280 (right figure).Dynamic linear regressionNow we build a more sophiscated model with extra variables in the data file. The extra variables are stored in the variable `features` in the actual code. To build the dynamic linear regression model, we simply add a new component# Build a dynamic regression modelfrompydlmimportdynamicregressor10=dynamic(features=features,discount=1.0,name='regressor10',w=10)drm=dlm(time_series)+linear_trend+seasonal52+regressor10drm.fit()drm.getMSE()# Plot the fitted resultsdrm.turnOff('data points')drm.plot()dynamicis the component for modeling dynamically changing predictors, which acceptsfeaturesas its argument. The above code plots the fitted result (top left).The one-day ahead prediction looks much better than the simple model, particularly around the crisis peak. The mean prediction error is0.099which is a 100% improvement over the simple model. Similarly, we also decompose the time series into the three componentsdrm.turnOff('predict plot')drm.turnOff('filtered plot')drm.plot('linear_trend')drm.plot('seasonal52')drm.plot('regressor10')This time, the shape of the time series is mostly attributed to the regressor and the linear trend looks more linear. If we do long-term forecasting again, i.e., use the previous301 week's data to forecast the next150 weeksand the previous251 week's data to forecast the next200 weeksdrm.plotPredictN(date=300,N=150)drm.plotPredictN(date=250,N=200)The results look much better compared to the simple modelDocumentationDetailed documentation is provided inPyDLMwith special attention to theUser manual.