I would like to be able to suppress some output coming from fbprophet while fitting a forecasting model. This output ("Initial log joint probability...", "Optimization terminated normally:", "Convergence detected:...", etc.) is apparently coming from Stan's cpp code and I cannot find any obvious way to control it [I am using python interface]. Digging a little bit into the code discovers verbose=False as default in high level stan() routines (in pystan/api.py), but apparently this parameter does not suppress this printout. Is it feasible without code modifications?
Asked
Active
Viewed 8,236 times
1 Answers
8
Unfortunately, it's more complex than it should be. I think some of the output is coming from C or Fortran compiled code or something. Here is how you can do it (found here):
import os
import sys
import pandas as pd
from fbprophet import Prophet
# from https://stackoverflow.com/questions/11130156/suppress-stdout-stderr-print-from-python-functions
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = (os.dup(1), os.dup(2))
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0], 1)
os.dup2(self.null_fds[1], 2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0], 1)
os.dup2(self.save_fds[1], 2)
# Close the null files
os.close(self.null_fds[0])
os.close(self.null_fds[1])
m = Prophet()
df = pd.read_csv('somefile.csv')
with suppress_stdout_stderr():
m.fit(minimal_df)
The 'simpler' way (if it would've worked, which it doesn't) would've been something like:
import os
import sys
import pandas as pd
from fbprophet import Prophet
m = Prophet()
df = pd.read_csv('somefile.csv')
orig_out = sys.stdout
sys.stdout = open(os.devnull, 'w')
m.fit(df)
sys.stdout = orig_out
wordsforthewise
- 11,271
- 5
- 74
- 108
-
Is the simpler way outdated? Because it doesn't seem to work for me inside a flask app. – Sayan Sil Aug 21 '19 at 20:30
-
1I'm not sure the simpler way worked; don't remember at this point if I had tested it or not. I seem to remember it not working though. I think it was a sort of suggestion of how it could be done usually, but not in the case of prophet. – wordsforthewise Aug 22 '19 at 04:31