unit8co / darts

A python library for user-friendly forecasting and anomaly detection on time series.
https://unit8co.github.io/darts/
Apache License 2.0
7.92k stars 859 forks source link

[BUG] Strange import behaviour? #2273

Open elbal opened 6 months ago

elbal commented 6 months ago

Describe the bug There is a (possibly) strange behaviour when importing darts. If I import darts as-is the only visible class is TimeSeries and I cannot use any submodule (darts.models, darts.utils, tec.) If, instead, I import darts.modules I can suddently use not only darts.modules but also darts.utils directly.

Also some classes seems to be imported at different levels in the library. Importing darts.models I can either use: darts.models.NaiveMean(ts) or: darts.models.forecasting.baselines.NaiveMean(ts) While in the API reference NaiveMean is only listed within darts.models.forecasting.baselines

To Reproduce

#### This import works even if it should not
import pandas as pd
import darts.models
import matplotlib.pyplot as plt

df = pd.DataFrame({"demand": [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    ]})
ts = darts.TimeSeries.from_dataframe(df)

darts.models.NaiveMean(ts)
darts.utils.statistics.plot_acf(ts)

plt.show()

#### This import does not work even if it should
import pandas as pd
import darts
import matplotlib.pyplot as plt

df = pd.DataFrame({"demand": [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    ]})
ts = darts.TimeSeries.from_dataframe(df)

darts.models.NaiveMean(ts)
darts.utils.statistics.plot_acf(ts)

plt.show()

Expected behavior The first import should not work while the second one should work.

Maybe both scripts should fail at: darts.models.NaiveMean(ts) Since, instead, the class should be called only as: darts.models.forecasting.baselines.NaiveMean(ts)

This last verison works as well and may be the correct one from the API description: https://unit8co.github.io/darts/generated_api/darts.models.forecasting.baselines.html#darts.models.forecasting.baselines.NaiveMean

System (please complete the following information):

Additional context None.

madtoinou commented 6 months ago

Hi @elbal,

Thank you for reporting this. I think that the modules need to be linked to the top __init__.py in order to get the expected behavior when using import darts. Just need to make sure that it does not cause other issues.

However, it is expected to be able to import the models from different levels of the library: darts.models for the sake of simplicity (thanks to the logic in the corresponding __init__.py) as visible in the documentation code example but also their "original" file, for example; darts/models/forecasting/baselines.py for NaiveMean (as displayed in the name of the class in the documentation). Not sure to understand why this could be a problem.

elbal commented 6 months ago

@madtoinou Thank you for your reply. I missed the example in the documentation as I went straight for the API. I think it would make sense just to link the main modules in the main __init__.py.

A slightly different issue (?) arises for the submodules. For example:

import pandas as pd
import darts.models
import matplotlib.pyplot as plt

df = pd.DataFrame({"demand": [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    ]})
ts = darts.TimeSeries.from_dataframe(df)

darts.models.forecasting.baselines.NaiveMean(ts)
darts.utils.statistics.plot_acf(ts)

plt.show()

Works, but Pycharm does not recognize the reference baselines and throws a waring. The reference forecasting, instead, is recognized even if it is not direcly linked in the darts.models __init__.py: https://github.com/unit8co/darts/blob/master/darts/models/__init__.py

I suspect the reason is that in the darts.models __init__.py there are references like darts.models.forecasting.exponential_smoothing that imply darts.models.forecasting but not darts.models.forecasting.baselines.

Is it something that should be fixed or the user is suppoosed to call the classes directly form darts.models?