Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ on:
pull_request:
branches: [ main ]

env:
CMDSTAN_VERSION: "2.26.1"

jobs:
build-and-test-python:

Expand Down Expand Up @@ -38,26 +35,11 @@ jobs:
key: ${{ runner.os }}-pip-${{ hashFiles('**/python/requirements.txt') }}-v1
restore-keys: |
${{ runner.os }}-pip-
- name: "Restore cmdstan cache"
id: cache-cmdstan
uses: actions/cache@v2
with:
path: ${{ env.DEFAULT_HOME }}/.cmdstan
key: ${{ runner.os }}-cmdstan-${{ env.CMDSTAN_VERSION }}-v1
- name: "Download cmdstan"
if: steps.cache-cmdstan.outputs.cache-hit != 'true'
run: |
wget https://github.com/stan-dev/cmdstan/releases/download/v${{ env.CMDSTAN_VERSION }}/cmdstan-${{ env.CMDSTAN_VERSION }}.tar.gz -O /tmp/cmdstan.tar.gz &> /dev/null
mkdir $HOME/.cmdstan
tar -xf /tmp/cmdstan.tar.gz -C $HOME/.cmdstan &> /dev/null
- name: Install and test
run: |
pip install -U -r python/requirements.txt dask[dataframe] distributed
cd python
STAN_BACKEND=PYSTAN python setup.py develop test
python setup.py clean
rm -rf prophet/stan_model
STAN_BACKEND=CMDSTANPY python setup.py develop test
python setup.py develop test

build-and-test-r:

Expand Down
39 changes: 3 additions & 36 deletions .github/workflows/wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ on:
types: [ created ]
workflow_dispatch: {}


env:
STAN_BACKEND: "PYSTAN,CMDSTANPY"
CMDSTAN_VERSION: "2.26.1"
STAN_BACKEND: "CMDSTANPY"

jobs:
make-wheel-windows:
Expand Down Expand Up @@ -55,35 +55,19 @@ jobs:
python -m pip install --upgrade pip
python -m pip install cibuildwheel build delvewheel

- name: "Restore cmdstan cache"
id: cache-cmdstan
uses: actions/cache@v2
with:
path: ${{ env.DEFAULT_HOME }}/.cmdstan
key: ${{ runner.os }}-cmdstan-${{ env.CMDSTAN_VERSION }}-v1

- name: "Restore RTools40"
id: cache-rtools
uses: actions/cache@v2
with:
path: C:/rtools40
key: ${{ runner.os }}-${{ env.OS_VERSION }}-rtools-v1

- name: "Download cmdstan"
if: steps.cache-cmdstan.outputs.cache-hit != 'true'
run: |
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest https://github.com/stan-dev/cmdstan/releases/download/v${{ env.CMDSTAN_VERSION }}/cmdstan-${{ env.CMDSTAN_VERSION }}.tar.gz -OutFile "D:/a/_temp/cmdstan.tar.gz"
New-Item -Path "$HOME" -Name ".cmdstan" -ItemType "directory"
tar -xf "D:/a/_temp/cmdstan.tar.gz" -C "$HOME/.cmdstan"

- name: "Build wheel"
run: |
cd python && python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ENVIRONMENT: >
STAN_BACKEND="${{ env.STAN_BACKEND }}"
CMDSTAN_VERSION=${{ env.CMDSTAN_VERSION }}
PIP_CACHE_DIR="${{ env.PIP_DEFAULT_CACHE }}"
CIBW_BUILD: cp36-* cp37-* cp38-*
CIBW_ARCHS: native
Expand Down Expand Up @@ -112,17 +96,16 @@ jobs:
- name: "Get OS version (Linux)"
if: startsWith(runner.os, 'Linux')
run: |
echo "OS_VERSION=`lsb_release -sr`" >> $GITHUB_ENV
echo "PIP_DEFAULT_CACHE=$HOME/.cache/pip" >> $GITHUB_ENV
echo "DEFAULT_HOME=$HOME" >> $GITHUB_ENV

- name: "Get OS version (macOS)"
if: startsWith(runner.os, 'macOS')
run: |
echo "OS_VERSION=`sw_vers -productVersion`" >> $GITHUB_ENV
echo "PIP_DEFAULT_CACHE=$HOME/Library/Caches/pip" >> $GITHUB_ENV
echo "DEFAULT_HOME=$HOME" >> $GITHUB_ENV


- name: "Checkout repo"
uses: actions/checkout@v2

Expand All @@ -146,31 +129,15 @@ jobs:
python -m pip install --upgrade pip
python -m pip install cibuildwheel build

- name: "Restore cmdstan cache"
id: cache-cmdstan
uses: actions/cache@v2
with:
path: ${{ env.DEFAULT_HOME }}/.cmdstan
key: ${{ runner.os }}-cmdstan-${{ env.CMDSTAN_VERSION }}-v1

- name: "Download cmdstan"
if: steps.cache-cmdstan.outputs.cache-hit != 'true'
run: |
wget https://github.com/stan-dev/cmdstan/releases/download/v${{ env.CMDSTAN_VERSION }}/cmdstan-${{ env.CMDSTAN_VERSION }}.tar.gz -O /tmp/cmdstan.tar.gz &> /dev/null
mkdir $HOME/.cmdstan
tar -xf /tmp/cmdstan.tar.gz -C $HOME/.cmdstan &> /dev/null

- name: "Build wheel"
run: |
cd python && python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ENVIRONMENT: >
STAN_BACKEND="${{ env.STAN_BACKEND }}"
CMDSTAN_VERSION=${{ env.CMDSTAN_VERSION }}
# Linux builds run in a Docker container, need to point the cache to the host machine.
CIBW_ENVIRONMENT_LINUX: >
STAN_BACKEND="${{ env.STAN_BACKEND }}"
CMDSTAN_VERSION=${{ env.CMDSTAN_VERSION }}
HOME="/host/${{ env.DEFAULT_HOME }}"
PIP_CACHE_DIR="/host/${{ env.PIP_DEFAULT_CACHE }}"
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
Expand Down
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,17 @@ On Windows, R requires a compiler so you'll need to [follow the instructions](ht

If you have custom Stan compiler settings, install from source rather than the CRAN binary.

## Installation in Python
## Installation in Python - PyPI release

Prophet is on PyPI, so you can use `pip` to install it. From v0.6 onwards, Python 2 is no longer supported. As of v1.0, the package name on PyPI is "prophet"; prior to v1.0 it was "fbprophet".

```bash
# Install pystan with pip before using pip to install prophet
# pystan>=3.0 is currently not supported
pip install pystan==2.19.1.1

pip install prophet
```

The default dependency that Prophet has is `pystan`. PyStan has its own [installation instructions](http://pystan.readthedocs.io/en/latest/installation_beginner.html). Install pystan with pip before using pip to install prophet.

#### Experimental backend - cmdstanpy

You can also choose a (more experimental) alternative stan backend called `cmdstanpy`. It requires the [CmdStan](https://mc-stan.org/users/interfaces/cmdstan) command line interface and you will have to specify the environment variable `STAN_BACKEND` pointing to it, for example:
Expand All @@ -90,20 +87,41 @@ $ CMDSTAN=/tmp/cmdstan-2.22.1 STAN_BACKEND=PYSTAN,CMDSTANPY pip install prophet

After installation, you can [get started!](https://facebook.github.io/prophet/docs/quick_start.html#python-api)

If you upgrade the version of PyStan installed on your system, you may need to reinstall prophet ([see here](https://github.com/facebook/prophet/issues/324)).
If you upgraded the version of PyStan installed on your system, you may need to reinstall prophet ([see here](https://github.com/facebook/prophet/issues/324)).

### Anaconda

Use `conda install gcc` to set up gcc. The easiest way to install Prophet is through conda-forge: `conda install -c conda-forge prophet`.
The easiest way to install Prophet is through conda-forge: `conda install -c conda-forge prophet`.

### Windows

On Windows, PyStan requires a compiler so you'll need to [follow the instructions](https://pystan2.readthedocs.io/en/latest/windows.html). The easiest way to install Prophet in Windows is in Anaconda.
The easiest way to install Prophet in Windows is in Anaconda.

### Linux

Make sure compilers (gcc, g++, build-essential) and Python development tools (python-dev, python3-dev) are installed. In Red Hat systems, install the packages gcc64 and gcc64-c++. If you are using a VM, be aware that you will need at least 4GB of memory to install prophet, and at least 2GB of memory to use prophet.

## Installation in Python - Development version

Since Pystan2 is no longer being maintained, the python package will move to depend solely on `cmdstanpy` (benefits described [here](https://github.com/facebook/prophet/issues/2041)). This has been updated in the development version of the package (1.1), but this version hasn't yet been released to PyPI. If you would like to use `cmdstanpy` only for your workflow, you can clone this repo and build from source manually:

```bash
git clone https://github.com/facebook/prophet.git
cd prophet/python
python -m install -r requirements.txt
python setup.py develop
```

By default, Prophet will use a fixed version of `cmdstan` (downloading and installing it if necessary) to compile the model executables. If this is undesired and you would like to use your own existing `cmdstan` installation, you can set the environment variable `PROPHET_REPACKAGE_CMDSTAN` to `False`:

```bash
export PROPHET_REPACKAGE_CMDSTAN=False; python setup.py develop
```

### Windows

Using `cmdstanpy` with Windows requires a Unix-compatible C compiler such as mingw-gcc. If cmdstanpy is installed first, one can be installed via the `cmdstanpy.install_cxx_toolchain` command.

## Changelog

### Version 1.0 (2021.03.28)
Expand Down
3 changes: 1 addition & 2 deletions python/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
include stan/unix/*.stan
include stan/win/*.stan
include stan/*.stan
include LICENSE
include requirements.txt

Expand Down
19 changes: 9 additions & 10 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ Full documentation and examples available at the homepage: https://facebook.gith
- Rob Hyndman's [forecast package](http://robjhyndman.com/software/forecast/)
- [Statsmodels](http://statsmodels.sourceforge.net/)

## Installation
## Installation - PyPI release

```shell
pip install prophet
```
Note: Installation requires PyStan, which has its [own installation instructions](http://pystan.readthedocs.io/en/latest/installation_beginner.html).
On Windows, PyStan requires a compiler so you'll need to [follow the instructions](http://pystan.readthedocs.io/en/latest/windows.html).
The key step is installing a recent [C++ compiler](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
See [Installation in Python - PyPI release](https://github.com/facebook/prophet#installation-in-python---pypi-release)

## Installation - Development version

## Installation using Docker and docker-compose (via Makefile)
See [Installation in Python - Development version](https://github.com/facebook/prophet#installation-in-python---development-version)

Simply type `make build` and if everything is fine you should be able to `make shell` or alternative jump directly to `make py-shell`.
### Installation using Docker and docker-compose (via Makefile)

Simply type `make build` and if everything is fine you should be able to `make shell` or alternative jump directly to `make py-shell`.

To run the tests, inside the container `cd python/prophet` and then `python -m unittest`

Expand All @@ -41,4 +40,4 @@ To run the tests, inside the container `cd python/prophet` and then `python -m u
>>> m.fit(df) # df is a pandas.DataFrame with 'y' and 'ds' columns
>>> future = m.make_future_dataframe(periods=365)
>>> m.predict(future)
```
```
23 changes: 8 additions & 15 deletions python/prophet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from __future__ import absolute_import, division, print_function
from abc import abstractmethod, ABC
from tempfile import mkdtemp
from typing import Tuple
from collections import OrderedDict
from enum import Enum
Expand Down Expand Up @@ -61,30 +62,21 @@ def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict:
class CmdStanPyBackend(IStanBackend):
CMDSTAN_VERSION = "2.26.1"
def __init__(self):
super().__init__()
import cmdstanpy
cmdstanpy.set_cmdstan_path(
pkg_resources.resource_filename("prophet", f"stan_model/cmdstan-{self.CMDSTAN_VERSION}")
# this must be set before super.__init__() for load_model to work on Windows
local_cmdstan = pkg_resources.resource_filename(
"prophet", f"stan_model/cmdstan-{self.CMDSTAN_VERSION}"
)
if Path(local_cmdstan).exists():
cmdstanpy.set_cmdstan_path(local_cmdstan)
super().__init__()

@staticmethod
def get_type():
return StanBackendEnum.CMDSTANPY.name

def _add_tbb_to_path(self):
"""Add the TBB library to $PATH on Windows only. Required for loading model binaries."""
if PLATFORM == "win":
tbb_path = pkg_resources.resource_filename(
"prophet",
f"stan_model/cmdstan-{self.CMDSTAN_VERSION}/stan/lib/stan_math/lib/tbb"
)
os.environ["PATH"] = ";".join(
list(OrderedDict.fromkeys([tbb_path] + os.environ.get("PATH", "").split(";")))
)

def load_model(self):
import cmdstanpy
self._add_tbb_to_path()
model_file = pkg_resources.resource_filename(
'prophet',
'stan_model/prophet_model.bin',
Expand All @@ -102,6 +94,7 @@ def fit(self, stan_init, stan_data, **kwargs):
inits=stan_init,
algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS',
iter=int(1e4),
output_dir = mkdtemp(),
)
args.update(kwargs)

Expand Down
2 changes: 1 addition & 1 deletion python/prophet/tests/test_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def test_cross_validation_custom_cutoffs(self):
period='10 days',
cutoffs=[pd.Timestamp('2012-07-31'), pd.Timestamp('2012-08-31')])
self.assertEqual(len(df_cv1['cutoff'].unique()), 2)

def test_cross_validation_uncertainty_disabled(self):
df = self.__df.copy()
for uncertainty in [0, False]:
Expand Down
3 changes: 1 addition & 2 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
requires = [
"setuptools>=42",
"wheel",
"pystan~=2.19.1.1",
"cmdstanpy==0.9.77",
"cmdstanpy>=1.0.0",
]
build-backend = "setuptools.build_meta"
2 changes: 1 addition & 1 deletion python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Cython>=0.22
cmdstanpy==0.9.77
cmdstanpy>=1.0.0
pystan~=2.19.1.1
numpy>=1.15.4
pandas>=1.0.4
Expand Down
Loading