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
4 changes: 2 additions & 2 deletions .github/workflows/wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
CIBW_ENVIRONMENT: >
STAN_BACKEND="${{ env.STAN_BACKEND }}"
PIP_CACHE_DIR="${{ env.PIP_DEFAULT_CACHE }}"
CIBW_BUILD: cp36-* cp37-* cp38-*
CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-*
CIBW_ARCHS: native
CIBW_BUILD_FRONTEND: build
# CIBW_REPAIR_WHEEL_COMMAND: delvewheel repair -w {dest_dir} {wheel}
Expand Down Expand Up @@ -142,7 +142,7 @@ jobs:
PIP_CACHE_DIR="/host/${{ env.PIP_DEFAULT_CACHE }}"
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_BEFORE_ALL_LINUX: chmod -R a+rwx /host/${{ env.PIP_DEFAULT_CACHE }}
CIBW_BUILD: cp36-* cp37-* cp38-*
CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-*
CIBW_SKIP: "*musllinux*"
CIBW_ARCHS: native
CIBW_BUILD_FRONTEND: build
Expand Down
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ $ CMDSTAN=/tmp/cmdstan-2.22.1 STAN_BACKEND=CMDSTANPY pip install prophet

Note that the `CMDSTAN` variable is directly related to `cmdstanpy` module and can be omitted if your CmdStan binaries are in your `$PATH`.

It is also possible to install Prophet with two backends:

```bash
# bash
$ 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 upgraded the version of PyStan installed on your system, you may need to reinstall prophet ([see here](https://github.com/facebook/prophet/issues/324)).
Expand Down
8 changes: 2 additions & 6 deletions docs/_docs/uncertainty_intervals.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,8 @@ prophet_plot_components(m, forecast)
# Python
fig = m.plot_components(forecast)
```

![png](/prophet/static/uncertainty_intervals_files/uncertainty_intervals_11_0.png)


You can access the raw posterior predictive samples in Python using the method `m.predictive_samples(future)`, or in R using the function `predictive_samples(m, future)`.
![png](/prophet/static/uncertainty_intervals_files/uncertainty_intervals_11_0.png)


There are upstream issues in PyStan for Windows which make MCMC sampling extremely slow. The best choice for MCMC sampling in Windows is to use R, or Python in a Linux VM.

You can access the raw posterior predictive samples in Python using the method `m.predictive_samples(future)`, or in R using the function `predictive_samples(m, future)`.
10 changes: 4 additions & 6 deletions notebooks/diagnostics.ipynb

Large diffs are not rendered by default.

11 changes: 2 additions & 9 deletions notebooks/uncertainty_intervals.ipynb

Large diffs are not rendered by default.

61 changes: 0 additions & 61 deletions python/prophet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,70 +227,9 @@ def stan_to_dict_numpy(column_names: Tuple[str, ...], data: 'np.array'):
return output


class PyStanBackend(IStanBackend):

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

def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict:

args = dict(
data=stan_data,
init=lambda: stan_init,
iter=samples,
)
args.update(kwargs)
self.stan_fit = self.model.sampling(**args)
out = {}
for par in self.stan_fit.model_pars:
out[par] = self.stan_fit[par]
# Shape vector parameters
if par in ['delta', 'beta'] and len(out[par].shape) < 2:
out[par] = out[par].reshape((-1, 1))
return out

def fit(self, stan_init, stan_data, **kwargs) -> dict:

args = dict(
data=stan_data,
init=lambda: stan_init,
algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS',
iter=1e4,
)
args.update(kwargs)
try:
self.stan_fit = self.model.optimizing(**args)
except RuntimeError as e:
# Fall back on Newton
if self.newton_fallback and args['algorithm'] != 'Newton':
logger.warning(
'Optimization terminated abnormally. Falling back to Newton.'
)
args['algorithm'] = 'Newton'
self.stan_fit = self.model.optimizing(**args)
else:
raise e

params = {}

for par in self.stan_fit.keys():
params[par] = self.stan_fit[par].reshape((1, -1))

return params

def load_model(self):
"""Load compiled Stan model"""
model_file = pkg_resources.resource_filename(
'prophet',
'stan_model/prophet_model.pkl',
)
with Path(model_file).open('rb') as f:
return pickle.load(f)


class StanBackendEnum(Enum):
PYSTAN = PyStanBackend
CMDSTANPY = CmdStanPyBackend

@staticmethod
Expand Down
3 changes: 1 addition & 2 deletions python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Cython>=0.22
cmdstanpy>=1.0.0
pystan~=2.19.1.1
cmdstanpy>=1.0.1
numpy>=1.15.4
pandas>=1.0.4
matplotlib>=2.0.0
Expand Down
25 changes: 4 additions & 21 deletions python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,34 +118,17 @@ def build_cmdstan_model(target_dir):
prune_cmdstan(cmdstan_dir)


def build_pystan_model(target_dir):
"""
Compile the stan model using pystan and pickle it. The pickle is copied to {target_dir}/prophet_model.pkl.
"""
import pystan
import pickle

model_name = "prophet.stan"
target_name = "prophet_model.pkl"
with open(os.path.join(MODEL_DIR, model_name)) as f:
model_code = f.read()
sm = pystan.StanModel(model_code=model_code)
with open(os.path.join(target_dir, target_name), "wb") as f:
pickle.dump(sm, f, protocol=pickle.HIGHEST_PROTOCOL)


def get_backends_from_env() -> List[str]:
return os.environ.get("STAN_BACKEND", "CMDSTANPY").split(",")


def build_models(target_dir):
for backend in get_backends_from_env():
print(f"Compiling {backend} model")
if backend == "CMDSTANPY":
build_cmdstan_model(target_dir)
elif backend == "PYSTAN" and PLATFORM != "win":
build_pystan_model(target_dir)
print(f"Compiling cmdstanpy model")
build_cmdstan_model(target_dir)

if 'PYSTAN' in get_backends_from_env():
raise ValueError("PyStan backend is not supported for Prophet >= 1.1")

class BuildPyCommand(build_py):
"""Custom build command to pre-compile Stan models."""
Expand Down