reconnect moved files to git repo
This commit is contained in:
@ -0,0 +1,13 @@
|
||||
"""
|
||||
The variables defined in compat are designed to provide compatibility.
|
||||
Each sub-module is specifically designed not to make calls out
|
||||
to other portions of pmdarima and to remove circular dependencies.
|
||||
"""
|
||||
|
||||
from .matplotlib import *
|
||||
from .pandas import *
|
||||
from .numpy import *
|
||||
from .sklearn import *
|
||||
from .statsmodels import *
|
||||
|
||||
__all__ = [s for s in dir() if not s.startswith('_')]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Author: Taylor G Smith <taylor.smith@alkaline-ml.com>
|
||||
#
|
||||
# Patch backend for MPL
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
__all__ = [
|
||||
'get_compatible_pyplot',
|
||||
'mpl_hist_arg'
|
||||
]
|
||||
|
||||
|
||||
def get_compatible_pyplot(backend=None, debug=True):
|
||||
"""Make the backend of MPL compatible.
|
||||
|
||||
In Travis Mac distributions, python is not installed as a framework. This
|
||||
means that using the TkAgg backend is the best solution (so it doesn't
|
||||
try to use the mac OS backend by default).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
backend : str, optional (default="TkAgg")
|
||||
The backend to default to.
|
||||
|
||||
debug : bool, optional (default=True)
|
||||
Whether to log the existing backend to stderr.
|
||||
"""
|
||||
import matplotlib
|
||||
|
||||
# If the backend provided is None, just default to
|
||||
# what's already being used.
|
||||
existing_backend = matplotlib.get_backend()
|
||||
if backend is not None:
|
||||
# Can this raise?...
|
||||
matplotlib.use(backend)
|
||||
|
||||
# Print out the new backend
|
||||
if debug:
|
||||
sys.stderr.write("Currently using '%s' MPL backend, "
|
||||
"switching to '%s' backend%s"
|
||||
% (existing_backend, backend, os.linesep))
|
||||
|
||||
# If backend is not set via env variable, but debug is
|
||||
elif debug:
|
||||
sys.stderr.write("Using '%s' MPL backend%s"
|
||||
% (existing_backend, os.linesep))
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
return plt
|
||||
|
||||
|
||||
def mpl_hist_arg(value=True):
|
||||
"""Find the appropriate `density` kwarg for our given matplotlib version.
|
||||
|
||||
This will determine if we should use `normed` or `density`. Additionally,
|
||||
since this is a kwarg, the user can supply a value (True or False) that
|
||||
they would like in the output dictionary.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
value : bool, optional (default=True)
|
||||
The boolean value of density/normed
|
||||
|
||||
Returns
|
||||
-------
|
||||
density_kwarg : dict
|
||||
A dictionary containing the appropriate density kwarg for the
|
||||
installed matplotlib version, mapped to the provided or default
|
||||
value
|
||||
"""
|
||||
import matplotlib
|
||||
|
||||
density_kwarg = 'density' if matplotlib.__version__ >= '2.1.0'\
|
||||
else 'normed'
|
||||
return {density_kwarg: value}
|
||||
17
venv/lib/python3.11/site-packages/pmdarima/compat/numpy.py
Normal file
17
venv/lib/python3.11/site-packages/pmdarima/compat/numpy.py
Normal file
@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Author: Taylor Smith <taylor.smith@alkaline-ml.com>
|
||||
#
|
||||
# Provide numpy compatibility and common variables. Since this
|
||||
# is a relatively sparse script, I feel I must defend this design
|
||||
# choice. See the docstring in the __init__: "Each sub-module is specifically
|
||||
# designed not to make calls out to other portions of pmdarima and to
|
||||
# remove circular dependencies."
|
||||
#
|
||||
# Since DTYPE is used commonly, this removes circular dependencies or
|
||||
# hard-coding.
|
||||
|
||||
import numpy as np
|
||||
|
||||
# this is going to be the data-type used across pmdarima
|
||||
DTYPE = np.float64
|
||||
@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Importing visualization modules changes in version 0.19
|
||||
try: # <= v0.19
|
||||
from pandas.tools import plotting
|
||||
except ImportError: # 0.20+
|
||||
from pandas import plotting
|
||||
28
venv/lib/python3.11/site-packages/pmdarima/compat/pytest.py
Normal file
28
venv/lib/python3.11/site-packages/pmdarima/compat/pytest.py
Normal file
@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import contextlib
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_error_str(error):
|
||||
"""Different for different versions of Pytest"""
|
||||
try:
|
||||
return str(error.value)
|
||||
except AttributeError:
|
||||
return str(error)
|
||||
|
||||
|
||||
def pytest_warning_messages(warnings):
|
||||
"""Get the warning messages for captured warnings"""
|
||||
return [str(w.message) for w in warnings.list]
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def raises(exception):
|
||||
"""Allows context managers for catching NO errors"""
|
||||
if exception is None:
|
||||
yield None
|
||||
|
||||
else:
|
||||
with pytest.raises(exception) as e:
|
||||
yield e
|
||||
98
venv/lib/python3.11/site-packages/pmdarima/compat/sklearn.py
Normal file
98
venv/lib/python3.11/site-packages/pmdarima/compat/sklearn.py
Normal file
@ -0,0 +1,98 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Author: Charles Drotar <drotarcharles@gmail.com>
|
||||
#
|
||||
# Patch backend for sklearn
|
||||
from packaging.version import Version
|
||||
|
||||
import sklearn
|
||||
from sklearn.exceptions import NotFittedError
|
||||
|
||||
__all__ = [
|
||||
'check_is_fitted',
|
||||
'if_delegate_has_method',
|
||||
'safe_indexing',
|
||||
]
|
||||
|
||||
|
||||
def check_is_fitted(estimator, attributes):
|
||||
"""Ensure the model has been fitted
|
||||
|
||||
Typically called at the beginning of an operation on a model that requires
|
||||
having been fit. Raises a ``NotFittedError`` if the model has not been
|
||||
fit.
|
||||
|
||||
This is an adaptation of scikit-learn's ``check_is_fitted``, which has been
|
||||
changed recently in a way that is no longer compatible with our package.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
estimator : estimator instance,
|
||||
The estimator that will be checked to see if it is fitted.
|
||||
|
||||
attributes : str or iterable
|
||||
The attributes to check for
|
||||
"""
|
||||
if isinstance(attributes, str):
|
||||
attributes = [attributes]
|
||||
if not hasattr(attributes, "__iter__"):
|
||||
raise TypeError("attributes must be a string or iterable")
|
||||
for attr in attributes:
|
||||
if hasattr(estimator, attr):
|
||||
return
|
||||
raise NotFittedError("Model has not been fit!")
|
||||
|
||||
|
||||
def safe_indexing(X, indices):
|
||||
"""Slice an array or dataframe. This is deprecated in sklearn"""
|
||||
if hasattr(X, 'iloc'):
|
||||
return X.iloc[indices]
|
||||
# numpy:
|
||||
# TODO: this does not currently support axis 1
|
||||
if hasattr(X, 'ndim') and X.ndim == 2:
|
||||
return X[indices, :]
|
||||
# list or 1d array
|
||||
return X[indices]
|
||||
|
||||
|
||||
def _estimator_has(attr):
|
||||
"""Checks if the model has a given attribute.
|
||||
|
||||
Meant to be used along with `sklearn.utils.metaestimators.available_if`
|
||||
|
||||
Parameters
|
||||
----------
|
||||
attr : str
|
||||
The attribute to check the calling object for
|
||||
|
||||
Returns
|
||||
-------
|
||||
fn : callable
|
||||
A function that will either raise an `AttributeError` if the attribute
|
||||
does not exist, or True if it does.
|
||||
"""
|
||||
def check(self):
|
||||
# raise original `AttributeError` if `attr` does not exist
|
||||
getattr(self, attr)
|
||||
return True
|
||||
|
||||
return check
|
||||
|
||||
|
||||
def if_delegate_has_method(attr):
|
||||
"""Compat method to replace `sklearn.utils.metaestimators.if_delegate_has`
|
||||
|
||||
Older versions (< 1.0.0) of sklearn support it, but newer versions use
|
||||
`available_if` instead.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://git.io/JzKiv
|
||||
.. [2] https://git.io/JzKiJ
|
||||
"""
|
||||
if Version(sklearn.__version__) < Version("1.0.0"):
|
||||
from sklearn.utils.metaestimators import if_delegate_has_method
|
||||
return if_delegate_has_method(attr)
|
||||
else:
|
||||
from sklearn.utils.metaestimators import available_if
|
||||
return available_if(_estimator_has(attr))
|
||||
@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Handle inconsistencies in the statsmodels API versions
|
||||
|
||||
from collections.abc import Iterable
|
||||
from packaging.version import Version
|
||||
import statsmodels as sm
|
||||
|
||||
__all__ = [
|
||||
'bind_df_model'
|
||||
]
|
||||
|
||||
_sm_version = sm.__version__
|
||||
|
||||
|
||||
def bind_df_model(model_fit, arima_results):
|
||||
"""Set model degrees of freedom.
|
||||
|
||||
Older versions of statsmodels don't handle this issue. Sets the
|
||||
model degrees of freedom in place if not already present.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
model_fit : ARMA, ARIMA or SARIMAX
|
||||
The fitted model.
|
||||
|
||||
arima_results : ModelResultsWrapper
|
||||
The results wrapper.
|
||||
"""
|
||||
if not hasattr(arima_results, 'df_model'):
|
||||
df_model = model_fit.k_exog + model_fit.k_trend + \
|
||||
model_fit.k_ar + model_fit.k_ma + \
|
||||
model_fit.k_seasonal_ar + model_fit.k_seasonal_ma
|
||||
setattr(arima_results, 'df_model', df_model)
|
||||
|
||||
|
||||
def check_seasonal_order(order):
|
||||
"""Check the seasonal order
|
||||
|
||||
Statsmodels 0.11.0 introduced a check for seasonal order == 1 that can
|
||||
raise a ValueError, but some of our old defaults allow for m == 1 in an
|
||||
otherwise null seasonal order.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
order : tuple
|
||||
The existing seasonal order
|
||||
"""
|
||||
|
||||
# If order[0] is an iterable, but not a string then we don't perform check.
|
||||
# Otherwise we perform the check and override order if it satisfies check.
|
||||
# See issue#370: https://github.com/alkaline-ml/pmdarima/issues/370
|
||||
if isinstance(order[0], Iterable) and not isinstance(order[0], str):
|
||||
return order
|
||||
else:
|
||||
if sum(order[:3]) == 0 and order[-1] == 1:
|
||||
order = (0, 0, 0, 0)
|
||||
|
||||
# user's order may be invalid, but we'll let statsmodels' validation
|
||||
# handle that.
|
||||
return order
|
||||
|
||||
|
||||
def _use_sm13():
|
||||
return Version(sm.__version__) >= Version("0.13.0")
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pmdarima.arima import ARIMA
|
||||
from pmdarima.compat.pytest import pytest_error_str
|
||||
from pmdarima.compat import sklearn as sk
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from numpy.testing import assert_array_equal
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'x,i,exp', [
|
||||
pytest.param(np.array([1, 2, 3, 4, 5]), [0, 1], np.array([1, 2])),
|
||||
pytest.param(pd.Series([1, 2, 3, 4, 5]), [0, 1], np.array([1, 2])),
|
||||
pytest.param(np.array([[1, 2], [3, 4]]), [0], np.array([[1, 2]])),
|
||||
]
|
||||
)
|
||||
def test_safe_indexing(x, i, exp):
|
||||
res = sk.safe_indexing(x, i)
|
||||
if hasattr(res, "values"): # pd.Series
|
||||
res = res.values
|
||||
assert_array_equal(exp, res)
|
||||
|
||||
|
||||
def test_check_is_fitted_error():
|
||||
with pytest.raises(TypeError) as te:
|
||||
sk.check_is_fitted(None, None)
|
||||
assert "attributes must be a string or iterable" in pytest_error_str(te)
|
||||
|
||||
|
||||
def test_not_fitted_error():
|
||||
with pytest.raises(sk.NotFittedError) as nfe:
|
||||
mod = ARIMA((0, 1, 0))
|
||||
sk.check_is_fitted(mod, "arima_res_")
|
||||
assert "Model has not been fit!" in pytest_error_str(nfe)
|
||||
@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pmdarima.compat.statsmodels import bind_df_model, check_seasonal_order
|
||||
|
||||
|
||||
# Test binding the degrees of freedom to a class in place. It's hard to test
|
||||
# on a potentially non-existent version of statsmodels, so we have to mock the
|
||||
# class
|
||||
def test_bind_df_model():
|
||||
class ModelFit(object):
|
||||
k_exog = 2
|
||||
k_trend = 1
|
||||
k_ar = 3
|
||||
k_ma = 2
|
||||
k_seasonal_ar = 1
|
||||
k_seasonal_ma = 2
|
||||
|
||||
class ARIMAResults(object):
|
||||
pass
|
||||
|
||||
fit = ModelFit()
|
||||
res = ARIMAResults()
|
||||
|
||||
# First, there is no 'df_model' in arima res
|
||||
assert not hasattr(res, 'df_model')
|
||||
bind_df_model(fit, res)
|
||||
|
||||
# Now it should
|
||||
assert hasattr(res, 'df_model')
|
||||
assert res.df_model == 11, res.df_model
|
||||
|
||||
|
||||
def test_check_seasonal_order():
|
||||
# issue370, using an iterable at position 0 returns
|
||||
order = ([1, 2, 3, 52], 0, 1, 7)
|
||||
checked_order = check_seasonal_order(order)
|
||||
assert order == checked_order
|
||||
|
||||
# Special case where we override the seasonal order that is passed in.
|
||||
order = (0, 0, 0, 1)
|
||||
checked_order = check_seasonal_order(order)
|
||||
assert checked_order == (0, 0, 0, 0)
|
||||
Reference in New Issue
Block a user