reconnect moved files to git repo

This commit is contained in:
root
2025-08-01 04:33:03 -04:00
commit 5d3c35492d
23190 changed files with 4750716 additions and 0 deletions

View File

@ -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('_')]

View File

@ -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}

View 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

View File

@ -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

View 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

View 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))

View File

@ -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")

View File

@ -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)

View File

@ -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)