diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index eecb60a..c7b9e16 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -4,7 +4,7 @@ title: "[Bug]: " labels: ["bug"] assignees: - octocat -body: +body: - type: input id: contact attributes: @@ -13,7 +13,7 @@ body: placeholder: ex. email@example.com validations: required: false - + - type: textarea id: bug-description attributes: @@ -21,7 +21,7 @@ body: placeholder: A clear and concise description of what the bug is. validations: required: true - + - type: textarea id: bug-reproduce attributes: @@ -34,7 +34,7 @@ body: 4. See error validations: required: true - + - type: textarea id: expected attributes: @@ -42,14 +42,14 @@ body: placeholder: A clear and concise description of what you expected to happen. validations: required: true - + - type: dropdown id: version attributes: label: Version description: What version of our product are you running? options: - - v0.1.0 (Default) + - v0.4.0 (Default) validations: required: true @@ -59,11 +59,11 @@ body: label: Relevant log output/screenshots description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. render: shell - + - type: textarea id: add-context attributes: label: Additional context placeholder: Add any other context about the bug report here. validations: - required: false + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index c688daf..9a5f0ec 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -12,7 +12,7 @@ body: placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: true - + - type: textarea id: solution attributes: @@ -20,7 +20,7 @@ body: placeholder: A clear and concise description of what you want to happen. validations: required: true - + - type: textarea id: input attributes: @@ -31,7 +31,7 @@ body: render: python validations: required: true - + - type: textarea id: output attributes: @@ -42,26 +42,26 @@ body: render: python validations: required: true - + - type: textarea id: add-context attributes: label: Additional context placeholder: Add any other context or screenshots about the feature request here. validations: - required: false - + required: false + - type: textarea id: accept attributes: label: Acceptance criteria placeholder: | NOTE: Acceptance criteria should be measurable and should be based on maximum possible limit. - + Example: If the acceptance criteria for an application is based on response time, specify the response time such that post which the application will not be adopted/used at all i.e. a deal breaker. Meaning if the acceptance criteria for response time is 1 minute, the end user will NOT use the application at all if the response time is more than 1 minute. validations: - required: true - + required: true + - type: dropdown id: version attributes: @@ -71,4 +71,3 @@ body: - v0.4.0 (Default) validations: required: true - diff --git a/.github/ISSUE_TEMPLATE/maintenance_request.yaml b/.github/ISSUE_TEMPLATE/maintenance_request.yaml index 1ede47b..b64324f 100644 --- a/.github/ISSUE_TEMPLATE/maintenance_request.yaml +++ b/.github/ISSUE_TEMPLATE/maintenance_request.yaml @@ -27,7 +27,7 @@ body: label: Version description: What version of our product are you running? options: - - v0.1.0 (Default) + - v0.4.0 (Default) validations: required: true @@ -37,5 +37,4 @@ body: label: Additional context placeholder: Add any other context or screenshots about the maintenance request here. validations: - required: false - + required: false diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 85e756a..6eaaf32 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -21,6 +21,7 @@ on: branches: - 'stable' - 'testing' + - 'feature*' pull_request: branches: - 'stable' @@ -51,7 +52,7 @@ jobs: - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names - flake8 . --count --extend-ignore=E402 --show-source --statistics + flake8 . --count --extend-ignore=E402,W0511 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest diff --git a/bin/metrics/build/lib.linux-x86_64-3.7/metrics.cpython-37m-x86_64-linux-gnu.so b/bin/metrics/build/lib.linux-x86_64-3.7/metrics.cpython-37m-x86_64-linux-gnu.so index c972ad9..da0163e 100644 Binary files a/bin/metrics/build/lib.linux-x86_64-3.7/metrics.cpython-37m-x86_64-linux-gnu.so and b/bin/metrics/build/lib.linux-x86_64-3.7/metrics.cpython-37m-x86_64-linux-gnu.so differ diff --git a/bin/metrics/build/temp.linux-x86_64-3.7/metrics.o b/bin/metrics/build/temp.linux-x86_64-3.7/metrics.o index f0c644c..c7cdbc4 100644 Binary files a/bin/metrics/build/temp.linux-x86_64-3.7/metrics.o and b/bin/metrics/build/temp.linux-x86_64-3.7/metrics.o differ diff --git a/bin/metrics/metrics.c b/bin/metrics/metrics.c index ea9ce05..4f93738 100644 --- a/bin/metrics/metrics.c +++ b/bin/metrics/metrics.c @@ -3,6 +3,7 @@ /* BEGIN: Cython Metadata { "distutils": { + "depends": [], "name": "metrics", "sources": [ "metrics.pyx" @@ -605,6 +606,7 @@ static CYTHON_INLINE float __PYX_NAN() { #define __PYX_HAVE__metrics #define __PYX_HAVE_API__metrics /* Early includes */ +#include #ifdef _OPENMP #include #endif /* _OPENMP */ @@ -817,6 +819,19 @@ static const char *__pyx_f[] = { }; /*--- Type declarations ---*/ +struct __pyx_opt_args_7metrics_aic; + +/* "metrics.pyx":190 + * + * + * cpdef double aic(list y, list y_hat, int k, str method="linear"): # <<<<<<<<<<<<<< + * """ + * Compute `Akaike information criterion + */ +struct __pyx_opt_args_7metrics_aic { + int __pyx_n; + PyObject *method; +}; /* --- Runtime support code (head) --- */ /* Refnanny.proto */ @@ -1016,8 +1031,21 @@ static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ __Pyx__ArgTypeTest(obj, type, name, exact)) static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* StrEquals.proto */ +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals +#else +#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals +#endif /* PyThreadStateGet.proto */ #if CYTHON_FAST_THREAD_STATE @@ -1055,6 +1083,14 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject #define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) #endif +/* WriteUnraisableException.proto */ +static void __Pyx_WriteUnraisable(const char *name, int clineno, + int lineno, const char *filename, + int full_traceback, int nogil); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + /* CLineInTraceback.proto */ #ifdef CYTHON_CLINE_IN_TRACEBACK #define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) @@ -1087,6 +1123,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); +/* None.proto */ +static CYTHON_INLINE long __Pyx_pow_long(long, long); + /* CIntFromPy.proto */ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); @@ -1113,18 +1152,22 @@ static int __Pyx_check_binary_version(void); static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); +/* Module declarations from 'libc.math' */ + /* Module declarations from 'metrics' */ static PyObject *__pyx_f_7metrics_rsq(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ static PyObject *__pyx_f_7metrics_mse(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ static PyObject *__pyx_f_7metrics_rmse(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ static PyObject *__pyx_f_7metrics_mae(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ static PyObject *__pyx_f_7metrics_mape(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ +static double __pyx_f_7metrics_aic(PyObject *, PyObject *, int, int __pyx_skip_dispatch, struct __pyx_opt_args_7metrics_aic *__pyx_optional_args); /*proto*/ #define __Pyx_MODULE_NAME "metrics" extern int __pyx_module_is_main_metrics; int __pyx_module_is_main_metrics = 0; /* Implementation of 'metrics' */ static PyObject *__pyx_builtin_range; +static const char __pyx_k_k[] = "k"; static const char __pyx_k_y[] = "y"; static const char __pyx_k_np[] = "_np"; static const char __pyx_k_main[] = "__main__"; @@ -1135,13 +1178,18 @@ static const char __pyx_k_range[] = "range"; static const char __pyx_k_round[] = "round"; static const char __pyx_k_y_hat[] = "y_hat"; static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_linear[] = "linear"; +static const char __pyx_k_method[] = "method"; static const char __pyx_k_corrcoef[] = "corrcoef"; static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_Common_metrics_required_in_mach[] = "\nCommon metrics required in machine learning modules.\n\n**Available functions:**\n - ``rsq``: R-Squared\n - ``mse``: Mean squared error\n - ``rmse``: Root mean squared error\n - ``mae``: Mean absolute error\n - ``mape``: Mean absolute percentage error\n\nCredits\n-------\n::\n\n Authors:\n - Diptesh\n\n Date: Sep 10, 2021\n"; +static const char __pyx_k_Common_metrics_required_in_mach[] = "\nCommon metrics required in machine learning modules.\n\n**Available functions:**\n - ``rsq``: R-Squared\n - ``mse``: Mean squared error\n - ``rmse``: Root mean squared error\n - ``mae``: Mean absolute error\n - ``mape``: Mean absolute percentage error\n - ``aic``: Akaike information criterion\n\nCredits\n-------\n::\n\n Authors:\n - Diptesh\n\n Date: Dec 19, 2021\n"; static PyObject *__pyx_n_s_cline_in_traceback; static PyObject *__pyx_n_s_corrcoef; static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_k; +static PyObject *__pyx_n_s_linear; static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_method; static PyObject *__pyx_n_s_name; static PyObject *__pyx_n_s_np; static PyObject *__pyx_n_s_numpy; @@ -1155,12 +1203,13 @@ static PyObject *__pyx_pf_7metrics_2mse(CYTHON_UNUSED PyObject *__pyx_self, PyOb static PyObject *__pyx_pf_7metrics_4rmse(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat); /* proto */ static PyObject *__pyx_pf_7metrics_6mae(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat); /* proto */ static PyObject *__pyx_pf_7metrics_8mape(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat); /* proto */ +static PyObject *__pyx_pf_7metrics_10aic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat, int __pyx_v_k, PyObject *__pyx_v_method); /* proto */ static PyObject *__pyx_float_0_5; static PyObject *__pyx_int_2; static PyObject *__pyx_int_3; /* Late includes */ -/* "metrics.pyx":28 +/* "metrics.pyx":31 * * * cpdef rsq(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1181,7 +1230,7 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h PyObject *__pyx_t_7 = NULL; __Pyx_RefNannySetupContext("rsq", 0); - /* "metrics.pyx":51 + /* "metrics.pyx":54 * * """ * return _np.round(_np.corrcoef(y, y_hat)[0][1] ** 2, 3) # <<<<<<<<<<<<<< @@ -1189,14 +1238,14 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h * */ __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_round); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_round); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_corrcoef); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_corrcoef); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; @@ -1214,7 +1263,7 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h #if CYTHON_FAST_PYCALL if (PyFunction_Check(__pyx_t_5)) { PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_y, __pyx_v_y_hat}; - __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_GOTREF(__pyx_t_2); } else @@ -1222,13 +1271,13 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h #if CYTHON_FAST_PYCCALL if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) { PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_y, __pyx_v_y_hat}; - __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_GOTREF(__pyx_t_2); } else #endif { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (__pyx_t_4) { __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL; @@ -1239,18 +1288,18 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h __Pyx_INCREF(__pyx_v_y_hat); __Pyx_GIVEREF(__pyx_v_y_hat); PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_v_y_hat); - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_5, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_5, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = PyNumber_Power(__pyx_t_2, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_5 = PyNumber_Power(__pyx_t_2, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = NULL; @@ -1268,7 +1317,7 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h #if CYTHON_FAST_PYCALL if (PyFunction_Check(__pyx_t_3)) { PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_t_5, __pyx_int_3}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; @@ -1277,14 +1326,14 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h #if CYTHON_FAST_PYCCALL if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_t_5, __pyx_int_3}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } else #endif { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (__pyx_t_2) { __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2); __pyx_t_2 = NULL; @@ -1295,7 +1344,7 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h __Pyx_GIVEREF(__pyx_int_3); PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_int_3); __pyx_t_5 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } @@ -1304,7 +1353,7 @@ static PyObject *__pyx_f_7metrics_rsq(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h __pyx_t_1 = 0; goto __pyx_L0; - /* "metrics.pyx":28 + /* "metrics.pyx":31 * * * cpdef rsq(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1360,11 +1409,11 @@ static PyObject *__pyx_pw_7metrics_1rsq(PyObject *__pyx_self, PyObject *__pyx_ar case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("rsq", 1, 2, 2, 1); __PYX_ERR(0, 28, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("rsq", 1, 2, 2, 1); __PYX_ERR(0, 31, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rsq") < 0)) __PYX_ERR(0, 28, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rsq") < 0)) __PYX_ERR(0, 31, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; @@ -1377,14 +1426,14 @@ static PyObject *__pyx_pw_7metrics_1rsq(PyObject *__pyx_self, PyObject *__pyx_ar } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("rsq", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 28, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("rsq", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 31, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("metrics.rsq", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 28, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 28, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 31, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 31, __pyx_L1_error) __pyx_r = __pyx_pf_7metrics_rsq(__pyx_self, __pyx_v_y, __pyx_v_y_hat); /* function exit code */ @@ -1402,7 +1451,7 @@ static PyObject *__pyx_pf_7metrics_rsq(CYTHON_UNUSED PyObject *__pyx_self, PyObj PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("rsq", 0); __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_rsq(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_rsq(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -1419,7 +1468,7 @@ static PyObject *__pyx_pf_7metrics_rsq(CYTHON_UNUSED PyObject *__pyx_self, PyObj return __pyx_r; } -/* "metrics.pyx":54 +/* "metrics.pyx":57 * * * cpdef mse(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1444,7 +1493,7 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h double __pyx_t_6; __Pyx_RefNannySetupContext("mse", 0); - /* "metrics.pyx":80 + /* "metrics.pyx":83 * cdef double a * cdef double b * cdef double op = 0.0 # <<<<<<<<<<<<<< @@ -1453,7 +1502,7 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ __pyx_v_op = 0.0; - /* "metrics.pyx":81 + /* "metrics.pyx":84 * cdef double b * cdef double op = 0.0 * arr_len = len(y) # <<<<<<<<<<<<<< @@ -1462,12 +1511,12 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 81, __pyx_L1_error) + __PYX_ERR(0, 84, __pyx_L1_error) } - __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 81, __pyx_L1_error) + __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 84, __pyx_L1_error) __pyx_v_arr_len = __pyx_t_1; - /* "metrics.pyx":82 + /* "metrics.pyx":85 * cdef double op = 0.0 * arr_len = len(y) * for i in range(0, arr_len, 1): # <<<<<<<<<<<<<< @@ -1479,7 +1528,7 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { __pyx_v_i = __pyx_t_4; - /* "metrics.pyx":83 + /* "metrics.pyx":86 * arr_len = len(y) * for i in range(0, arr_len, 1): * a = y[i] # <<<<<<<<<<<<<< @@ -1488,15 +1537,15 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 83, __pyx_L1_error) + __PYX_ERR(0, 86, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 83, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 86, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 83, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 86, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_a = __pyx_t_6; - /* "metrics.pyx":84 + /* "metrics.pyx":87 * for i in range(0, arr_len, 1): * a = y[i] * b = y_hat[i] # <<<<<<<<<<<<<< @@ -1505,15 +1554,15 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y_hat == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 84, __pyx_L1_error) + __PYX_ERR(0, 87, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 84, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_b = __pyx_t_6; - /* "metrics.pyx":85 + /* "metrics.pyx":88 * a = y[i] * b = y_hat[i] * op = op + (a - b) ** 2 # <<<<<<<<<<<<<< @@ -1523,7 +1572,7 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h __pyx_v_op = (__pyx_v_op + pow((__pyx_v_a - __pyx_v_b), 2.0)); } - /* "metrics.pyx":86 + /* "metrics.pyx":89 * b = y_hat[i] * op = op + (a - b) ** 2 * op = op * arr_len ** -1.0 # <<<<<<<<<<<<<< @@ -1532,7 +1581,7 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ __pyx_v_op = (__pyx_v_op * pow(((double)__pyx_v_arr_len), -1.0)); - /* "metrics.pyx":87 + /* "metrics.pyx":90 * op = op + (a - b) ** 2 * op = op * arr_len ** -1.0 * return op # <<<<<<<<<<<<<< @@ -1540,13 +1589,13 @@ static PyObject *__pyx_f_7metrics_mse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h * cpdef rmse(list y, list y_hat): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; - /* "metrics.pyx":54 + /* "metrics.pyx":57 * * * cpdef mse(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1597,11 +1646,11 @@ static PyObject *__pyx_pw_7metrics_3mse(PyObject *__pyx_self, PyObject *__pyx_ar case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("mse", 1, 2, 2, 1); __PYX_ERR(0, 54, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mse", 1, 2, 2, 1); __PYX_ERR(0, 57, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mse") < 0)) __PYX_ERR(0, 54, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mse") < 0)) __PYX_ERR(0, 57, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; @@ -1614,14 +1663,14 @@ static PyObject *__pyx_pw_7metrics_3mse(PyObject *__pyx_self, PyObject *__pyx_ar } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("mse", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 54, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mse", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 57, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("metrics.mse", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 54, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 54, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 57, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 57, __pyx_L1_error) __pyx_r = __pyx_pf_7metrics_2mse(__pyx_self, __pyx_v_y, __pyx_v_y_hat); /* function exit code */ @@ -1639,7 +1688,7 @@ static PyObject *__pyx_pf_7metrics_2mse(CYTHON_UNUSED PyObject *__pyx_self, PyOb PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("mse", 0); __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_mse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_mse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -1656,7 +1705,7 @@ static PyObject *__pyx_pf_7metrics_2mse(CYTHON_UNUSED PyObject *__pyx_self, PyOb return __pyx_r; } -/* "metrics.pyx":89 +/* "metrics.pyx":92 * return op * * cpdef rmse(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1672,7 +1721,7 @@ static PyObject *__pyx_f_7metrics_rmse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("rmse", 0); - /* "metrics.pyx":111 + /* "metrics.pyx":114 * * """ * return mse(y, y_hat) ** 0.5 # <<<<<<<<<<<<<< @@ -1680,16 +1729,16 @@ static PyObject *__pyx_f_7metrics_rmse(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ * */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_mse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_mse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyNumber_Power(__pyx_t_1, __pyx_float_0_5, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 111, __pyx_L1_error) + __pyx_t_2 = PyNumber_Power(__pyx_t_1, __pyx_float_0_5, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; - /* "metrics.pyx":89 + /* "metrics.pyx":92 * return op * * cpdef rmse(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1741,11 +1790,11 @@ static PyObject *__pyx_pw_7metrics_5rmse(PyObject *__pyx_self, PyObject *__pyx_a case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("rmse", 1, 2, 2, 1); __PYX_ERR(0, 89, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("rmse", 1, 2, 2, 1); __PYX_ERR(0, 92, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmse") < 0)) __PYX_ERR(0, 89, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmse") < 0)) __PYX_ERR(0, 92, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; @@ -1758,14 +1807,14 @@ static PyObject *__pyx_pw_7metrics_5rmse(PyObject *__pyx_self, PyObject *__pyx_a } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("rmse", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 89, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("rmse", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 92, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("metrics.rmse", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 89, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 89, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 92, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 92, __pyx_L1_error) __pyx_r = __pyx_pf_7metrics_4rmse(__pyx_self, __pyx_v_y, __pyx_v_y_hat); /* function exit code */ @@ -1783,7 +1832,7 @@ static PyObject *__pyx_pf_7metrics_4rmse(CYTHON_UNUSED PyObject *__pyx_self, PyO PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("rmse", 0); __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_rmse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_rmse(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -1800,7 +1849,7 @@ static PyObject *__pyx_pf_7metrics_4rmse(CYTHON_UNUSED PyObject *__pyx_self, PyO return __pyx_r; } -/* "metrics.pyx":114 +/* "metrics.pyx":117 * * * cpdef mae(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1825,7 +1874,7 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h double __pyx_t_6; __Pyx_RefNannySetupContext("mae", 0); - /* "metrics.pyx":140 + /* "metrics.pyx":143 * cdef double a * cdef double b * cdef double op = 0.0 # <<<<<<<<<<<<<< @@ -1834,7 +1883,7 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ __pyx_v_op = 0.0; - /* "metrics.pyx":141 + /* "metrics.pyx":144 * cdef double b * cdef double op = 0.0 * arr_len = len(y) # <<<<<<<<<<<<<< @@ -1843,12 +1892,12 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 141, __pyx_L1_error) + __PYX_ERR(0, 144, __pyx_L1_error) } - __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 141, __pyx_L1_error) + __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 144, __pyx_L1_error) __pyx_v_arr_len = __pyx_t_1; - /* "metrics.pyx":142 + /* "metrics.pyx":145 * cdef double op = 0.0 * arr_len = len(y) * for i in range(0, arr_len, 1): # <<<<<<<<<<<<<< @@ -1860,7 +1909,7 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { __pyx_v_i = __pyx_t_4; - /* "metrics.pyx":143 + /* "metrics.pyx":146 * arr_len = len(y) * for i in range(0, arr_len, 1): * a = y[i] # <<<<<<<<<<<<<< @@ -1869,15 +1918,15 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 143, __pyx_L1_error) + __PYX_ERR(0, 146, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 143, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 146, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 143, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 146, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_a = __pyx_t_6; - /* "metrics.pyx":144 + /* "metrics.pyx":147 * for i in range(0, arr_len, 1): * a = y[i] * b = y_hat[i] # <<<<<<<<<<<<<< @@ -1886,15 +1935,15 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ if (unlikely(__pyx_v_y_hat == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 144, __pyx_L1_error) + __PYX_ERR(0, 147, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 144, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 144, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 147, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_b = __pyx_t_6; - /* "metrics.pyx":145 + /* "metrics.pyx":148 * a = y[i] * b = y_hat[i] * op += abs(a - b) # <<<<<<<<<<<<<< @@ -1904,7 +1953,7 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h __pyx_v_op = (__pyx_v_op + fabs((__pyx_v_a - __pyx_v_b))); } - /* "metrics.pyx":146 + /* "metrics.pyx":149 * b = y_hat[i] * op += abs(a - b) * op = op * arr_len ** -1.0 # <<<<<<<<<<<<<< @@ -1913,7 +1962,7 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h */ __pyx_v_op = (__pyx_v_op * pow(((double)__pyx_v_arr_len), -1.0)); - /* "metrics.pyx":147 + /* "metrics.pyx":150 * op += abs(a - b) * op = op * arr_len ** -1.0 * return op # <<<<<<<<<<<<<< @@ -1921,13 +1970,13 @@ static PyObject *__pyx_f_7metrics_mae(PyObject *__pyx_v_y, PyObject *__pyx_v_y_h * */ __Pyx_XDECREF(__pyx_r); - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; - /* "metrics.pyx":114 + /* "metrics.pyx":117 * * * cpdef mae(list y, list y_hat): # <<<<<<<<<<<<<< @@ -1978,11 +2027,11 @@ static PyObject *__pyx_pw_7metrics_7mae(PyObject *__pyx_self, PyObject *__pyx_ar case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("mae", 1, 2, 2, 1); __PYX_ERR(0, 114, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mae", 1, 2, 2, 1); __PYX_ERR(0, 117, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mae") < 0)) __PYX_ERR(0, 114, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mae") < 0)) __PYX_ERR(0, 117, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; @@ -1995,14 +2044,14 @@ static PyObject *__pyx_pw_7metrics_7mae(PyObject *__pyx_self, PyObject *__pyx_ar } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("mae", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 114, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mae", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 117, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("metrics.mae", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 114, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 114, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 117, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 117, __pyx_L1_error) __pyx_r = __pyx_pf_7metrics_6mae(__pyx_self, __pyx_v_y, __pyx_v_y_hat); /* function exit code */ @@ -2020,7 +2069,7 @@ static PyObject *__pyx_pf_7metrics_6mae(CYTHON_UNUSED PyObject *__pyx_self, PyOb PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("mae", 0); __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_mae(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_mae(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -2037,7 +2086,7 @@ static PyObject *__pyx_pf_7metrics_6mae(CYTHON_UNUSED PyObject *__pyx_self, PyOb return __pyx_r; } -/* "metrics.pyx":150 +/* "metrics.pyx":153 * * * cpdef mape(list y, list y_hat): # <<<<<<<<<<<<<< @@ -2060,9 +2109,10 @@ static PyObject *__pyx_f_7metrics_mape(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ int __pyx_t_4; PyObject *__pyx_t_5 = NULL; double __pyx_t_6; + int __pyx_t_7; __Pyx_RefNannySetupContext("mape", 0); - /* "metrics.pyx":176 + /* "metrics.pyx":179 * cdef double a * cdef double b * cdef double op = 0.0 # <<<<<<<<<<<<<< @@ -2071,7 +2121,7 @@ static PyObject *__pyx_f_7metrics_mape(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ */ __pyx_v_op = 0.0; - /* "metrics.pyx":177 + /* "metrics.pyx":180 * cdef double b * cdef double op = 0.0 * arr_len = len(y) # <<<<<<<<<<<<<< @@ -2080,12 +2130,12 @@ static PyObject *__pyx_f_7metrics_mape(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 177, __pyx_L1_error) + __PYX_ERR(0, 180, __pyx_L1_error) } - __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 177, __pyx_L1_error) + __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 180, __pyx_L1_error) __pyx_v_arr_len = __pyx_t_1; - /* "metrics.pyx":178 + /* "metrics.pyx":181 * cdef double op = 0.0 * arr_len = len(y) * for i in range(0, arr_len, 1): # <<<<<<<<<<<<<< @@ -2097,71 +2147,93 @@ static PyObject *__pyx_f_7metrics_mape(PyObject *__pyx_v_y, PyObject *__pyx_v_y_ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { __pyx_v_i = __pyx_t_4; - /* "metrics.pyx":179 + /* "metrics.pyx":182 * arr_len = len(y) * for i in range(0, arr_len, 1): * a = y[i] # <<<<<<<<<<<<<< * b = y_hat[i] - * op += abs(1 - (b * a ** -1.0)) + * if a != 0.0: */ if (unlikely(__pyx_v_y == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 179, __pyx_L1_error) + __PYX_ERR(0, 182, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 179, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 182, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 179, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 182, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_a = __pyx_t_6; - /* "metrics.pyx":180 + /* "metrics.pyx":183 * for i in range(0, arr_len, 1): * a = y[i] * b = y_hat[i] # <<<<<<<<<<<<<< - * op += abs(1 - (b * a ** -1.0)) - * op = op * arr_len ** -1.0 + * if a != 0.0: + * op += abs(1 - (b * a ** -1.0)) */ if (unlikely(__pyx_v_y_hat == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 180, __pyx_L1_error) + __PYX_ERR(0, 183, __pyx_L1_error) } - __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 180, __pyx_L1_error) + __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 180, __pyx_L1_error) + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 183, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_b = __pyx_t_6; - /* "metrics.pyx":181 + /* "metrics.pyx":184 * a = y[i] * b = y_hat[i] - * op += abs(1 - (b * a ** -1.0)) # <<<<<<<<<<<<<< + * if a != 0.0: # <<<<<<<<<<<<<< + * op += abs(1 - (b * a ** -1.0)) + * op = op * arr_len ** -1.0 + */ + __pyx_t_7 = ((__pyx_v_a != 0.0) != 0); + if (__pyx_t_7) { + + /* "metrics.pyx":185 + * b = y_hat[i] + * if a != 0.0: + * op += abs(1 - (b * a ** -1.0)) # <<<<<<<<<<<<<< * op = op * arr_len ** -1.0 * return op */ - __pyx_v_op = (__pyx_v_op + fabs((1.0 - (__pyx_v_b * pow(__pyx_v_a, -1.0))))); - } + __pyx_v_op = (__pyx_v_op + fabs((1.0 - (__pyx_v_b * pow(__pyx_v_a, -1.0))))); - /* "metrics.pyx":182 + /* "metrics.pyx":184 + * a = y[i] * b = y_hat[i] - * op += abs(1 - (b * a ** -1.0)) + * if a != 0.0: # <<<<<<<<<<<<<< + * op += abs(1 - (b * a ** -1.0)) + * op = op * arr_len ** -1.0 + */ + } + } + + /* "metrics.pyx":186 + * if a != 0.0: + * op += abs(1 - (b * a ** -1.0)) * op = op * arr_len ** -1.0 # <<<<<<<<<<<<<< * return op + * */ __pyx_v_op = (__pyx_v_op * pow(((double)__pyx_v_arr_len), -1.0)); - /* "metrics.pyx":183 - * op += abs(1 - (b * a ** -1.0)) + /* "metrics.pyx":187 + * op += abs(1 - (b * a ** -1.0)) * op = op * arr_len ** -1.0 * return op # <<<<<<<<<<<<<< + * + * */ __Pyx_XDECREF(__pyx_r); - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_op); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; - /* "metrics.pyx":150 + /* "metrics.pyx":153 * * * cpdef mape(list y, list y_hat): # <<<<<<<<<<<<<< @@ -2212,11 +2284,11 @@ static PyObject *__pyx_pw_7metrics_9mape(PyObject *__pyx_self, PyObject *__pyx_a case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("mape", 1, 2, 2, 1); __PYX_ERR(0, 150, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mape", 1, 2, 2, 1); __PYX_ERR(0, 153, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mape") < 0)) __PYX_ERR(0, 150, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mape") < 0)) __PYX_ERR(0, 153, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; @@ -2229,14 +2301,14 @@ static PyObject *__pyx_pw_7metrics_9mape(PyObject *__pyx_self, PyObject *__pyx_a } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("mape", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 150, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mape", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 153, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("metrics.mape", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 150, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 150, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 153, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 153, __pyx_L1_error) __pyx_r = __pyx_pf_7metrics_8mape(__pyx_self, __pyx_v_y, __pyx_v_y_hat); /* function exit code */ @@ -2254,7 +2326,7 @@ static PyObject *__pyx_pf_7metrics_8mape(CYTHON_UNUSED PyObject *__pyx_self, PyO PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("mape", 0); __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7metrics_mape(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7metrics_mape(__pyx_v_y, __pyx_v_y_hat, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 153, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -2271,12 +2343,386 @@ static PyObject *__pyx_pf_7metrics_8mape(CYTHON_UNUSED PyObject *__pyx_self, PyO return __pyx_r; } +/* "metrics.pyx":190 + * + * + * cpdef double aic(list y, list y_hat, int k, str method="linear"): # <<<<<<<<<<<<<< + * """ + * Compute `Akaike information criterion + */ + +static PyObject *__pyx_pw_7metrics_11aic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static double __pyx_f_7metrics_aic(PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat, int __pyx_v_k, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_7metrics_aic *__pyx_optional_args) { + PyObject *__pyx_v_method = ((PyObject*)__pyx_n_s_linear); + double __pyx_v_op; + double __pyx_v_sse; + double __pyx_v_a; + double __pyx_v_b; + int __pyx_v_arr_len; + double __pyx_v_small_sample; + long __pyx_v_i; + double __pyx_r; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + long __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + double __pyx_t_8; + __Pyx_RefNannySetupContext("aic", 0); + if (__pyx_optional_args) { + if (__pyx_optional_args->__pyx_n > 0) { + __pyx_v_method = __pyx_optional_args->method; + } + } + + /* "metrics.pyx":220 + * + * """ + * cdef double op = 0.0 # <<<<<<<<<<<<<< + * cdef double sse = 0.0 + * cdef double a = 0.0 + */ + __pyx_v_op = 0.0; + + /* "metrics.pyx":221 + * """ + * cdef double op = 0.0 + * cdef double sse = 0.0 # <<<<<<<<<<<<<< + * cdef double a = 0.0 + * cdef double b = 0.0 + */ + __pyx_v_sse = 0.0; + + /* "metrics.pyx":222 + * cdef double op = 0.0 + * cdef double sse = 0.0 + * cdef double a = 0.0 # <<<<<<<<<<<<<< + * cdef double b = 0.0 + * cdef int arr_len = 0 + */ + __pyx_v_a = 0.0; + + /* "metrics.pyx":223 + * cdef double sse = 0.0 + * cdef double a = 0.0 + * cdef double b = 0.0 # <<<<<<<<<<<<<< + * cdef int arr_len = 0 + * cdef double small_sample = 0.0 + */ + __pyx_v_b = 0.0; + + /* "metrics.pyx":224 + * cdef double a = 0.0 + * cdef double b = 0.0 + * cdef int arr_len = 0 # <<<<<<<<<<<<<< + * cdef double small_sample = 0.0 + * small_sample = arr_len * k ** -1 + */ + __pyx_v_arr_len = 0; + + /* "metrics.pyx":225 + * cdef double b = 0.0 + * cdef int arr_len = 0 + * cdef double small_sample = 0.0 # <<<<<<<<<<<<<< + * small_sample = arr_len * k ** -1 + * arr_len = len(y) + */ + __pyx_v_small_sample = 0.0; + + /* "metrics.pyx":226 + * cdef int arr_len = 0 + * cdef double small_sample = 0.0 + * small_sample = arr_len * k ** -1 # <<<<<<<<<<<<<< + * arr_len = len(y) + * if method == "linear": + */ + __pyx_v_small_sample = (__pyx_v_arr_len * __Pyx_pow_long(((long)__pyx_v_k), -1L)); + + /* "metrics.pyx":227 + * cdef double small_sample = 0.0 + * small_sample = arr_len * k ** -1 + * arr_len = len(y) # <<<<<<<<<<<<<< + * if method == "linear": + * for i in range(0, arr_len, 1): + */ + if (unlikely(__pyx_v_y == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(0, 227, __pyx_L1_error) + } + __pyx_t_1 = PyList_GET_SIZE(__pyx_v_y); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 227, __pyx_L1_error) + __pyx_v_arr_len = __pyx_t_1; + + /* "metrics.pyx":228 + * small_sample = arr_len * k ** -1 + * arr_len = len(y) + * if method == "linear": # <<<<<<<<<<<<<< + * for i in range(0, arr_len, 1): + * a = y[i] + */ + __pyx_t_2 = (__Pyx_PyString_Equals(__pyx_v_method, __pyx_n_s_linear, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 228, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_2 != 0); + if (__pyx_t_3) { + + /* "metrics.pyx":229 + * arr_len = len(y) + * if method == "linear": + * for i in range(0, arr_len, 1): # <<<<<<<<<<<<<< + * a = y[i] + * b = y_hat[i] + */ + __pyx_t_4 = __pyx_v_arr_len; + __pyx_t_5 = __pyx_t_4; + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_i = __pyx_t_6; + + /* "metrics.pyx":230 + * if method == "linear": + * for i in range(0, arr_len, 1): + * a = y[i] # <<<<<<<<<<<<<< + * b = y_hat[i] + * sse += (a - b) ** 2 + */ + if (unlikely(__pyx_v_y == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 230, __pyx_L1_error) + } + __pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_y, __pyx_v_i, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_7); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_a = __pyx_t_8; + + /* "metrics.pyx":231 + * for i in range(0, arr_len, 1): + * a = y[i] + * b = y_hat[i] # <<<<<<<<<<<<<< + * sse += (a - b) ** 2 + * op = 2 * k - 2 * log(sse) + */ + if (unlikely(__pyx_v_y_hat == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 231, __pyx_L1_error) + } + __pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_y_hat, __pyx_v_i, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_7); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 231, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_b = __pyx_t_8; + + /* "metrics.pyx":232 + * a = y[i] + * b = y_hat[i] + * sse += (a - b) ** 2 # <<<<<<<<<<<<<< + * op = 2 * k - 2 * log(sse) + * if small_sample <= 40: + */ + __pyx_v_sse = (__pyx_v_sse + pow((__pyx_v_a - __pyx_v_b), 2.0)); + } + + /* "metrics.pyx":233 + * b = y_hat[i] + * sse += (a - b) ** 2 + * op = 2 * k - 2 * log(sse) # <<<<<<<<<<<<<< + * if small_sample <= 40: + * op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 + */ + __pyx_v_op = ((2 * __pyx_v_k) - (2.0 * log(__pyx_v_sse))); + + /* "metrics.pyx":234 + * sse += (a - b) ** 2 + * op = 2 * k - 2 * log(sse) + * if small_sample <= 40: # <<<<<<<<<<<<<< + * op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 + * return op + */ + __pyx_t_3 = ((__pyx_v_small_sample <= 40.0) != 0); + if (__pyx_t_3) { + + /* "metrics.pyx":235 + * op = 2 * k - 2 * log(sse) + * if small_sample <= 40: + * op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 # <<<<<<<<<<<<<< + * return op + */ + __pyx_v_op = (__pyx_v_op + (((2 * __pyx_v_k) * (__pyx_v_k + 1)) * __Pyx_pow_long(((__pyx_v_arr_len - __pyx_v_k) - 1), -1L))); + + /* "metrics.pyx":234 + * sse += (a - b) ** 2 + * op = 2 * k - 2 * log(sse) + * if small_sample <= 40: # <<<<<<<<<<<<<< + * op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 + * return op + */ + } + + /* "metrics.pyx":228 + * small_sample = arr_len * k ** -1 + * arr_len = len(y) + * if method == "linear": # <<<<<<<<<<<<<< + * for i in range(0, arr_len, 1): + * a = y[i] + */ + } + + /* "metrics.pyx":236 + * if small_sample <= 40: + * op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 + * return op # <<<<<<<<<<<<<< + */ + __pyx_r = __pyx_v_op; + goto __pyx_L0; + + /* "metrics.pyx":190 + * + * + * cpdef double aic(list y, list y_hat, int k, str method="linear"): # <<<<<<<<<<<<<< + * """ + * Compute `Akaike information criterion + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_7); + __Pyx_WriteUnraisable("metrics.aic", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_7metrics_11aic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7metrics_10aic[] = "\n Compute `Akaike information criterion\n `_.\n\n Parameters\n ----------\n y : list\n\n Actual values.\n\n y_hat : list\n\n Predicted values.\n\n k : int\n\n Number of parameters.\n\n method : str, optional\n\n Type of regression (the default is linear).\n\n Returns\n -------\n op : float\n\n Akaike information criterion.\n\n "; +static PyObject *__pyx_pw_7metrics_11aic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_y = 0; + PyObject *__pyx_v_y_hat = 0; + int __pyx_v_k; + PyObject *__pyx_v_method = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("aic (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_y,&__pyx_n_s_y_hat,&__pyx_n_s_k,&__pyx_n_s_method,0}; + PyObject* values[4] = {0,0,0,0}; + values[3] = ((PyObject*)__pyx_n_s_linear); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y_hat)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("aic", 0, 3, 4, 1); __PYX_ERR(0, 190, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_k)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("aic", 0, 3, 4, 2); __PYX_ERR(0, 190, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method); + if (value) { values[3] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "aic") < 0)) __PYX_ERR(0, 190, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_y = ((PyObject*)values[0]); + __pyx_v_y_hat = ((PyObject*)values[1]); + __pyx_v_k = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_k == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 190, __pyx_L3_error) + __pyx_v_method = ((PyObject*)values[3]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("aic", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 190, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("metrics.aic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), (&PyList_Type), 1, "y", 1))) __PYX_ERR(0, 190, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y_hat), (&PyList_Type), 1, "y_hat", 1))) __PYX_ERR(0, 190, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_method), (&PyString_Type), 1, "method", 1))) __PYX_ERR(0, 190, __pyx_L1_error) + __pyx_r = __pyx_pf_7metrics_10aic(__pyx_self, __pyx_v_y, __pyx_v_y_hat, __pyx_v_k, __pyx_v_method); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7metrics_10aic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_y_hat, int __pyx_v_k, PyObject *__pyx_v_method) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + double __pyx_t_1; + struct __pyx_opt_args_7metrics_aic __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + __Pyx_RefNannySetupContext("aic", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_2.__pyx_n = 1; + __pyx_t_2.method = __pyx_v_method; + __pyx_t_1 = __pyx_f_7metrics_aic(__pyx_v_y, __pyx_v_y_hat, __pyx_v_k, 0, &__pyx_t_2); + __pyx_t_3 = PyFloat_FromDouble(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 190, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("metrics.aic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + static PyMethodDef __pyx_methods[] = { {"rsq", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_1rsq, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_rsq}, {"mse", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_3mse, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_2mse}, {"rmse", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_5rmse, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_4rmse}, {"mae", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_7mae, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_6mae}, {"mape", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_9mape, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_8mape}, + {"aic", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7metrics_11aic, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7metrics_10aic}, {0, 0, 0, 0} }; @@ -2325,7 +2771,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, {&__pyx_n_s_corrcoef, __pyx_k_corrcoef, sizeof(__pyx_k_corrcoef), 0, 0, 1, 1}, {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_k, __pyx_k_k, sizeof(__pyx_k_k), 0, 0, 1, 1}, + {&__pyx_n_s_linear, __pyx_k_linear, sizeof(__pyx_k_linear), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 0, 1, 1}, {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, @@ -2337,7 +2786,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {0, 0, 0, 0, 0, 0, 0} }; static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 82, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 85, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; @@ -2621,16 +3070,16 @@ if (!__Pyx_RefNanny) { if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif - /* "metrics.pyx":21 + /* "metrics.pyx":22 * """ * * import numpy as _np # <<<<<<<<<<<<<< * - * # ============================================================================= + * from libc.math cimport log */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 21, __pyx_L1_error) + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 21, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 22, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "metrics.pyx":1 @@ -3186,6 +3635,221 @@ static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *nam return 0; } +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* WriteUnraisableException */ +static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, + CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, + int full_traceback, CYTHON_UNUSED int nogil) { + PyObject *old_exc, *old_val, *old_tb; + PyObject *ctx; + __Pyx_PyThreadState_declare +#ifdef WITH_THREAD + PyGILState_STATE state; + if (nogil) + state = PyGILState_Ensure(); +#ifdef _MSC_VER + else state = (PyGILState_STATE)-1; +#endif +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); + if (full_traceback) { + Py_XINCREF(old_exc); + Py_XINCREF(old_val); + Py_XINCREF(old_tb); + __Pyx_ErrRestore(old_exc, old_val, old_tb); + PyErr_PrintEx(1); + } + #if PY_MAJOR_VERSION < 3 + ctx = PyString_FromString(name); + #else + ctx = PyUnicode_FromString(name); + #endif + __Pyx_ErrRestore(old_exc, old_val, old_tb); + if (!ctx) { + PyErr_WriteUnraisable(Py_None); + } else { + PyErr_WriteUnraisable(ctx); + Py_DECREF(ctx); + } +#ifdef WITH_THREAD + if (nogil) + PyGILState_Release(state); +#endif +} + /* Import */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; @@ -3251,30 +3915,6 @@ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { return module; } -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - /* CLineInTraceback */ #ifndef CYTHON_CLINE_IN_TRACEBACK static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { @@ -3482,6 +4122,28 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, Py_XDECREF(py_frame); } +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; @@ -3544,27 +4206,32 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { } } -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ +/* None */ +static CYTHON_INLINE long __Pyx_pow_long(long b, long e) { + long t = b; + switch (e) { + case 3: + t *= b; + CYTHON_FALLTHROUGH; + case 2: + t *= b; + CYTHON_FALLTHROUGH; + case 1: + return t; + case 0: + return 1; } + #if 1 + if (unlikely(e<0)) return 0; + #endif + t = 1; + while (likely(e)) { + t *= (b * (e&1)) | ((~e)&1); + b *= b; + e >>= 1; + } + return t; +} /* CIntFromPy */ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { diff --git a/bin/metrics/metrics.pyx b/bin/metrics/metrics.pyx index 268ac13..1ee757a 100644 --- a/bin/metrics/metrics.pyx +++ b/bin/metrics/metrics.pyx @@ -7,6 +7,7 @@ Common metrics required in machine learning modules. - ``rmse``: Root mean squared error - ``mae``: Mean absolute error - ``mape``: Mean absolute percentage error + - ``aic``: Akaike information criterion Credits ------- @@ -15,11 +16,13 @@ Credits Authors: - Diptesh - Date: Sep 10, 2021 + Date: Dec 19, 2021 """ import numpy as _np +from libc.math cimport log + # ============================================================================= # --- User defined functions # ============================================================================= @@ -178,6 +181,56 @@ cpdef mape(list y, list y_hat): for i in range(0, arr_len, 1): a = y[i] b = y_hat[i] - op += abs(1 - (b * a ** -1.0)) + if a != 0.0: + op += abs(1 - (b * a ** -1.0)) op = op * arr_len ** -1.0 return op + + +cpdef double aic(list y, list y_hat, int k, str method="linear"): + """ + Compute `Akaike information criterion + `_. + + Parameters + ---------- + y : list + + Actual values. + + y_hat : list + + Predicted values. + + k : int + + Number of parameters. + + method : str, optional + + Type of regression (the default is linear). + + Returns + ------- + op : float + + Akaike information criterion. + + """ + cdef double op = 0.0 + cdef double sse = 0.0 + cdef double a = 0.0 + cdef double b = 0.0 + cdef int arr_len = 0 + cdef double small_sample = 0.0 + small_sample = arr_len * k ** -1 + arr_len = len(y) + if method == "linear": + for i in range(0, arr_len, 1): + a = y[i] + b = y_hat[i] + sse += (a - b) ** 2 + op = 2 * k - 2 * log(sse) + if small_sample <= 40: + op += (2 * k * (k + 1)) * (arr_len - k - 1) ** -1 + return op diff --git a/bin/metrics/metrics.so b/bin/metrics/metrics.so index c972ad9..da0163e 100644 Binary files a/bin/metrics/metrics.so and b/bin/metrics/metrics.so differ diff --git a/bin/run_tests.sh b/bin/run_tests.sh index ff63c0e..a39cb95 100644 --- a/bin/run_tests.sh +++ b/bin/run_tests.sh @@ -51,6 +51,7 @@ then printf "\nRating code style...\n\n" score=0 cnt=0 + rm $proj_dir/logs/pylint/*.out for i in $(find "$proj_dir" -name "*.py") do file=${i#$(dirname "$(dirname "$i")")/} diff --git a/data/input/test_time_series.csv b/data/input/test_time_series.csv deleted file mode 100644 index 03b99df..0000000 --- a/data/input/test_time_series.csv +++ /dev/null @@ -1,336 +0,0 @@ -ds,y,cost,cp,stock_level,retail_price -01/01/2017,0,0,42.5340409356725,4890,152.650887920178 -01/02/2017,171,7273.321,42.5340409356725,2233,63.02 -01/03/2017,168,7150.338,42.5615357142857,3119,107.835443960089 -01/04/2017,166,7074.227,42.6158253012048,2725,63.02 -01/05/2017,211,8993.719,42.6242606635071,2507,62.694863635 -01/06/2017,278,11866.209,42.6842050359712,2583,91.9407013800594 -01/07/2017,226,9648.065,42.6905530973451,2323,107.835443960089 -01/08/2017,119,5087.746,42.7541680672269,2276,107.835443960089 -01/09/2017,152,6499.54,42.7601315789474,2338,62.885833335 -01/10/2017,239,10242.383,42.8551589958159,2633,63.02 -01/11/2017,87,3733.673,42.9157816091954,2214,63.02 -01/12/2017,133,5709.179,42.9261578947368,3179,107.835443960089 -01/13/2017,192,8232.189,42.875984375,2434,63.02 -01/14/2017,142,6085.145,42.8531338028169,2510,107.835443960089 -01/15/2017,146,6262.695,42.8951712328767,2142,63.02 -01/16/2017,92,3943.497,42.864097826087,2161,107.835443960089 -01/17/2017,107,4510.448,42.1537196261682,2458,107.835443960089 -01/18/2017,104,4341.49,41.7450961538462,2940,107.835443960089 -01/19/2017,145,6022.307,41.5331517241379,2676,62.45136607 -01/20/2017,171,7088.815,41.4550584795322,2859,107.835443960089 -01/21/2017,157,6488.643,41.3289363057325,2141,63.02 -01/22/2017,113,4659.682,41.2361238938053,3146,107.835443960089 -01/23/2017,112,4606.455,41.1290625,2466,107.835443960089 -01/24/2017,106,4261.04,40.1984905660377,9019,107.835443960089 -01/25/2017,2269,91009.308,40.1098757161745,8520,50.14 -01/26/2017,2303,92107.172,39.9944298740773,9728,50.14 -01/27/2017,1984,79289.119,39.9642736895161,11955,50.14 -01/28/2017,1634,65292.518,39.9587013463892,10265,50.14 -01/29/2017,1970,78729.548,39.9642375634518,8272,50.14 -01/30/2017,1685,67231.442,39.899965578635,9273,101.395443960089 -01/31/2017,1587,63382.228,39.9383919344676,7969,50.14 -02/01/2017,1798,71822.048,39.9455216907675,7320,50.14 -02/02/2017,1958,78094.678,39.8849223697651,6606,50.14 -02/03/2017,1877,74800.067,39.8508614810868,7912,50.14 -02/04/2017,1888,75277.974,39.8718082627119,6008,50.14 -02/05/2017,1097,43709.917,39.8449562443026,4939,101.395443960089 -02/06/2017,1756,69952.031,39.8360085421412,5335,101.395443960089 -02/07/2017,2595,103354.382,39.8282782273603,3947,84.3247031333928 -02/08/2017,198,7940.389,40.1029747474747,4228,92.7849113567261 -02/09/2017,230,9253.719,40.2335608695652,4405,87.4749256033928 -02/10/2017,305,12386.147,40.6103180327869,4582,92.8659552333927 -02/11/2017,227,9248.287,40.7413524229075,4013,107.835443960089 -02/12/2017,174,7055.609,40.5494770114943,3839,107.835443960089 -02/13/2017,162,6573.97,40.5800617283951,3672,107.835443960089 -02/14/2017,152,6191.34,40.7325,4576,107.835443960089 -02/15/2017,232,9423.421,40.6181939655172,3726,61.99601064 -02/16/2017,236,9622.819,40.774656779661,3491,62.90723611 -02/17/2017,261,10680.505,40.9214750957854,3398,63.02 -02/18/2017,221,9085.481,41.1107737556561,3101,63.02 -02/19/2017,169,6969.824,41.2415621301775,3082,92.4386054967261 -02/20/2017,179,7306.143,40.8164413407821,2811,62.8834375 -02/21/2017,210,8647.538,41.1787523809524,2860,62.95151111 -02/22/2017,88,3640.098,41.36475,3202,107.835443960089 -02/23/2017,110,4576.135,41.6012272727273,3167,92.7351107867261 -02/24/2017,126,5216.422,41.4001746031746,2951,63.02 -02/25/2017,97,4035.09,41.5988659793814,2853,63.02 -02/26/2017,86,3568.977,41.4997325581395,2426,63.02 -02/27/2017,70,2921.921,41.7417285714286,3028,107.835443960089 -02/28/2017,72,2971.001,41.2639027777778,2609,62.758375 -03/01/2017,85,3544.384,41.6986352941177,2457,63.02 -03/02/2017,107,4433.725,41.4366822429907,2728,107.835443960089 -03/03/2017,103,4244.492,41.2086601941748,2743,63.02 -03/04/2017,100,4094.95,40.9495,2404,63.02 -03/05/2017,73,2996.138,41.0429863013699,2803,107.835443960089 -03/06/2017,102,4176.189,40.9430294117647,2938,62.94248148 -03/07/2017,220,8744.37,39.7471363636364,7746,107.835443960089 -03/08/2017,1782,70621.311,39.6303653198653,7536,50.14 -03/09/2017,1492,59057.646,39.5828726541555,10712,50.14 -03/10/2017,1663,65769.123,39.5484804570054,11222,50.14 -03/11/2017,1375,54412.044,39.5723956363636,9831,50.14 -03/12/2017,1032,40820.386,39.5546375968992,8787,50.14 -03/13/2017,1084,42856.57,39.5355811808118,9246,50.14 -03/14/2017,1366,53990.655,39.5246376281113,8224,50.14 -03/15/2017,1400,55377.518,39.55537,7288,50.14 -03/16/2017,1671,66007.17,39.5015978456014,6761,50.14 -03/17/2017,1632,64447.291,39.4897616421569,5948,50.14 -03/18/2017,1566,61859.569,39.5016404853129,4380,50.14 -03/19/2017,1045,41254.979,39.4784488038278,3314,50.14 -03/20/2017,1197,47235.105,39.4612406015038,4196,50.14 -03/21/2017,1740,68730.959,39.5005511494253,2918,50.14 -03/22/2017,178,7169.895,40.280308988764,3252,107.835443960089 -03/23/2017,192,7742.795,40.3270572916667,3210,107.835443960089 -03/24/2017,257,10365.979,40.3345486381323,2641,92.6563251400594 -03/25/2017,150,6040.82,40.2721333333333,5334,107.835443960089 -03/26/2017,133,5368.805,40.3669548872181,2713,107.835443960089 -03/27/2017,145,5823.139,40.1595793103448,2484,92.8148842100594 -03/28/2017,178,7204.39,40.4741011235955,2906,107.835443960089 -03/29/2017,147,5988.401,40.7374217687075,2541,107.835443960089 -03/30/2017,173,7038.352,40.6841156069364,5271,92.8342763667261 -03/31/2017,210,8628.25,41.0869047619048,2670,63.02 -04/01/2017,167,6871.911,41.1491676646707,3051,85.1230676025446 -04/02/2017,180,7426.882,41.2604555555556,2678,62.96097794 -04/03/2017,162,6678.796,41.2271358024691,2453,62.857789475 -04/04/2017,167,6886.495,41.236497005988,2269,63.02 -04/05/2017,212,8766.558,41.3516886792453,2418,63.02 -04/06/2017,212,8875.46,41.8653773584906,2553,63.02 -04/07/2017,320,13327.721,41.649128125,2231,63.02 -04/08/2017,252,10480.18,41.5880158730159,1976,63.02 -04/09/2017,180,7513.064,41.7392444444444,1662,63.02 -04/10/2017,200,8209.41,41.04705,2167,92.3416473233928 -04/11/2017,213,8681.005,40.7558920187793,1991,62.814533335 -04/12/2017,292,11891.483,40.7242568493151,2053,62.83870588 -04/13/2017,417,16868.784,40.4527194244604,1984,62.920935715 -04/14/2017,202,8161.504,40.4034851485149,1759,92.6463935333928 -04/15/2017,189,7656.959,40.5130105820106,1569,107.835443960089 -04/16/2017,129,5222.73,40.4862790697674,0,107.835443960089 -04/17/2017,0,0,39.6269481481481,2979,152.650887920178 -04/18/2017,270,10699.276,39.6269481481481,7470,92.8773100567261 -04/19/2017,1757,69526.763,39.5712936824132,7448,50.14 -04/20/2017,1939,76730.581,39.5722439401753,7923,50.14 -04/21/2017,1728,68251.792,39.4975648148148,10554,50.14 -04/22/2017,1576,62220.08,39.4797461928934,8797,50.14 -04/23/2017,1783,70410.847,39.4900992708918,7350,84.2545848633927 -04/24/2017,1840,72644.71,39.4808206521739,7146,50.14 -04/25/2017,1587,62608.972,39.4511480781348,7685,50.14 -04/26/2017,1885,74337.055,39.4361034482759,6863,50.14 -04/27/2017,1961,77319.606,39.4286619071902,5697,50.14 -04/28/2017,1955,77071.251,39.4226347826087,6842,50.14 -04/29/2017,1559,61458.227,39.4215695958948,5102,101.395443960089 -04/30/2017,1217,47975.17,39.4208463434675,4245,101.395443960089 -05/01/2017,850,33514.149,39.4284105882353,3256,101.395443960089 -05/02/2017,2120,83558.343,39.414312735849,3621,50.14 -05/03/2017,138,5438.966,39.4127971014493,3509,92.6034388300594 -05/04/2017,140,5517.856,39.4132571428571,3308,107.835443960089 -05/05/2017,202,8015.232,39.6793663366337,3106,107.835443960089 -05/06/2017,113,4478.493,39.6326814159292,3394,107.835443960089 -05/07/2017,108,4286.008,39.6852592592593,0,107.835443960089 -05/08/2017,0,0,40.55,6122,152.650887920178 -05/09/2017,180,7299,40.55,3584,107.835443960089 -05/10/2017,138,5551.717,40.2298333333333,3809,107.835443960089 -05/11/2017,180,7281.151,40.4508388888889,3442,63.02 -05/12/2017,171,6901.396,40.3590409356725,3537,63.02 -05/13/2017,175,7101.16,40.5780571428571,2840,62.782923075 -05/14/2017,114,4614.55,40.4785087719298,3760,92.6739904167261 -05/15/2017,104,4261.916,40.9799615384615,3315,85.2865275350446 -05/16/2017,160,6552.587,40.95366875,3155,62.506333335 -05/17/2017,208,8585.482,41.2763557692308,3023,63.02 -05/18/2017,241,9920.996,41.1659585062241,2777,62.95248387 -05/19/2017,240,9878.367,41.1598625,2871,63.02 -05/20/2017,122,5031.618,41.2427704918033,2745,92.8182665600594 -05/21/2017,120,4913.015,40.9417916666667,2699,107.835443960089 -05/22/2017,201,8230.237,40.9464527363184,2602,62.3517541666667 -05/23/2017,158,6454.544,40.8515443037975,2619,63.02 -05/24/2017,251,10292.388,41.0055298804781,2331,62.506333335 -05/25/2017,298,12126.31,40.6923154362416,2209,62.83870588 -05/26/2017,211,8662.579,41.0548767772512,1974,62.95459375 -05/27/2017,154,6335.861,41.1419545454545,1819,107.835443960089 -05/28/2017,126,5126.109,40.6834047619048,1663,107.835443960089 -05/29/2017,147,5898.818,40.1280136054422,2494,107.835443960089 -05/30/2017,209,8326.593,39.8401578947368,8552,62.956984695 -05/31/2017,1649,65638.164,39.8048295936931,8282,52.88313904 -06/01/2017,1616,64356.628,39.824646039604,8743,51.98 -06/02/2017,1539,61284.996,39.8213099415205,10380,51.870331125 -06/03/2017,1035,41198.222,39.805045410628,9340,102.315443960089 -06/04/2017,1081,43027.852,39.8037483811286,8828,102.315443960089 -06/05/2017,1374,54692.01,39.8049563318777,9088,51.98 -06/06/2017,1738,69165.763,39.7961812428078,8198,51.98 -06/07/2017,1642,65367.052,39.8094104750305,7313,51.98 -06/08/2017,1724,68638.413,39.8134646171694,6961,51.98 -06/09/2017,1388,55255.291,39.8092874639769,7876,51.98 -06/10/2017,1412,56199.249,39.8011678470255,6458,51.33025 -06/11/2017,832,33111.808,39.7978461538462,5626,51.98 -06/12/2017,1511,60130.965,39.7954765056254,5509,51.98 -06/13/2017,1493,59428.146,39.80451841929,4900,52.11065089 -06/14/2017,268,10663.657,39.7897649253731,4600,84.9021288550446 -06/15/2017,329,13091.226,39.7909604863222,4242,62.63475 -06/16/2017,347,13806.867,39.789242074928,3884,92.8550306667261 -06/17/2017,247,9829.483,39.7954777327935,3645,92.0931242567261 -06/18/2017,191,7600.971,39.7956596858639,3490,107.835443960089 -06/19/2017,214,8534.008,39.8785420560748,2586,92.7627959733928 -06/20/2017,248,9900.52,39.9214516129032,2336,92.6286293067261 -06/21/2017,218,8700.277,39.9095275229358,4325,92.7993868833928 -06/22/2017,303,12077.315,39.8591254125413,2781,107.835443960089 -06/23/2017,391,15746.597,40.2726265984655,2538,63.02 -06/24/2017,213,8596.265,40.3580516431925,2133,107.835443960089 -06/25/2017,182,7367.257,40.4794340659341,2332,107.835443960089 -06/26/2017,302,12386.278,41.0141655629139,2459,92.8635229233928 -06/27/2017,207,8502.284,41.0738357487923,2392,62.50532787 -06/28/2017,209,8709.028,41.669990430622,2594,107.835443960089 -06/29/2017,193,8113.113,42.0368549222798,2617,63.02 -06/30/2017,153,6434.957,42.0585424836601,2331,63.02 -07/01/2017,144,6030.386,41.8776805555556,2421,107.835443960089 -07/02/2017,85,3529.386,41.5221882352941,2237,107.835443960089 -07/03/2017,128,5291.125,41.3369140625,2256,65.151884375 -07/04/2017,168,6929.476,41.2468809523809,2258,92.7225459733928 -07/05/2017,94,3860.778,41.0721063829787,2157,107.835443960089 -07/06/2017,103,4210.848,40.8820194174757,2048,107.835443960089 -07/07/2017,185,7592.528,41.0406918918919,2135,107.835443960089 -07/08/2017,97,3945.699,40.6773092783505,2135,107.835443960089 -07/09/2017,123,4998.921,40.6416341463415,2174,107.835443960089 -07/10/2017,136,5555.909,40.8522720588235,3461,107.835443960089 -07/11/2017,183,7408.934,40.4859781420765,7176,62.595384615 -07/12/2017,1592,63833.704,40.0965477386935,7168,51.98 -07/13/2017,1306,52286.549,40.0356424196018,8654,51.98 -07/14/2017,1632,65184.244,39.9413259803922,9779,51.98 -07/15/2017,1411,56388.283,39.9633472714387,8327,51.98 -07/16/2017,848,33863.934,39.9338844339623,7478,51.98 -07/17/2017,1619,64557.749,39.875076590488,8565,51.98 -07/18/2017,1265,50470.759,39.897833201581,7459,51.98 -07/19/2017,1277,50929.072,39.8818104933438,7278,51.98 -07/20/2017,1500,59814.049,39.8760326666667,6445,51.98 -07/21/2017,1915,76286.889,39.8364955613577,7098,51.98 -07/22/2017,1545,61538.171,39.8305313915858,5551,51.98 -07/23/2017,1371,54612.731,39.834231218089,4180,51.98 -07/24/2017,1701,67741.369,39.8244379776602,3907,51.98 -07/25/2017,1432,57021.207,39.8192786312849,3650,51.98 -07/26/2017,318,12781.842,40.1944716981132,3644,92.7452959733927 -07/27/2017,371,14902.618,40.168781671159,3464,92.8342763667261 -07/28/2017,398,16015.209,40.2392185929648,3221,107.835443960089 -07/29/2017,262,10587.207,40.4091870229008,2959,107.835443960089 -07/30/2017,185,7455.474,40.2998594594595,2774,107.835443960089 -07/31/2017,239,9646.362,40.3613472803347,2663,92.8177895633928 -08/01/2017,255,10256.54,40.2217254901961,2333,92.8039404167261 -08/02/2017,278,11319.987,40.7193776978417,2399,107.835443960089 -08/03/2017,309,12726.702,41.1867378640777,1972,107.835443960089 -08/04/2017,325,13382.205,41.1760153846154,1805,92.7796910367261 -08/05/2017,245,10138.619,41.3821183673469,1533,107.835443960089 -08/06/2017,160,6600.458,41.2528625,1411,107.835443960089 -08/07/2017,227,9476.837,41.7481806167401,2655,107.835443960089 -08/08/2017,215,8953.562,41.6444744186047,2089,107.835443960089 -08/09/2017,171,7188.559,42.0383567251462,3731,107.835443960089 -08/10/2017,229,9668.716,42.2214672489083,2328,63.02 -08/11/2017,221,9357.258,42.3405339366516,2454,63.02 -08/12/2017,197,8299.478,42.1293299492386,2256,63.02 -08/13/2017,130,5495.347,42.2719,2126,63.02 -08/14/2017,211,8985.055,42.5831990521327,2259,63.02 -08/15/2017,202,8567.05,42.4111386138614,2362,62.723875 -08/16/2017,160,6810.689,42.56680625,2751,107.835443960089 -08/17/2017,195,8293.931,42.5329794871795,2590,62.6439682533333 -08/18/2017,200,8509.278,42.54639,2562,92.8411493067261 -08/19/2017,202,8623.633,42.6912524752475,2353,63.02 -08/20/2017,159,6785.075,42.673427672956,2191,63.02 -08/21/2017,175,7445.819,42.5475371428571,2005,63.02 -08/22/2017,195,8297.547,42.5515230769231,1804,63.02 -08/23/2017,216,9221.763,42.6933472222222,2486,107.835443960089 -08/24/2017,283,12071.587,42.6557844522968,2378,92.8610023233928 -08/25/2017,307,13133.25,42.7793159609121,2516,107.835443960089 -08/26/2017,197,8430.243,42.7931116751269,2313,92.8613126400594 -08/27/2017,170,7267.621,42.7507117647059,2867,92.7533868833928 -08/28/2017,202,8665.418,42.8981089108911,2473,63.02 -08/29/2017,168,7183.898,42.7612976190476,2372,63.02 -08/30/2017,248,10612.125,42.7908266129032,2266,63.02 -08/31/2017,302,12970.226,42.9477682119205,2302,63.02 -09/01/2017,308,13242.006,42.993525974026,2158,63.02 -09/02/2017,269,11570.245,43.012063197026,1883,63.02 -09/03/2017,224,9631.855,42.9993526785714,1659,62.590163935 -09/04/2017,224,9612.973,42.9150580357143,1869,85.1883282650446 -09/05/2017,222,9535.506,42.9527297297297,1934,63.02 -09/06/2017,329,14152.03,43.0152887537994,1779,63.02 -09/07/2017,341,14682.012,43.0557536656892,2025,62.4709412125 -09/08/2017,384,16529.168,43.0447083333333,1721,63.02 -09/09/2017,183,7880.352,43.0620327868853,1535,92.3591164867261 -09/10/2017,234,10068.952,43.0297094017094,1298,92.3507126400594 -09/11/2017,247,10635.629,43.0592267206478,1676,92.8282959733928 -09/12/2017,291,12535.347,43.076793814433,2698,107.835443960089 -09/13/2017,292,12581.728,43.0881095890411,1863,63.02 -09/14/2017,279,12022.346,43.0908458781362,1820,62.8843 -09/15/2017,327,14089.953,43.0885412844037,2021,63.02 -09/16/2017,290,12490.764,43.0716,1728,60.319142855 -09/17/2017,208,8960.449,43.0790817307692,1517,62.33 -09/18/2017,237,10213.395,43.0944936708861,1897,63.02 -09/19/2017,227,9784.746,43.1046079295154,1756,63.02 -09/20/2017,302,13016.996,43.1026357615894,1811,63.02 -09/21/2017,276,11898.642,43.1110217391304,1890,63.02 -09/22/2017,305,13149.681,43.1137081967213,2375,62.92524 -09/23/2017,342,14743.873,43.1107397660819,2028,62.938310345 -09/24/2017,228,9829.763,43.1129956140351,1801,62.37787755 -09/25/2017,214,9221.229,43.0898551401869,1752,63.02 -09/26/2017,315,13538.112,42.9781333333333,2415,62.95657576 -09/27/2017,294,12631.024,42.9626666666667,678,62.96487931 -09/28/2017,0,0,42.931957957958,4005,152.650887920178 -09/29/2017,333,14296.342,42.931957957958,2261,62.81024 -09/30/2017,220,9445.945,42.9361136363636,2035,63.02 -10/01/2017,147,6310.564,42.9290068027211,1885,108.985443960089 -10/02/2017,191,8190.616,42.8828062827225,3380,108.985443960089 -10/03/2017,288,12334.398,42.8277708333333,7408,65.32 -10/04/2017,2103,90062.746,42.8258421302901,6602,54.74 -10/05/2017,1431,61270.458,42.8165324947589,8231,54.74 -10/06/2017,1572,67299.886,42.8116323155216,9577,54.74 -10/07/2017,1644,70378.079,42.809050486618,7920,54.74 -10/08/2017,1046,44784.743,42.815241873805,6860,54.74 -10/09/2017,1211,51841.537,42.8088662262593,7308,103.695443960089 -10/10/2017,1299,55606.976,42.8075257890685,6783,103.695443960089 -10/11/2017,1373,58774.558,42.8073983976693,7209,103.695443960089 -10/12/2017,1374,58817.494,42.8074919941776,6369,54.74 -10/13/2017,1690,72341.95,42.8058875739645,5794,54.74 -10/14/2017,1141,48841.882,42.8062068361087,5235,54.74 -10/15/2017,1053,45078.95,42.8100189933523,3978,54.74 -10/16/2017,1145,49010.384,42.8038288209607,4649,54.74 -10/17/2017,1278,54705.786,42.805779342723,4129,54.74 -10/18/2017,157,6750.396,42.996152866242,4148,65.32 -10/19/2017,151,6497.754,43.0314834437086,3993,66.33309524 -10/20/2017,221,9489.569,42.9392262443439,4100,68.00736842 -10/21/2017,143,6163.539,43.1016713286713,3956,66.672 -10/22/2017,118,5095.904,43.1856271186441,3837,95.8486293067261 -10/23/2017,134,5793.803,43.2373358208955,3947,88.9256386475446 -10/24/2017,105,4530.957,43.1519714285714,3835,62.33 -10/25/2017,141,6088.645,43.1818794326241,3855,95.8486293067261 -10/26/2017,140,6044.189,43.1727785714286,3700,67.4475 -10/27/2017,215,9275.179,43.1403674418605,0,67.4475 -10/28/2017,0,0,43.5072777777778,6910,152.650887920178 -10/29/2017,162,7048.179,43.5072777777778,3168,67.4475 -10/30/2017,115,4986.981,43.365052173913,3050,87.9965344800446 -10/31/2017,99,4296.642,43.4004242424243,3151,95.8486293067261 -11/01/2017,147,6415.192,43.6407619047619,3024,67.4475 -11/02/2017,164,7150.652,43.6015365853659,2946,67.4475 -11/03/2017,212,9282.983,43.7876556603774,3079,67.4475 -11/04/2017,177,7761.292,43.8491073446328,2899,67.4475 -11/05/2017,137,6001.851,43.8091313868613,2762,67.4475 -11/06/2017,148,6440.734,43.518472972973,2781,67.4475 -11/07/2017,154,6704.156,43.5334805194805,2772,67.4475 -11/08/2017,148,6428.351,43.4348040540541,2605,67.4475 -11/09/2017,208,9027.142,43.3997211538462,2395,67.4475 -11/10/2017,220,9537.216,43.3509818181818,2525,66.212023275 -11/11/2017,176,7625.437,43.3263465909091,2351,67.4475 -11/12/2017,123,5316.449,43.223162601626,2228,88.1533369800446 -11/13/2017,117,5041.355,43.0885042735043,3280,88.1459719800445 -11/14/2017,170,7304.779,42.9692882352941,6695,67.4475 -11/15/2017,1352,58169.635,43.0248779585799,5710,54.74 -11/16/2017,1455,62329.123,42.8378852233677,9924,103.695443960089 -11/17/2017,838,35895.753,42.8350274463007,8832,54.74 -11/18/2017,1055,45200.645,42.8442132701422,8042,103.695443960089 -11/19/2017,924,39586.055,42.8420508658009,7012,103.695443960089 -11/20/2017,1031,44163.348,42.8354490785645,7255,54.74 -11/21/2017,1102,47202.729,42.8336923774955,7236,54.74 -11/22/2017,985,42192.024,42.8345421319797,6402,54.74 -11/23/2017,900,38543.506,42.8261177777778,6029,54.74 -11/24/2017,1281,54852.794,42.8202919594067,5803,54.74 -11/25/2017,1032,44193.38,42.8230426356589,4747,54.74 -11/26/2017,814,34859.275,42.8246621621622,3943,54.74 -11/27/2017,657,28136.798,42.8261765601218,3878,103.695443960089 -11/28/2017,783,33527.082,42.8187509578544,3684,103.695443960089 -11/29/2017,212,9093.485,42.8937971698113,3568,83.3611775840356 -11/30/2017,246,10553.893,42.9020040650406,3538,78.0323283100255 -12/01/2017,240,10305.775,42.9407291666667,3122,81.4544813200297 diff --git a/data/input/test_time_series.xlsx b/data/input/test_time_series.xlsx index 7981ed7..d9b3d0b 100644 Binary files a/data/input/test_time_series.xlsx and b/data/input/test_time_series.xlsx differ diff --git a/data/input/test_ts_passengers.csv b/data/input/test_ts_passengers.csv deleted file mode 100644 index 0ba6bd0..0000000 --- a/data/input/test_ts_passengers.csv +++ /dev/null @@ -1,145 +0,0 @@ -Month,Passengers -1949-01,112 -1949-02,118 -1949-03,132 -1949-04,129 -1949-05,121 -1949-06,135 -1949-07,148 -1949-08,148 -1949-09,136 -1949-10,119 -1949-11,104 -1949-12,118 -1950-01,115 -1950-02,126 -1950-03,141 -1950-04,135 -1950-05,125 -1950-06,149 -1950-07,170 -1950-08,170 -1950-09,158 -1950-10,133 -1950-11,114 -1950-12,140 -1951-01,145 -1951-02,150 -1951-03,178 -1951-04,163 -1951-05,172 -1951-06,178 -1951-07,199 -1951-08,199 -1951-09,184 -1951-10,162 -1951-11,146 -1951-12,166 -1952-01,171 -1952-02,180 -1952-03,193 -1952-04,181 -1952-05,183 -1952-06,218 -1952-07,230 -1952-08,242 -1952-09,209 -1952-10,191 -1952-11,172 -1952-12,194 -1953-01,196 -1953-02,196 -1953-03,236 -1953-04,235 -1953-05,229 -1953-06,243 -1953-07,264 -1953-08,272 -1953-09,237 -1953-10,211 -1953-11,180 -1953-12,201 -1954-01,204 -1954-02,188 -1954-03,235 -1954-04,227 -1954-05,234 -1954-06,264 -1954-07,302 -1954-08,293 -1954-09,259 -1954-10,229 -1954-11,203 -1954-12,229 -1955-01,242 -1955-02,233 -1955-03,267 -1955-04,269 -1955-05,270 -1955-06,315 -1955-07,364 -1955-08,347 -1955-09,312 -1955-10,274 -1955-11,237 -1955-12,278 -1956-01,284 -1956-02,277 -1956-03,317 -1956-04,313 -1956-05,318 -1956-06,374 -1956-07,413 -1956-08,405 -1956-09,355 -1956-10,306 -1956-11,271 -1956-12,306 -1957-01,315 -1957-02,301 -1957-03,356 -1957-04,348 -1957-05,355 -1957-06,422 -1957-07,465 -1957-08,467 -1957-09,404 -1957-10,347 -1957-11,305 -1957-12,336 -1958-01,340 -1958-02,318 -1958-03,362 -1958-04,348 -1958-05,363 -1958-06,435 -1958-07,491 -1958-08,505 -1958-09,404 -1958-10,359 -1958-11,310 -1958-12,337 -1959-01,360 -1959-02,342 -1959-03,406 -1959-04,396 -1959-05,420 -1959-06,472 -1959-07,548 -1959-08,559 -1959-09,463 -1959-10,407 -1959-11,362 -1959-12,405 -1960-01,417 -1960-02,391 -1960-03,419 -1960-04,461 -1960-05,472 -1960-06,535 -1960-07,622 -1960-08,606 -1960-09,508 -1960-10,461 -1960-11,390 -1960-12,432 diff --git a/logs/cov.out b/logs/cov.out index 99bc335..345a9de 100644 --- a/logs/cov.out +++ b/logs/cov.out @@ -1,12 +1,12 @@ -Name Stmts Miss Cover Missing -------------------------------------------------------- -mllib/__init__.py 7 0 100% -mllib/lib/__init__.py 7 0 100% -mllib/lib/cluster.py 103 0 100% -mllib/lib/knn.py 70 0 100% -mllib/lib/model.py 44 0 100% -mllib/lib/opt.py 157 0 100% -mllib/lib/timeseries.py 85 0 100% -mllib/lib/tree.py 79 0 100% -------------------------------------------------------- -TOTAL 552 0 100% +Name Stmts Miss Cover Missing +--------------------------------------------------------------------------------------------- +/media/ph33r/Data/Project/CodeLib/Git/mllib/__init__.py 7 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/__init__.py 7 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/cluster.py 103 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/knn.py 70 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/model.py 44 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/opt.py 157 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/timeseries.py 61 0 100% +/media/ph33r/Data/Project/CodeLib/Git/mllib/lib/tree.py 79 0 100% +--------------------------------------------------------------------------------------------- +TOTAL 528 0 100% diff --git a/logs/pip.out b/logs/pip.out index 03fb79a..27f1fe1 100644 --- a/logs/pip.out +++ b/logs/pip.out @@ -1 +1 @@ -./bin/run_tests.sh: line 78: pipreqs: command not found +INFO: Successfully saved requirements file in /media/ph33r/Data/Project/CodeLib/Git/requirements.txt diff --git a/logs/pylint/lib-timeseries-py.out b/logs/pylint/lib-timeseries-py.out index e6474ef..ec79001 100644 --- a/logs/pylint/lib-timeseries-py.out +++ b/logs/pylint/lib-timeseries-py.out @@ -1,8 +1,8 @@ ************* Module mllib.lib.timeseries -timeseries.py:188:41: I1101: Module 'metrics' has no 'rsq' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) -timeseries.py:189:41: I1101: Module 'metrics' has no 'mae' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) -timeseries.py:190:42: I1101: Module 'metrics' has no 'mape' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) -timeseries.py:191:42: I1101: Module 'metrics' has no 'rmse' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +timeseries.py:208:41: I1101: Module 'metrics' has no 'rsq' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +timeseries.py:209:41: I1101: Module 'metrics' has no 'mae' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +timeseries.py:210:42: I1101: Module 'metrics' has no 'mape' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +timeseries.py:211:42: I1101: Module 'metrics' has no 'rmse' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) -------------------------------------------------------------------- Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) diff --git a/logs/pylint/tests-test_metrics-py.out b/logs/pylint/tests-test_metrics-py.out index d40a4ad..10dc202 100644 --- a/logs/pylint/tests-test_metrics-py.out +++ b/logs/pylint/tests-test_metrics-py.out @@ -4,6 +4,7 @@ test_metrics.py:69:22: I1101: Module 'mllib.lib.metrics' has no 'mse' member, bu test_metrics.py:77:22: I1101: Module 'mllib.lib.metrics' has no 'rmse' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) test_metrics.py:85:22: I1101: Module 'mllib.lib.metrics' has no 'mae' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) test_metrics.py:93:22: I1101: Module 'mllib.lib.metrics' has no 'mape' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +test_metrics.py:101:22: I1101: Module 'mllib.lib.metrics' has no 'aic' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) -------------------------------------------------------------------- Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) diff --git a/mllib/__main__.py b/mllib/__main__.py index 22414a6..c15175e 100644 --- a/mllib/__main__.py +++ b/mllib/__main__.py @@ -33,7 +33,7 @@ from lib.tree import XGBoost # noqa: F841 from lib.opt import TSP # noqa: F841 from lib.opt import Transport # noqa: F841 -from lib.timeseries import TimeSeries # noqa: F841 +from lib.timeseries import AutoArima # noqa: F841 # ============================================================================= # --- DO NOT CHANGE ANYTHING FROM HERE @@ -64,7 +64,6 @@ args = CLI.parse_args() fn_ip = args.filename[0] -fn_ip = "iris.csv" # ============================================================================= # --- Main @@ -72,12 +71,22 @@ if __name__ == '__main__': start = time.time_ns() + # --- KNN + start_t = time.time_ns() + df_ip = pd.read_csv(path + "input/iris.csv") + mod = KNN(df_ip, "y", ["x1", "x2", "x3", "x4"], method="classify") + print("KNN\n") + for k, v in mod.model_summary.items(): + print(k, str(v).rjust(69 - len(k))) + print(elapsed_time("Time", start_t), + sep, + sep="\n") # --- Clustering start_t = time.time_ns() df_ip = pd.read_csv(path + "input/" + fn_ip) clus_sol = Cluster(df=df_ip, x_var=["x1"]) clus_sol.opt_k() - print("Clustering\n", + print("\nClustering\n", "optimal k = " + str(clus_sol.optimal_k), elapsed_time("Time", start_t), sep, @@ -94,16 +103,6 @@ print(elapsed_time("Time", start_t), sep, sep="\n") - # --- KNN - start_t = time.time_ns() - df_ip = pd.read_csv(path + "input/iris.csv") - mod = KNN(df_ip, "y", ["x1", "x2", "x3", "x4"], method="classify") - print("\nKNN\n") - for k, v in mod.model_summary.items(): - print(k, str(v).rjust(69 - len(k))) - print(elapsed_time("Time", start_t), - sep, - sep="\n") # --- Random forest start_t = time.time_ns() df_ip = pd.read_csv(path + "input/iris.csv") @@ -158,14 +157,13 @@ # --- Time series start_t = time.time_ns() df_ip = pd.read_excel(path + "input/test_time_series.xlsx", - sheet_name="product_01") - mod = TimeSeries(df=df_ip, - y_var="y", - x_var=["cost", "stock_level", "retail_price"], - ds="ds") - op = mod.model_summary + sheet_name="exog") + df_ip = df_ip.set_index("ts") + mod = AutoArima(df=df_ip, y_var="y", x_var=["cost"]) + op = mod.metrics print("\nTime series\n") - print("R-squared:", op["rsq"]) + for k, v in op.items(): + print(k, str(v).rjust(69 - len(k))) print(elapsed_time("Time", start_t), sep, sep="\n") diff --git a/mllib/lib/metrics.so b/mllib/lib/metrics.so index c972ad9..da0163e 100644 Binary files a/mllib/lib/metrics.so and b/mllib/lib/metrics.so differ diff --git a/mllib/lib/timeseries.py b/mllib/lib/timeseries.py index fd1dffe..372d3ca 100644 --- a/mllib/lib/timeseries.py +++ b/mllib/lib/timeseries.py @@ -3,7 +3,7 @@ **Available routines:** -- class ``TimeSeries``: Builds time series model using fbprophet. +- class ``AutoArima``: Builds time series model using SARIMAX. Credits ------- @@ -13,26 +13,27 @@ - Diptesh - Madhu - Date: Oct 03, 2021 + Date: Dec 31, 2021 """ # pylint: disable=invalid-name -# pylint: disable=R0902,R0903,R0913,C0413,R0205 +# pylint: disable=wrong-import-position +# pylint: disable=R0902,R0903,W0511 -from typing import List, Dict, Any +from inspect import getsourcefile +from os.path import abspath + +from typing import Dict, List import re import sys -import os - -from inspect import getsourcefile -from os.path import abspath import pandas as pd import numpy as np -import pystan -from fbprophet import Prophet +import pmdarima as pm + +from statsmodels.tsa.seasonal import seasonal_decompose path = abspath(getsourcefile(lambda: 0)) path = re.sub(r"(.+\/)(.+.py)", "\\1", path) @@ -40,55 +41,20 @@ import metrics # noqa: F841 -__all__ = ["pystan", ] +# ============================================================================= +# --- +# ============================================================================= -os.environ['NUMEXPR_MAX_THREADS'] = '8' - -class suppress_stdout_stderr(object): - """ - Suppress fbprophet stdout. - - 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): - """Initialize variables.""" - # 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): - """Enter statements.""" - # 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, *_): - """Exit statements.""" - # 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]) - - -class TimeSeries(): - """Time series module. +class AutoArima(): + """Auto ARIMA time series module. Parameters ---------- df: pandas.DataFrame - Pandas dataframe containing the `y_var`, `ds` and `x_var` + Pandas dataframe containing the `y_var` and optinal `x_var`. The index + **must** be a datetime with no missing periods. y_var: str @@ -98,21 +64,21 @@ class TimeSeries(): Independant variables (the default is None). - ds: str, optional + params: dict, optional - Column name of the date variable (the default is None). + Time series parameters (the default is None). If no parameters are + passed the following is set as parameters:: - k_fold: int, optional, Not implemented yet - - Number of cross validations folds (the default is None). - - uid: str, optional, Not implemented yet - - Description of parameter `uid` (the default is None). - - param: dict, optional, Not implemented yet - - Time series parameters (the default is None). + max_p: 15, + max_d: 2, + max_q: 15, + max_P: 15, + max_D: 2, + max_Q: 15, + seasonal: seasonal, + m: m, + threshold: 0.05, + debug: False Returns ------- @@ -120,22 +86,29 @@ class TimeSeries(): Final optimal model. - model_summary: Dict + metrics: Dict - Model summary containing key metrics like R-squared, RMSE, MSE, MAE, + Model metrics containing key metrics like R-squared, RMSE, MSE, MAE, MAPE. + model_summary: object + + Model summary with optimal parameters. + + y_hat: list + + Predicted values for the orginal data. + Methods ------- predict Example ------- - >> > mod = TimeSeries(df=df_ip, - y_var="y", - x_var=["cost", "stock_level", "retail_price"], - ds="ds") - >> > df_op = mod.predict(x_predict) + >>> mod = AutoArima(df=df_ip, + y_var="y", + x_var=["cost", "stock_level", "retail_price"]) + >>> df_op = mod.predict(x_predict) """ @@ -143,150 +116,102 @@ def __init__(self, df: pd.DataFrame, y_var: str, x_var: List[str] = None, - ds: str = "ds", - k_fold: int = None, - uid: str = None, - param: Dict = None): + params: Dict[str, object] = None + ): """Initialize variables.""" + self.df = df self.y_var = y_var self.x_var = x_var - self.ds = ds - self.df = df.reset_index(drop=True) - if uid is not None: - raise NotImplementedError("uid is not supported yet") - if k_fold is not None: - raise NotImplementedError("k_fold is not supported yet") - if param is None: - param = {"interval_width": 0.95} - self.model = None + self.params = params + self.y_hat = None self.model_summary = None - self.param = param - self._pre_processing() - self._fit() - self._compute_metrics() - if x_var is not None: - self.betas = self._regressor_coefficients(self.model) - - def _pre_processing(self): - self.df[self.ds] = pd.to_datetime(self.df[self.ds]) + # Set default parameters + if self.params is None: + self.params = self._seasonality() + # Build optimal model + self.model = self._opt_params() + self.opt_params = self.model.to_dict() + # Compute metrics + self.metrics = self._compute_metrics() + # Model summary + self.model_summary = self.model.summary() + + def _seasonality(self) -> Dict[str, object]: + """Determine seasonality and return parameters.""" + decomposition = seasonal_decompose(self.df[self.y_var], + model="additive") + _seasonal = decomposition.seasonal + freq = _seasonal.value_counts() + m = int(np.ceil(len(self.df) / freq.iloc[0])) + seasonal = True + if m < 2: # pragma: no cover + seasonal = False + params = {"max_p": 15, + "max_d": 2, + "max_q": 15, + "max_P": 15, + "max_D": 2, + "max_Q": 15, + "seasonal": seasonal, + "m": m, + "threshold": 0.05, + "debug": False} + return params + + def _opt_params(self) -> object: if self.x_var is None: - self.df = self.df[[self.ds] + [self.y_var]] + model = pm.auto_arima(y=self.df[[self.y_var]], + start_p=0, + max_p=self.params["max_p"], + max_d=self.params["max_d"], + start_q=0, + max_q=self.params["max_q"], + start_P=0, + max_P=self.params["max_P"], + max_D=self.params["max_D"], + start_Q=0, + max_Q=self.params["max_Q"], + information_criterion="aicc", + alpha=self.params["threshold"], + trace=self.params["debug"], + seasonal=self.params["seasonal"], + m=self.params["m"]) else: - self.df = self.df[[self.ds] + [self.y_var] + self.x_var] - coln = list(self.df.columns) - self.df.columns = ["ds", "y"] + coln[2:] - self.y_var = "y" - self.ds = "ds" - - def _compute_metrics(self): + model = pm.auto_arima(y=self.df[[self.y_var]], + X=self.df[self.x_var], + start_p=0, + max_p=self.params["max_p"], + max_d=self.params["max_d"], + start_q=0, + max_q=self.params["max_q"], + start_P=0, + max_P=self.params["max_P"], + max_D=self.params["max_D"], + start_Q=0, + max_Q=self.params["max_Q"], + information_criterion="aicc", + alpha=self.params["threshold"], + trace=self.params["debug"], + seasonal=self.params["seasonal"], + m=self.params["m"]) + return model + + def _compute_metrics(self) -> Dict[str, float]: """Compute commonly used metrics to evaluate the model.""" - y = self.df.loc[:, self.y_var].values.tolist() + y = self.df[[self.y_var]].iloc[:, 0].values.tolist() if self.x_var is None: - y_hat = list(self.model.predict(self.df[[self.ds]])["yhat"]) + d = self.opt_params["order"][1] + y_hat = list(self.model.predict_in_sample(start=d, + end=len(self.df))) else: - y_hat = list(self.model.predict(self.df[[self.ds] - + self.x_var])["yhat"]) + y_hat = list(self.predict(self.df[self.x_var])[self.y_var].values) model_summary = {"rsq": np.round(metrics.rsq(y, y_hat), 3), "mae": np.round(metrics.mae(y, y_hat), 3), "mape": np.round(metrics.mape(y, y_hat), 3), "rmse": np.round(metrics.rmse(y, y_hat), 3)} model_summary["mse"] = np.round(model_summary["rmse"] ** 2, 3) - self.model_summary = model_summary - - @staticmethod - def _regressor_index(m, name): - """ - Given the name of a regressor, return its index in the `beta` matrix. - - Parameters - ---------- - m: object - - Prophet model object, after fitting. - - name: str - - Name of the regressor, as passed into the `add_regressor` function. - - Returns - ------- - int - - The column index of the regressor in the `beta` matrix. - - """ - op = np.extract(m.train_component_cols[name] == 1, - m.train_component_cols.index)[0] - return op - - def _regressor_coefficients(self, m): # pragma: no cover - """ - Summarise the coefficients of the extra regressors used in the model. - - For additive regressors, the coefficient represents the incremental - impact on `y` of a unit increase in the regressor. For multiplicative - regressors, the incremental impact is equal to `trend(t)` multiplied - by the coefficient. - - Coefficients are measured on the original scale of the training data. - - Parameters - ---------- - m: object - - Prophet model object, after fitting. - - Returns - ------- - pd.DataFrame - - containing: : - - regressor: Name of the regressor - regressor_mode: Additive/multiplicative effect on y - center: The mean of the regressor if standardized else 0 - coef_lower: Lower bound for the coefficient - coef: Expected value of the coefficient - coef_upper: Upper bound for the coefficient - - coef_lower/upper are estimated from MCMC samples. - It is only different to coef if mcmc_samples > 0. - - """ - assert len(m.extra_regressors) > 0, 'No extra regressors found.' - coefs = [] - for regressor, params in m.extra_regressors.items(): - beta = m.params['beta'][:, self._regressor_index(m, regressor)] - if params['mode'] == 'additive': - coef = beta * m.y_scale / params['std'] - else: - coef = beta / params['std'] - percentiles = [ - (1 - m.interval_width) / 2, - 1 - (1 - m.interval_width) / 2, - ] - coef_bounds = np.quantile(coef, q=percentiles) - record = { - 'regressor': regressor, - 'regressor_mode': params['mode'], - 'center': params['mu'], - 'coef_lower': coef_bounds[0], - 'coef': np.mean(coef), - 'coef_upper': coef_bounds[1], - } - coefs.append(record) - return pd.DataFrame(coefs) - - def _fit(self) -> Dict[str, Any]: - """Fit model.""" - with suppress_stdout_stderr(): - model = Prophet(interval_width=self.param["interval_width"]) - if self.x_var is not None: - for var in self.x_var: - model.add_regressor(var) - with suppress_stdout_stderr(): - model.fit(self.df) - self.model = model + self.y_hat = y_hat + return model_summary def predict(self, x_predict: pd.DataFrame = None, @@ -297,7 +222,7 @@ def predict(self, ---------- x_predict : pd.DataFrame, optional - Pandas dataframe containing `ds` and `x_var` (the default is None). + Pandas dataframe containing `x_var` (the default is None). n_interval : int, optional @@ -307,14 +232,24 @@ def predict(self, ------- pd.DataFrame - Pandas dataframe containing `y_var`, `ds` and `x_var`. + Pandas dataframe containing `y_var` and `x_var` (optional). """ if self.x_var is None: - x_predict = self.model.make_future_dataframe(periods=n_interval) - x_predict = x_predict.iloc[-n_interval:, :] - df_op = x_predict.copy(deep=True) - forecast = self.model.predict(x_predict) - y_hat = forecast['yhat'].values.tolist() - df_op.insert(loc=0, column=self.y_var, value=y_hat) - return df_op + df_pred = self.model.predict(n_periods=n_interval, + alpha=self.params["threshold"], + return_conf_int=False) + df_pred = pd.DataFrame(df_pred) + df_pred.columns = [self.y_var] + else: + n_interval = x_predict.shape[0] + df_pred = self.model.predict(n_periods=n_interval, + X=x_predict, + alpha=self.params["threshold"], + return_conf_int=False) + df_pred = pd.DataFrame(df_pred) + df_pred = pd.concat([df_pred, x_predict.reset_index(drop=True)], + axis=1, + ignore_index=True) + df_pred.columns = list(self.y_var) + self.x_var + return df_pred diff --git a/requirements.txt b/requirements.txt index e7948ab..0fb8a4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,9 @@ +pandas==1.0.1 +statsmodels==0.11.0 +xlrd==1.2.0 +numpy==1.18.1 +pmdarima==1.8.0 +xgboost==1.5.0 Cython==0.29.15 PuLP==1.6.8 -fbprophet==0.6 -numpy==1.18.1 -pandas==1.0.1 -xgboost==1.3.3 -pystan==2.17.1.0 -scikit_learn==1.0 +scikit_learn==1.0.2 diff --git a/tests/test_cluster.py b/tests/test_cluster.py index f14e30b..f31a160 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -60,7 +60,7 @@ def setUp(self): """Set up for module ``metric``.""" def test_categorical(self): - """Cluster: Test for categorical variables.""" + """Cluster: Test for categorical variables""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x1"], max_cluster=6, @@ -70,7 +70,7 @@ def test_categorical(self): self.assertEqual(clus_sol.method, "gap_max") def test_categorical_multiple(self): - """Cluster: Test for multiple categorical variables.""" + """Cluster: Test for multiple categorical variables""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x1", "x4"], max_cluster=10, @@ -80,7 +80,7 @@ def test_categorical_multiple(self): self.assertEqual(clus_sol.method, "gap_max") def test_categorical_continuos(self): - """Cluster: Test for categorical and continuos variables.""" + """Cluster: Test for categorical and continuos variables""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x1", "x2"], max_cluster=6, @@ -90,7 +90,7 @@ def test_categorical_continuos(self): self.assertEqual(clus_sol.method, "gap_max") def test_continuos_gap_max(self): - """Cluster: Test for continuos variables gap_max.""" + """Cluster: Test for continuos variables gap_max""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x2"], max_cluster=5, @@ -101,7 +101,7 @@ def test_continuos_gap_max(self): self.assertEqual(clus_sol.method, "gap_max") def test_continuos_one_se(self): - """Cluster: Test for continuos variables one_se.""" + """Cluster: Test for continuos variables one_se""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x2", "x3"], max_cluster=3, @@ -111,7 +111,7 @@ def test_continuos_one_se(self): self.assertEqual(clus_sol.method, "one_se") def test_gap_max_less_max_clus(self): - """Cluster: Test for gap_max where optimal k < max_cluster.""" + """Cluster: Test for gap_max where optimal k < max_cluster""" df_ip = pd.read_csv(path + "test_cluster.csv") clus_sol = Cluster(df=df_ip, x_var=["x3"], max_cluster=3, diff --git a/tests/test_knn.py b/tests/test_knn.py index a4c0547..70a5f9d 100644 --- a/tests/test_knn.py +++ b/tests/test_knn.py @@ -64,7 +64,7 @@ def setUp(self): """Set up for module ``KNN``.""" def test_knn_class(self): - """KNN: Test for classification.""" + """KNN: Test for classification""" x_var = ["x1", "x2"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") @@ -81,7 +81,7 @@ def test_knn_class(self): @ignore_warnings def test_knn_reg(self): - """KNN: Test for regression.""" + """KNN: Test for regression""" x_var = ["x1", "x2"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") @@ -97,7 +97,7 @@ def test_knn_reg(self): self.assertLessEqual(mse, 0.1) def test_knn_cat(self): - """KNN: Test for one-hot encoding in prediction.""" + """KNN: Test for one-hot encoding in prediction""" x_var = ["x1", "x2"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 948bec4..3132a1d 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -54,7 +54,7 @@ def setUp(self): """Set up for module ``metrics``.""" def test_rsq(self): - """Metrics: Test for R-squared.""" + """Metrics: Test for R-squared""" y = [3, 8, 10, 17, 24, 27] y_hat = [2, 8, 10, 13, 18, 20] exp_op = 0.973 @@ -62,7 +62,7 @@ def test_rsq(self): self.assertEqual(op, exp_op) def test_mse(self): - """Metrics: Test for MSE.""" + """Metrics: Test for MSE""" y = [34, 37, 44, 47, 48, 48, 46, 43, 32, 27, 26, 24] y_hat = [37, 40, 46, 44, 46, 50, 45, 44, 34, 30, 22, 23] exp_op = 5.917 @@ -70,7 +70,7 @@ def test_mse(self): self.assertEqual(op, exp_op) def test_rmse(self): - """Metrics: Test for RMSE.""" + """Metrics: Test for RMSE""" y = [34, 37, 44, 47, 48, 48, 46, 43, 32, 27, 26, 24] y_hat = [37, 40, 46, 44, 46, 50, 45, 44, 34, 30, 22, 23] exp_op = 2.432 @@ -78,7 +78,7 @@ def test_rmse(self): self.assertEqual(op, exp_op) def test_mae(self): - """Metrics: Test for MAE.""" + """Metrics: Test for MAE""" y = [12, 13, 14, 15, 15, 22, 27] y_hat = [11, 13, 14, 14, 15, 16, 18] exp_op = 2.429 @@ -86,13 +86,21 @@ def test_mae(self): self.assertEqual(op, exp_op) def test_mape(self): - """Metrics: Test for MAPE.""" + """Metrics: Test for MAPE""" y = [34, 37, 44, 47, 48, 48, 46, 43, 32, 27, 26, 24] y_hat = [37, 40, 46, 44, 46, 50, 45, 44, 34, 30, 22, 23] exp_op = 0.065 op = np.round(metrics.mape(y, y_hat), 3) self.assertEqual(op, exp_op) + def test_aic_linear(self): + """Metrics: Test for AIC in linear regression""" + y = [34, 37, 44, 47, 48, 48, 46, 43, 32, 27, 26, 24] + y_hat = [37, 40, 46, 44, 46, 50, 45, 44, 34, 30, 22, 23] + exp_op = -6.525 + op = np.round(metrics.aic(y, y_hat, k=1, method="linear"), 3) + self.assertEqual(op, exp_op) + # ============================================================================= # --- Main diff --git a/tests/test_model.py b/tests/test_model.py index a4c7ac1..e0c4cd7 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -61,7 +61,7 @@ def setUp(self): """Set up for module ``GLMNet``.""" def test_known_equation(self): - """GLMNet: Test a known equation.""" + """GLMNet: Test a known equation""" df_ip = pd.read_csv(path + "test_glmnet.csv") mod = GLMNet(df=df_ip, y_var="y", @@ -73,7 +73,7 @@ def test_known_equation(self): self.assertEqual(np.round(op.get('coef')[2], 0), 0.0) def test_predict_target_variable(self): - """GLMNet: Test to predict a target variable.""" + """GLMNet: Test to predict a target variable""" df_ip = pd.read_csv(path + "test_glmnet.csv") mod = GLMNet(df=df_ip, y_var="y", diff --git a/tests/test_timeseries.py b/tests/test_timeseries.py index 58a0bd9..e46fbfe 100644 --- a/tests/test_timeseries.py +++ b/tests/test_timeseries.py @@ -13,6 +13,7 @@ # pylint: disable=invalid-name # pylint: disable=wrong-import-position +# pylint: disable=W0511,W0611 import unittest import warnings @@ -23,6 +24,7 @@ from os.path import abspath import pandas as pd +import xlrd # Set base path path = abspath(getsourcefile(lambda: 0)) @@ -30,7 +32,9 @@ sys.path.insert(0, path) -from mllib.lib.timeseries import TimeSeries # noqa: F841 +from mllib.lib.timeseries import AutoArima # noqa: F841 + +__all__ = ["xlrd", ] # ============================================================================= # --- DO NOT CHANGE ANYTHING FROM HERE @@ -53,47 +57,32 @@ def do_test(self, *args, **kwargs): return do_test +# TODO: Change integration tests. class TestTimeSeries(unittest.TestCase): """Test suite for module ``TimeSeries``.""" def setUp(self): """Set up for module ``TimeSeries``.""" - @ignore_warnings def test_multivariate(self): - """TimeSeries: Test for multivariate.""" - df_ip = pd.read_csv(path + "test_time_series.csv") - mod = TimeSeries(df=df_ip, - y_var="y", - x_var=["cost", "stock_level", "retail_price"], - ds="ds") - op = mod.model_summary - self.assertAlmostEqual(0.99, op["rsq"], places=1) - - @ignore_warnings - def test_raise_exceptions(self): - """TimeSeries: Test raise exceptions.""" - df_ip = pd.read_csv(path + "test_time_series.csv") - self.assertRaises(NotImplementedError, TimeSeries, - df=df_ip, - y_var="y", - x_var=["stock_level", "retail_price"], - ds="ds", - uid="cost") - self.assertRaises(NotImplementedError, TimeSeries, - df=df_ip, - y_var="y", - x_var=["stock_level", "retail_price"], - ds="ds", - k_fold=5) - - @ignore_warnings + """TimeSeries: Test for multivariate""" + df_ip = pd.read_excel(path + "test_time_series.xlsx", + sheet_name="exog") + df_ip = df_ip.set_index("ts") + mod = AutoArima(df=df_ip, y_var="y", x_var=["cost"]) + op = mod.metrics + self.assertEqual(mod.opt_params["order"], (0, 1, 1)) + self.assertAlmostEqual(1.0, op["rsq"], places=1) + self.assertLessEqual(op["mape"], 0.1) + def test_univariate(self): - """TimeSeries: Test for univariate.""" - df_ip = pd.read_csv(path + "test_ts_passengers.csv") - mod = TimeSeries(df=df_ip, y_var="Passengers", ds="Month") + """TimeSeries: Test for univariate""" + df_ip = pd.read_excel(path + "test_time_series.xlsx", + sheet_name="endog") + df_ip = df_ip.set_index("ts") + mod = AutoArima(df=df_ip, y_var="Passengers") op = mod.predict() - self.assertAlmostEqual(op["y"].values[0], 446.911, places=1) + self.assertAlmostEqual(op["Passengers"].values[0], 445.634, places=1) # ============================================================================= diff --git a/tests/test_tree.py b/tests/test_tree.py index 5ae5fc2..016e8e9 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -65,7 +65,7 @@ def setUp(self): """Set up for module ``RandomForest``.""" def test_rf_class(self): - """RandomForest: Test for classification.""" + """RandomForest: Test for classification""" x_var = ["x1", "x2", "x3", "x4"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") @@ -82,7 +82,7 @@ def test_rf_class(self): @ignore_warnings def test_rf_reg(self): - """RandomForest: Test for regression.""" + """RandomForest: Test for regression""" x_var = ["x1", "x2", "x3", "x4"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") @@ -106,7 +106,7 @@ def setUp(self): @ignore_warnings def test_xgboost_class(self): - """XGBoost: Test for classification.""" + """XGBoost: Test for classification""" x_var = ["x1", "x2"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv") @@ -123,7 +123,7 @@ def test_xgboost_class(self): @ignore_warnings def test_xgboost_reg(self): - """XGBoost: Test for regression.""" + """XGBoost: Test for regression""" x_var = ["x1", "x2", "x3", "x4"] y_var = "y" df_ip = pd.read_csv(path + "iris.csv")