mirror of
https://github.com/saymrwulf/prophet.git
synced 2026-07-22 19:23:36 +00:00
Remove pystan, leave backend abstraction for now (#2148)
This commit is contained in:
parent
9968f8be41
commit
df411c9192
8 changed files with 15 additions and 114 deletions
4
.github/workflows/wheel.yml
vendored
4
.github/workflows/wheel.yml
vendored
|
|
@ -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}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)).
|
||||
|
|
|
|||
|
|
@ -73,12 +73,8 @@ prophet_plot_components(m, forecast)
|
|||
# Python
|
||||
fig = m.plot_components(forecast)
|
||||
```
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
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)`.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -227,70 +227,9 @@ class CmdStanPyBackend(IStanBackend):
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue