From aa4188cb8258e5f7b2636617fdd7bbfcfabbaa97 Mon Sep 17 00:00:00 2001 From: Hyunsung Lee Date: Wed, 2 Oct 2019 19:50:17 +0900 Subject: [PATCH] Add metric AUC@k (#275) * . * . * . --- implicit/evaluation.cpp | 2547 ++++++++++++++++++++++++++++++--------- implicit/evaluation.pyx | 94 ++ 2 files changed, 2055 insertions(+), 586 deletions(-) diff --git a/implicit/evaluation.cpp b/implicit/evaluation.cpp index cd631a44..b0d1076e 100644 --- a/implicit/evaluation.cpp +++ b/implicit/evaluation.cpp @@ -1,4 +1,4 @@ -/* Generated by Cython 0.29.8 */ +/* Generated by Cython 0.29.12 */ /* BEGIN: Cython Metadata { @@ -33,8 +33,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_29_8" -#define CYTHON_HEX_VERSION 0x001D08F0 +#define CYTHON_ABI "0_29_12" +#define CYTHON_HEX_VERSION 0x001D0CF0 #define CYTHON_FUTURE_DIVISION 1 #include #ifndef offsetof @@ -350,12 +350,12 @@ class __Pyx_FakeReference { #define __Pyx_DefaultClassType PyClass_Type #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX < 0x030800A4 +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #else #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #endif #define __Pyx_DefaultClassType PyType_Type #endif @@ -1187,7 +1187,7 @@ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, #define __Pyx_PyFunction_FastCall(func, args, nargs)\ __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) #if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs); +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif @@ -1862,6 +1862,7 @@ static const char __pyx_k_ap[] = "ap"; static const char __pyx_k_cg[] = "cg"; static const char __pyx_k_id[] = "id"; static const char __pyx_k_np[] = "np"; +static const char __pyx_k_auc[] = "__auc"; static const char __pyx_k_col[] = "col"; static const char __pyx_k_ids[] = "ids"; static const char __pyx_k_new[] = "__new__"; @@ -1873,6 +1874,7 @@ static const char __pyx_k_dict[] = "__dict__"; static const char __pyx_k_idcg[] = "idcg"; static const char __pyx_k_log2[] = "log2"; static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_miss[] = "__miss"; static const char __pyx_k_mode[] = "mode"; static const char __pyx_k_name[] = "name"; static const char __pyx_k_ndim[] = "ndim"; @@ -1884,11 +1886,13 @@ static const char __pyx_k_stop[] = "stop"; static const char __pyx_k_test[] = "test"; static const char __pyx_k_tqdm[] = "tqdm"; static const char __pyx_k_ASCII[] = "ASCII"; +static const char __pyx_k_auc_2[] = "auc"; static const char __pyx_k_class[] = "__class__"; static const char __pyx_k_close[] = "close"; static const char __pyx_k_dtype[] = "dtype"; static const char __pyx_k_error[] = "error"; static const char __pyx_k_flags[] = "flags"; +static const char __pyx_k_items[] = "items"; static const char __pyx_k_likes[] = "likes"; static const char __pyx_k_model[] = "model"; static const char __pyx_k_numpy[] = "numpy"; @@ -1921,7 +1925,9 @@ static const char __pyx_k_indices[] = "indices"; static const char __pyx_k_mean_ap[] = "mean_ap"; static const char __pyx_k_memview[] = "memview"; static const char __pyx_k_ratings[] = "ratings"; +static const char __pyx_k_AUC_at_k[] = "AUC_at_k"; static const char __pyx_k_Ellipsis[] = "Ellipsis"; +static const char __pyx_k_auc_list[] = "_auc_list"; static const char __pyx_k_getstate[] = "__getstate__"; static const char __pyx_k_itemsize[] = "itemsize"; static const char __pyx_k_progress[] = "progress"; @@ -1941,6 +1947,7 @@ static const char __pyx_k_coo_matrix[] = "coo_matrix"; static const char __pyx_k_csr_matrix[] = "csr_matrix"; static const char __pyx_k_pyx_result[] = "__pyx_result"; static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; +static const char __pyx_k_relevant_2[] = "__relevant"; static const char __pyx_k_test_index[] = "test_index"; static const char __pyx_k_MemoryError[] = "MemoryError"; static const char __pyx_k_PickleError[] = "PickleError"; @@ -1952,6 +1959,8 @@ static const char __pyx_k_random_index[] = "random_index"; static const char __pyx_k_scipy_sparse[] = "scipy.sparse"; static const char __pyx_k_stringsource[] = "stringsource"; static const char __pyx_k_test_indices[] = "test_indices"; +static const char __pyx_k_num_neg_items[] = "__num_neg_items"; +static const char __pyx_k_num_pos_items[] = "__num_pos_items"; static const char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; static const char __pyx_k_show_progress[] = "show_progress"; @@ -1996,6 +2005,7 @@ static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing ex static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; static PyObject *__pyx_n_s_ASCII; +static PyObject *__pyx_n_s_AUC_at_k; static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; static PyObject *__pyx_kp_s_Cannot_assign_to_read_only_memor; @@ -2023,6 +2033,9 @@ static PyObject *__pyx_n_s_View_MemoryView; static PyObject *__pyx_n_s_allocate_buffer; static PyObject *__pyx_n_s_ap; static PyObject *__pyx_n_s_arange; +static PyObject *__pyx_n_s_auc; +static PyObject *__pyx_n_s_auc_2; +static PyObject *__pyx_n_s_auc_list; static PyObject *__pyx_n_s_base; static PyObject *__pyx_n_s_c; static PyObject *__pyx_n_u_c; @@ -2061,6 +2074,7 @@ static PyObject *__pyx_kp_s_implicit_evaluation_pyx; static PyObject *__pyx_n_s_import; static PyObject *__pyx_n_s_indices; static PyObject *__pyx_n_s_indptr; +static PyObject *__pyx_n_s_items; static PyObject *__pyx_n_s_itemsize; static PyObject *__pyx_kp_s_itemsize_0_for_cython_array; static PyObject *__pyx_n_s_likes; @@ -2069,6 +2083,7 @@ static PyObject *__pyx_n_s_main; static PyObject *__pyx_n_s_mean_ap; static PyObject *__pyx_n_s_mean_average_precision_at_k; static PyObject *__pyx_n_s_memview; +static PyObject *__pyx_n_s_miss; static PyObject *__pyx_n_s_mode; static PyObject *__pyx_n_s_model; static PyObject *__pyx_n_s_name; @@ -2078,6 +2093,8 @@ static PyObject *__pyx_n_s_ndim; static PyObject *__pyx_n_s_new; static PyObject *__pyx_kp_s_no_default___reduce___due_to_non; static PyObject *__pyx_n_s_np; +static PyObject *__pyx_n_s_num_neg_items; +static PyObject *__pyx_n_s_num_pos_items; static PyObject *__pyx_n_s_num_threads; static PyObject *__pyx_n_s_numpy; static PyObject *__pyx_n_s_obj; @@ -2103,6 +2120,7 @@ static PyObject *__pyx_n_s_reduce; static PyObject *__pyx_n_s_reduce_cython; static PyObject *__pyx_n_s_reduce_ex; static PyObject *__pyx_n_s_relevant; +static PyObject *__pyx_n_s_relevant_2; static PyObject *__pyx_n_s_row; static PyObject *__pyx_n_s_scipy_sparse; static PyObject *__pyx_n_s_setstate; @@ -2144,6 +2162,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_model, PyObject *__pyx_v_train_user_items, PyObject *__pyx_v_test_user_items, int __pyx_v_K, PyObject *__pyx_v_show_progress, int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_model, PyObject *__pyx_v_train_user_items, PyObject *__pyx_v_test_user_items, int __pyx_v_K, PyObject *__pyx_v_show_progress, int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_model, PyObject *__pyx_v_train_user_items, PyObject *__pyx_v_test_user_items, int __pyx_v_K, PyObject *__pyx_v_show_progress, int __pyx_v_num_threads); /* proto */ +static PyObject *__pyx_pf_8implicit_10evaluation_8AUC_at_k(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_model, PyObject *__pyx_v_train_user_items, PyObject *__pyx_v_test_user_items, int __pyx_v_K, PyObject *__pyx_v_show_progress, int __pyx_v_num_threads); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */ @@ -2220,16 +2239,18 @@ static PyObject *__pyx_tuple__21; static PyObject *__pyx_tuple__23; static PyObject *__pyx_tuple__25; static PyObject *__pyx_tuple__27; -static PyObject *__pyx_tuple__28; static PyObject *__pyx_tuple__29; static PyObject *__pyx_tuple__30; static PyObject *__pyx_tuple__31; static PyObject *__pyx_tuple__32; +static PyObject *__pyx_tuple__33; +static PyObject *__pyx_tuple__34; static PyObject *__pyx_codeobj__20; static PyObject *__pyx_codeobj__22; static PyObject *__pyx_codeobj__24; static PyObject *__pyx_codeobj__26; -static PyObject *__pyx_codeobj__33; +static PyObject *__pyx_codeobj__28; +static PyObject *__pyx_codeobj__35; /* Late includes */ /* "implicit/evaluation.pyx":17 @@ -2237,12 +2258,12 @@ static PyObject *__pyx_codeobj__33; * * def train_test_split(ratings, train_percentage=0.8): # <<<<<<<<<<<<<< * """ Randomly splits the ratings matrix into two matrices for training/testing. - * Parameters + * */ /* Python wrapper */ static PyObject *__pyx_pw_8implicit_10evaluation_1train_test_split(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8implicit_10evaluation_train_test_split[] = " Randomly splits the ratings matrix into two matrices for training/testing.\n Parameters\n ----------\n ratings : coo_matrix\n A sparse matrix to split\n train_percentage : float\n What percentage of ratings should be used for training\n Returns\n -------\n (train, test) : csr_matrix, csr_matrix\n A tuple of csr_matrices for training/testing "; +static char __pyx_doc_8implicit_10evaluation_train_test_split[] = " Randomly splits the ratings matrix into two matrices for training/testing.\n\n Parameters\n ----------\n ratings : coo_matrix\n A sparse matrix to split\n train_percentage : float\n What percentage of ratings should be used for training\n\n Returns\n -------\n (train, test) : csr_matrix, csr_matrix\n A tuple of csr_matrices for training/testing "; static PyMethodDef __pyx_mdef_8implicit_10evaluation_1train_test_split = {"train_test_split", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8implicit_10evaluation_1train_test_split, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8implicit_10evaluation_train_test_split}; static PyObject *__pyx_pw_8implicit_10evaluation_1train_test_split(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_ratings = 0; @@ -2324,14 +2345,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __Pyx_RefNannySetupContext("train_test_split", 0); __Pyx_INCREF(__pyx_v_ratings); - /* "implicit/evaluation.pyx":29 + /* "implicit/evaluation.pyx":31 * (train, test) : csr_matrix, csr_matrix * A tuple of csr_matrices for training/testing """ * ratings = ratings.tocoo() # <<<<<<<<<<<<<< * * random_index = np.random.random(len(ratings.data)) */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_tocoo); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_tocoo); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { @@ -2345,32 +2366,32 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED } __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF_SET(__pyx_v_ratings, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":31 + /* "implicit/evaluation.pyx":33 * ratings = ratings.tocoo() * * random_index = np.random.random(len(ratings.data)) # <<<<<<<<<<<<<< * train_index = random_index < train_percentage * test_index = random_index >= train_percentage */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_random); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_random); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_random); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_random); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_4 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { @@ -2385,67 +2406,67 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_random_index = __pyx_t_1; __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":32 + /* "implicit/evaluation.pyx":34 * * random_index = np.random.random(len(ratings.data)) * train_index = random_index < train_percentage # <<<<<<<<<<<<<< * test_index = random_index >= train_percentage * */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_random_index, __pyx_v_train_percentage, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) + __pyx_t_1 = PyObject_RichCompare(__pyx_v_random_index, __pyx_v_train_percentage, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) __pyx_v_train_index = __pyx_t_1; __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":33 + /* "implicit/evaluation.pyx":35 * random_index = np.random.random(len(ratings.data)) * train_index = random_index < train_percentage * test_index = random_index >= train_percentage # <<<<<<<<<<<<<< * * train = csr_matrix((ratings.data[train_index], */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_random_index, __pyx_v_train_percentage, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_t_1 = PyObject_RichCompare(__pyx_v_random_index, __pyx_v_train_percentage, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) __pyx_v_test_index = __pyx_t_1; __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":35 + /* "implicit/evaluation.pyx":37 * test_index = random_index >= train_percentage * * train = csr_matrix((ratings.data[train_index], # <<<<<<<<<<<<<< * (ratings.row[train_index], ratings.col[train_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "implicit/evaluation.pyx":36 + /* "implicit/evaluation.pyx":38 * * train = csr_matrix((ratings.data[train_index], * (ratings.row[train_index], ratings.col[train_index])), # <<<<<<<<<<<<<< * shape=ratings.shape, dtype=ratings.dtype) * */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_row); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_row); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_col); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_col); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_v_train_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5); @@ -2454,14 +2475,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __pyx_t_5 = 0; __pyx_t_6 = 0; - /* "implicit/evaluation.pyx":35 + /* "implicit/evaluation.pyx":37 * test_index = random_index >= train_percentage * * train = csr_matrix((ratings.data[train_index], # <<<<<<<<<<<<<< * (ratings.row[train_index], ratings.col[train_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3); @@ -2469,38 +2490,38 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); __pyx_t_3 = 0; __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_6); __pyx_t_6 = 0; - /* "implicit/evaluation.pyx":37 + /* "implicit/evaluation.pyx":39 * train = csr_matrix((ratings.data[train_index], * (ratings.row[train_index], ratings.col[train_index])), * shape=ratings.shape, dtype=ratings.dtype) # <<<<<<<<<<<<<< * * test = csr_matrix((ratings.data[test_index], */ - __pyx_t_6 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 37, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_dtype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_dtype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 37, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "implicit/evaluation.pyx":35 + /* "implicit/evaluation.pyx":37 * test_index = random_index >= train_percentage * * train = csr_matrix((ratings.data[train_index], # <<<<<<<<<<<<<< * (ratings.row[train_index], ratings.col[train_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -2508,39 +2529,39 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __pyx_v_train = __pyx_t_3; __pyx_t_3 = 0; - /* "implicit/evaluation.pyx":39 + /* "implicit/evaluation.pyx":41 * shape=ratings.shape, dtype=ratings.dtype) * * test = csr_matrix((ratings.data[test_index], # <<<<<<<<<<<<<< * (ratings.row[test_index], ratings.col[test_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_data); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - /* "implicit/evaluation.pyx":40 + /* "implicit/evaluation.pyx":42 * * test = csr_matrix((ratings.data[test_index], * (ratings.row[test_index], ratings.col[test_index])), # <<<<<<<<<<<<<< * shape=ratings.shape, dtype=ratings.dtype) * */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_row); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_row); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_col); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_col); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_v_test_index); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1); @@ -2549,14 +2570,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __pyx_t_1 = 0; __pyx_t_5 = 0; - /* "implicit/evaluation.pyx":39 + /* "implicit/evaluation.pyx":41 * shape=ratings.shape, dtype=ratings.dtype) * * test = csr_matrix((ratings.data[test_index], # <<<<<<<<<<<<<< * (ratings.row[test_index], ratings.col[test_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); @@ -2564,38 +2585,38 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); __pyx_t_2 = 0; __pyx_t_6 = 0; - __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = 0; - /* "implicit/evaluation.pyx":41 + /* "implicit/evaluation.pyx":43 * test = csr_matrix((ratings.data[test_index], * (ratings.row[test_index], ratings.col[test_index])), * shape=ratings.shape, dtype=ratings.dtype) # <<<<<<<<<<<<<< * * test.data[test.data < 0] = 0 */ - __pyx_t_5 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 41, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 41, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 41, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_dtype); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 41, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_ratings, __pyx_n_s_dtype); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 41, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "implicit/evaluation.pyx":39 + /* "implicit/evaluation.pyx":41 * shape=ratings.shape, dtype=ratings.dtype) * * test = csr_matrix((ratings.data[test_index], # <<<<<<<<<<<<<< * (ratings.row[test_index], ratings.col[test_index])), * shape=ratings.shape, dtype=ratings.dtype) */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; @@ -2603,31 +2624,31 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED __pyx_v_test = __pyx_t_2; __pyx_t_2 = 0; - /* "implicit/evaluation.pyx":43 + /* "implicit/evaluation.pyx":45 * shape=ratings.shape, dtype=ratings.dtype) * * test.data[test.data < 0] = 0 # <<<<<<<<<<<<<< * test.eliminate_zeros() * */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 43, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 43, __pyx_L1_error) + __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(PyObject_SetItem(__pyx_t_2, __pyx_t_6, __pyx_int_0) < 0)) __PYX_ERR(0, 43, __pyx_L1_error) + if (unlikely(PyObject_SetItem(__pyx_t_2, __pyx_t_6, __pyx_int_0) < 0)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - /* "implicit/evaluation.pyx":44 + /* "implicit/evaluation.pyx":46 * * test.data[test.data < 0] = 0 * test.eliminate_zeros() # <<<<<<<<<<<<<< * * return train, test */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_eliminate_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_test, __pyx_n_s_eliminate_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { @@ -2641,12 +2662,12 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED } __pyx_t_6 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_2); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 44, __pyx_L1_error) + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - /* "implicit/evaluation.pyx":46 + /* "implicit/evaluation.pyx":48 * test.eliminate_zeros() * * return train, test # <<<<<<<<<<<<<< @@ -2654,7 +2675,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED * */ __Pyx_XDECREF(__pyx_r); - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 46, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 48, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_INCREF(__pyx_v_train); __Pyx_GIVEREF(__pyx_v_train); @@ -2671,7 +2692,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED * * def train_test_split(ratings, train_percentage=0.8): # <<<<<<<<<<<<<< * """ Randomly splits the ratings matrix into two matrices for training/testing. - * Parameters + * */ /* function exit code */ @@ -2695,7 +2716,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED return __pyx_r; } -/* "implicit/evaluation.pyx":50 +/* "implicit/evaluation.pyx":52 * * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -2705,7 +2726,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_train_test_split(CYTHON_UNUSED /* Python wrapper */ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8implicit_10evaluation_2precision_at_k[] = " Calculates P@K for a given trained model\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used\n in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to\n test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n Returns\n -------\n float\n the calculated p@k\n "; +static char __pyx_doc_8implicit_10evaluation_2precision_at_k[] = " Calculates P@K for a given trained model\n\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used\n in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to\n test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n\n Returns\n -------\n float\n the calculated p@k\n "; static PyMethodDef __pyx_mdef_8implicit_10evaluation_3precision_at_k = {"precision_at_k", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8implicit_10evaluation_3precision_at_k, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8implicit_10evaluation_2precision_at_k}; static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_model = 0; @@ -2721,12 +2742,12 @@ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_model,&__pyx_n_s_train_user_items,&__pyx_n_s_test_user_items,&__pyx_n_s_K,&__pyx_n_s_show_progress,&__pyx_n_s_num_threads,0}; PyObject* values[6] = {0,0,0,0,0,0}; - /* "implicit/evaluation.pyx":51 + /* "implicit/evaluation.pyx":53 * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, * show_progress=True, int num_threads=1): # <<<<<<<<<<<<<< * """ Calculates P@K for a given trained model - * Parameters + * */ values[4] = ((PyObject *)Py_True); if (unlikely(__pyx_kwds)) { @@ -2757,13 +2778,13 @@ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_train_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, 1); __PYX_ERR(0, 50, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, 1); __PYX_ERR(0, 52, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, 2); __PYX_ERR(0, 50, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, 2); __PYX_ERR(0, 52, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: @@ -2785,7 +2806,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "precision_at_k") < 0)) __PYX_ERR(0, 50, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "precision_at_k") < 0)) __PYX_ERR(0, 52, __pyx_L3_error) } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { @@ -2806,20 +2827,20 @@ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx __pyx_v_train_user_items = values[1]; __pyx_v_test_user_items = values[2]; if (values[3]) { - __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 50, __pyx_L3_error) + __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 52, __pyx_L3_error) } else { __pyx_v_K = ((int)10); } __pyx_v_show_progress = values[4]; if (values[5]) { - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 51, __pyx_L3_error) + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 53, __pyx_L3_error) } else { __pyx_v_num_threads = ((int)1); } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 50, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("precision_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 52, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("implicit.evaluation.precision_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); @@ -2827,7 +2848,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_3precision_at_k(PyObject *__pyx __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_8implicit_10evaluation_2precision_at_k(__pyx_self, __pyx_v_model, __pyx_v_train_user_items, __pyx_v_test_user_items, __pyx_v_K, __pyx_v_show_progress, __pyx_v_num_threads); - /* "implicit/evaluation.pyx":50 + /* "implicit/evaluation.pyx":52 * * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -2886,28 +2907,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __Pyx_INCREF(__pyx_v_train_user_items); __Pyx_INCREF(__pyx_v_test_user_items); - /* "implicit/evaluation.pyx":77 + /* "implicit/evaluation.pyx":81 * the calculated p@k * """ * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< * train_user_items = train_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 77, __pyx_L1_error) + __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { - /* "implicit/evaluation.pyx":78 + /* "implicit/evaluation.pyx":82 * """ * if not isinstance(train_user_items, csr_matrix): * train_user_items = train_user_items.tocsr() # <<<<<<<<<<<<<< * * if not isinstance(test_user_items, csr_matrix): */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 78, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 82, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -2921,13 +2942,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_train_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":77 + /* "implicit/evaluation.pyx":81 * the calculated p@k * """ * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -2936,28 +2957,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ } - /* "implicit/evaluation.pyx":80 + /* "implicit/evaluation.pyx":84 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< * test_user_items = test_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 84, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 80, __pyx_L1_error) + __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 84, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":81 + /* "implicit/evaluation.pyx":85 * * if not isinstance(test_user_items, csr_matrix): * test_user_items = test_user_items.tocsr() # <<<<<<<<<<<<<< * * cdef int users = test_user_items.shape[0], u, i */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 81, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -2971,13 +2992,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_test_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":80 + /* "implicit/evaluation.pyx":84 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -2986,23 +3007,23 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ } - /* "implicit/evaluation.pyx":83 + /* "implicit/evaluation.pyx":87 * test_user_items = test_user_items.tocsr() * * cdef int users = test_user_items.shape[0], u, i # <<<<<<<<<<<<<< * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 83, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 83, __pyx_L1_error) + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 83, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_users = __pyx_t_6; - /* "implicit/evaluation.pyx":84 + /* "implicit/evaluation.pyx":88 * * cdef int users = test_user_items.shape[0], u, i * cdef double relevant = 0, total = 0 # <<<<<<<<<<<<<< @@ -3012,64 +3033,64 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __pyx_v_relevant = 0.0; __pyx_v_total = 0.0; - /* "implicit/evaluation.pyx":85 + /* "implicit/evaluation.pyx":89 * cdef int users = test_user_items.shape[0], u, i * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr # <<<<<<<<<<<<<< * cdef int[:] test_indices = test_user_items.indices * */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 89, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 85, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 89, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indptr = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":86 + /* "implicit/evaluation.pyx":90 * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr * cdef int[:] test_indices = test_user_items.indices # <<<<<<<<<<<<<< * * cdef int * ids */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 86, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 86, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indices = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":91 + /* "implicit/evaluation.pyx":95 * cdef unordered_set[int] * likes * * progress = tqdm(total=users, disable=not show_progress) # <<<<<<<<<<<<<< * * with nogil, parallel(num_threads=num_threads): */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 91, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_5) < 0) __PYX_ERR(0, 91, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_5) < 0) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 91, __pyx_L1_error) - __pyx_t_5 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 91, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 95, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_5) < 0) __PYX_ERR(0, 91, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_5) < 0) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 91, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_progress = __pyx_t_5; __pyx_t_5 = 0; - /* "implicit/evaluation.pyx":93 + /* "implicit/evaluation.pyx":97 * progress = tqdm(total=users, disable=not show_progress) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -3108,7 +3129,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __pyx_v_ids = ((int *)1); __pyx_v_likes = ((std::unordered_set *)1); - /* "implicit/evaluation.pyx":94 + /* "implicit/evaluation.pyx":98 * * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) # <<<<<<<<<<<<<< @@ -3117,7 +3138,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ __pyx_v_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":95 + /* "implicit/evaluation.pyx":99 * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() # <<<<<<<<<<<<<< @@ -3134,11 +3155,11 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __PYX_ERR(0, 95, __pyx_L10_error) + __PYX_ERR(0, 99, __pyx_L10_error) } __pyx_v_likes = __pyx_t_8; - /* "implicit/evaluation.pyx":96 + /* "implicit/evaluation.pyx":100 * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() * try: # <<<<<<<<<<<<<< @@ -3147,7 +3168,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ /*try:*/ { - /* "implicit/evaluation.pyx":97 + /* "implicit/evaluation.pyx":101 * likes = new unordered_set[int]() * try: * for u in prange(users, schedule='guided'): # <<<<<<<<<<<<<< @@ -3178,7 +3199,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P /* Initialize private variables to invalid values */ __pyx_v_i = ((int)0xbad0bad0); - /* "implicit/evaluation.pyx":99 + /* "implicit/evaluation.pyx":103 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -3192,7 +3213,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __pyx_t_2 = (((*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_11 * __pyx_v_test_indptr.strides[0]) ))) == (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_12 * __pyx_v_test_indptr.strides[0]) )))) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":100 + /* "implicit/evaluation.pyx":104 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -3205,14 +3226,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P #endif /*try:*/ { - /* "implicit/evaluation.pyx":101 + /* "implicit/evaluation.pyx":105 * if test_indptr[u] == test_indptr[u+1]: * with gil: * progress.update(1) # <<<<<<<<<<<<<< * continue * memset(ids, 0, sizeof(int) * K) */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L25_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 105, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -3226,13 +3247,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } __pyx_t_5 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_4, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_int_1); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 101, __pyx_L25_error) + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 105, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } - /* "implicit/evaluation.pyx":100 + /* "implicit/evaluation.pyx":104 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -3256,7 +3277,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } } - /* "implicit/evaluation.pyx":102 + /* "implicit/evaluation.pyx":106 * with gil: * progress.update(1) * continue # <<<<<<<<<<<<<< @@ -3265,7 +3286,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ goto __pyx_L17_continue; - /* "implicit/evaluation.pyx":99 + /* "implicit/evaluation.pyx":103 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -3274,7 +3295,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ } - /* "implicit/evaluation.pyx":103 + /* "implicit/evaluation.pyx":107 * progress.update(1) * continue * memset(ids, 0, sizeof(int) * K) # <<<<<<<<<<<<<< @@ -3283,7 +3304,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ (void)(memset(__pyx_v_ids, 0, ((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":105 + /* "implicit/evaluation.pyx":109 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -3296,18 +3317,18 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P #endif /*try:*/ { - /* "implicit/evaluation.pyx":106 + /* "implicit/evaluation.pyx":110 * * with gil: * recs = model.recommend(u, train_user_items, N=K) # <<<<<<<<<<<<<< * for i in range(len(recs)): * ids[i] = recs[i][0] */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); @@ -3315,13 +3336,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __Pyx_GIVEREF(__pyx_v_train_user_items); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_train_user_items); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_13) < 0) __PYX_ERR(0, 106, __pyx_L30_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_13) < 0) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 106, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 110, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; @@ -3329,43 +3350,43 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __Pyx_XDECREF_SET(__pyx_v_recs, __pyx_t_13); __pyx_t_13 = 0; - /* "implicit/evaluation.pyx":107 + /* "implicit/evaluation.pyx":111 * with gil: * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): # <<<<<<<<<<<<<< * ids[i] = recs[i][0] * progress.update(1) */ - __pyx_t_14 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 107, __pyx_L30_error) + __pyx_t_14 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 111, __pyx_L30_error) __pyx_t_15 = __pyx_t_14; for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) { __pyx_v_i = __pyx_t_16; - /* "implicit/evaluation.pyx":108 + /* "implicit/evaluation.pyx":112 * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): * ids[i] = recs[i][0] # <<<<<<<<<<<<<< * progress.update(1) * */ - __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 108, __pyx_L30_error) + __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 112, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_13, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L30_error) + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_13, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __pyx_t_17 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_17 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L30_error) + __pyx_t_17 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_17 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 112, __pyx_L30_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; (__pyx_v_ids[__pyx_v_i]) = __pyx_t_17; } - /* "implicit/evaluation.pyx":109 + /* "implicit/evaluation.pyx":113 * for i in range(len(recs)): * ids[i] = recs[i][0] * progress.update(1) # <<<<<<<<<<<<<< * * # mostly we're going to be blocked on the gil here, */ - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 109, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 113, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { @@ -3379,13 +3400,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_13, __pyx_t_4, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_int_1); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 109, __pyx_L30_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 113, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } - /* "implicit/evaluation.pyx":105 + /* "implicit/evaluation.pyx":109 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -3409,7 +3430,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } } - /* "implicit/evaluation.pyx":113 + /* "implicit/evaluation.pyx":117 * # mostly we're going to be blocked on the gil here, * # so try to do actual scoring without it * likes.clear() # <<<<<<<<<<<<<< @@ -3418,7 +3439,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ __pyx_v_likes->clear(); - /* "implicit/evaluation.pyx":114 + /* "implicit/evaluation.pyx":118 * # so try to do actual scoring without it * likes.clear() * for i in range(test_indptr[u], test_indptr[u+1]): # <<<<<<<<<<<<<< @@ -3434,7 +3455,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P for (__pyx_t_20 = (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_19 * __pyx_v_test_indptr.strides[0]) ))); __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":115 + /* "implicit/evaluation.pyx":119 * likes.clear() * for i in range(test_indptr[u], test_indptr[u+1]): * likes.insert(test_indices[i]) # <<<<<<<<<<<<<< @@ -3446,7 +3467,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P (void)(__pyx_v_likes->insert((*((int *) ( /* dim=0 */ (__pyx_v_test_indices.data + __pyx_t_21 * __pyx_v_test_indices.strides[0]) ))))); } - /* "implicit/evaluation.pyx":117 + /* "implicit/evaluation.pyx":121 * likes.insert(test_indices[i]) * * total += fmin(K, likes.size()) # <<<<<<<<<<<<<< @@ -3455,7 +3476,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ __pyx_v_total = (__pyx_v_total + fmin(__pyx_v_K, __pyx_v_likes->size())); - /* "implicit/evaluation.pyx":119 + /* "implicit/evaluation.pyx":123 * total += fmin(K, likes.size()) * * for i in range(K): # <<<<<<<<<<<<<< @@ -3467,7 +3488,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P for (__pyx_t_20 = 0; __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":120 + /* "implicit/evaluation.pyx":124 * * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< @@ -3477,7 +3498,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __pyx_t_2 = ((__pyx_v_likes->find((__pyx_v_ids[__pyx_v_i])) != __pyx_v_likes->end()) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":121 + /* "implicit/evaluation.pyx":125 * for i in range(K): * if likes.find(ids[i]) != likes.end(): * relevant += 1 # <<<<<<<<<<<<<< @@ -3486,7 +3507,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ __pyx_v_relevant = (__pyx_v_relevant + 1.0); - /* "implicit/evaluation.pyx":120 + /* "implicit/evaluation.pyx":124 * * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< @@ -3562,7 +3583,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } } - /* "implicit/evaluation.pyx":123 + /* "implicit/evaluation.pyx":127 * relevant += 1 * finally: * free(ids) # <<<<<<<<<<<<<< @@ -3573,7 +3594,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P /*normal exit:*/{ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":124 + /* "implicit/evaluation.pyx":128 * finally: * free(ids) * del likes # <<<<<<<<<<<<<< @@ -3613,7 +3634,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P #endif { - /* "implicit/evaluation.pyx":123 + /* "implicit/evaluation.pyx":127 * relevant += 1 * finally: * free(ids) # <<<<<<<<<<<<<< @@ -3622,7 +3643,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P */ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":124 + /* "implicit/evaluation.pyx":128 * finally: * free(ids) * del likes # <<<<<<<<<<<<<< @@ -3740,7 +3761,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P #endif } - /* "implicit/evaluation.pyx":93 + /* "implicit/evaluation.pyx":97 * progress = tqdm(total=users, disable=not show_progress) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -3766,14 +3787,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } } - /* "implicit/evaluation.pyx":126 + /* "implicit/evaluation.pyx":130 * del likes * * progress.close() # <<<<<<<<<<<<<< * return relevant / total * */ - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 126, __pyx_L1_error) + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 130, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_13); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { @@ -3787,12 +3808,12 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P } __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_13); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 126, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":127 + /* "implicit/evaluation.pyx":131 * * progress.close() * return relevant / total # <<<<<<<<<<<<<< @@ -3802,15 +3823,15 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P __Pyx_XDECREF(__pyx_r); if (unlikely(__pyx_v_total == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 127, __pyx_L1_error) + __PYX_ERR(0, 131, __pyx_L1_error) } - __pyx_t_1 = PyFloat_FromDouble((__pyx_v_relevant / __pyx_v_total)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error) + __pyx_t_1 = PyFloat_FromDouble((__pyx_v_relevant / __pyx_v_total)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 131, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "implicit/evaluation.pyx":50 + /* "implicit/evaluation.pyx":52 * * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -3839,7 +3860,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P return __pyx_r; } -/* "implicit/evaluation.pyx":131 +/* "implicit/evaluation.pyx":135 * * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -3849,7 +3870,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_2precision_at_k(CYTHON_UNUSED P /* Python wrapper */ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8implicit_10evaluation_4mean_average_precision_at_k[] = " Calculates MAP@K for a given trained model\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n Returns\n -------\n float\n the calculated MAP@k\n "; +static char __pyx_doc_8implicit_10evaluation_4mean_average_precision_at_k[] = " Calculates MAP@K for a given trained model\n\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n\n Returns\n -------\n float\n the calculated MAP@k\n "; static PyMethodDef __pyx_mdef_8implicit_10evaluation_5mean_average_precision_at_k = {"mean_average_precision_at_k", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8implicit_10evaluation_4mean_average_precision_at_k}; static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_model = 0; @@ -3865,12 +3886,12 @@ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(Py static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_model,&__pyx_n_s_train_user_items,&__pyx_n_s_test_user_items,&__pyx_n_s_K,&__pyx_n_s_show_progress,&__pyx_n_s_num_threads,0}; PyObject* values[6] = {0,0,0,0,0,0}; - /* "implicit/evaluation.pyx":132 + /* "implicit/evaluation.pyx":136 * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, * show_progress=True, int num_threads=1): # <<<<<<<<<<<<<< * """ Calculates MAP@K for a given trained model - * Parameters + * */ values[4] = ((PyObject *)Py_True); if (unlikely(__pyx_kwds)) { @@ -3901,13 +3922,13 @@ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(Py case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_train_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, 1); __PYX_ERR(0, 131, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, 1); __PYX_ERR(0, 135, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, 2); __PYX_ERR(0, 131, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, 2); __PYX_ERR(0, 135, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: @@ -3929,7 +3950,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(Py } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mean_average_precision_at_k") < 0)) __PYX_ERR(0, 131, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mean_average_precision_at_k") < 0)) __PYX_ERR(0, 135, __pyx_L3_error) } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { @@ -3950,20 +3971,20 @@ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(Py __pyx_v_train_user_items = values[1]; __pyx_v_test_user_items = values[2]; if (values[3]) { - __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 131, __pyx_L3_error) + __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 135, __pyx_L3_error) } else { __pyx_v_K = ((int)10); } __pyx_v_show_progress = values[4]; if (values[5]) { - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 132, __pyx_L3_error) + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 136, __pyx_L3_error) } else { __pyx_v_num_threads = ((int)1); } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 131, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("mean_average_precision_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 135, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("implicit.evaluation.mean_average_precision_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); @@ -3971,7 +3992,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_5mean_average_precision_at_k(Py __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(__pyx_self, __pyx_v_model, __pyx_v_train_user_items, __pyx_v_test_user_items, __pyx_v_K, __pyx_v_show_progress, __pyx_v_num_threads); - /* "implicit/evaluation.pyx":131 + /* "implicit/evaluation.pyx":135 * * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -4034,28 +4055,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __Pyx_INCREF(__pyx_v_train_user_items); __Pyx_INCREF(__pyx_v_test_user_items); - /* "implicit/evaluation.pyx":158 + /* "implicit/evaluation.pyx":164 * # TODO: there is a fair amount of boilerplate here that is cut and paste * # from precision_at_k. refactor it out. * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< * train_user_items = train_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 164, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 158, __pyx_L1_error) + __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 164, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { - /* "implicit/evaluation.pyx":159 + /* "implicit/evaluation.pyx":165 * # from precision_at_k. refactor it out. * if not isinstance(train_user_items, csr_matrix): * train_user_items = train_user_items.tocsr() # <<<<<<<<<<<<<< * * if not isinstance(test_user_items, csr_matrix): */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -4069,13 +4090,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_train_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":158 + /* "implicit/evaluation.pyx":164 * # TODO: there is a fair amount of boilerplate here that is cut and paste * # from precision_at_k. refactor it out. * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -4084,28 +4105,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ } - /* "implicit/evaluation.pyx":161 + /* "implicit/evaluation.pyx":167 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< * test_user_items = test_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 167, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 161, __pyx_L1_error) + __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 167, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":162 + /* "implicit/evaluation.pyx":168 * * if not isinstance(test_user_items, csr_matrix): * test_user_items = test_user_items.tocsr() # <<<<<<<<<<<<<< * * cdef int users = test_user_items.shape[0], u, i, total = 0 */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 162, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 168, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -4119,13 +4140,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 162, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 168, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_test_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":161 + /* "implicit/evaluation.pyx":167 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -4134,24 +4155,24 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ } - /* "implicit/evaluation.pyx":164 + /* "implicit/evaluation.pyx":170 * test_user_items = test_user_items.tocsr() * * cdef int users = test_user_items.shape[0], u, i, total = 0 # <<<<<<<<<<<<<< * cdef double mean_ap = 0, ap = 0, relevant = 0 * cdef int[:] test_indptr = test_user_items.indptr */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 164, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 170, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 164, __pyx_L1_error) + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 170, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 164, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 170, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_users = __pyx_t_6; __pyx_v_total = 0; - /* "implicit/evaluation.pyx":165 + /* "implicit/evaluation.pyx":171 * * cdef int users = test_user_items.shape[0], u, i, total = 0 * cdef double mean_ap = 0, ap = 0, relevant = 0 # <<<<<<<<<<<<<< @@ -4162,64 +4183,64 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __pyx_v_ap = 0.0; __pyx_v_relevant = 0.0; - /* "implicit/evaluation.pyx":166 + /* "implicit/evaluation.pyx":172 * cdef int users = test_user_items.shape[0], u, i, total = 0 * cdef double mean_ap = 0, ap = 0, relevant = 0 * cdef int[:] test_indptr = test_user_items.indptr # <<<<<<<<<<<<<< * cdef int[:] test_indices = test_user_items.indices * */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 166, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 172, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 166, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 172, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indptr = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":167 + /* "implicit/evaluation.pyx":173 * cdef double mean_ap = 0, ap = 0, relevant = 0 * cdef int[:] test_indptr = test_user_items.indptr * cdef int[:] test_indices = test_user_items.indices # <<<<<<<<<<<<<< * * cdef int * ids */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 167, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 173, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 167, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 173, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indices = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":172 + /* "implicit/evaluation.pyx":178 * cdef unordered_set[int] * likes * * progress = tqdm(total=users, disable=not show_progress) # <<<<<<<<<<<<<< * * with nogil, parallel(num_threads=num_threads): */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 172, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 172, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 172, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_5) < 0) __PYX_ERR(0, 172, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_5) < 0) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 172, __pyx_L1_error) - __pyx_t_5 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 172, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 178, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_5) < 0) __PYX_ERR(0, 172, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_5) < 0) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 172, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_progress = __pyx_t_5; __pyx_t_5 = 0; - /* "implicit/evaluation.pyx":174 + /* "implicit/evaluation.pyx":180 * progress = tqdm(total=users, disable=not show_progress) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -4258,7 +4279,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __pyx_v_ids = ((int *)1); __pyx_v_likes = ((std::unordered_set *)1); - /* "implicit/evaluation.pyx":175 + /* "implicit/evaluation.pyx":181 * * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) # <<<<<<<<<<<<<< @@ -4267,7 +4288,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ __pyx_v_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":176 + /* "implicit/evaluation.pyx":182 * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() # <<<<<<<<<<<<<< @@ -4284,11 +4305,11 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __PYX_ERR(0, 176, __pyx_L10_error) + __PYX_ERR(0, 182, __pyx_L10_error) } __pyx_v_likes = __pyx_t_8; - /* "implicit/evaluation.pyx":177 + /* "implicit/evaluation.pyx":183 * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() * try: # <<<<<<<<<<<<<< @@ -4297,7 +4318,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ /*try:*/ { - /* "implicit/evaluation.pyx":178 + /* "implicit/evaluation.pyx":184 * likes = new unordered_set[int]() * try: * for u in prange(users, schedule='guided'): # <<<<<<<<<<<<<< @@ -4332,7 +4353,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __pyx_v_i = ((int)0xbad0bad0); __pyx_v_relevant = ((double)__PYX_NAN()); - /* "implicit/evaluation.pyx":180 + /* "implicit/evaluation.pyx":186 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -4346,7 +4367,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __pyx_t_2 = (((*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_11 * __pyx_v_test_indptr.strides[0]) ))) == (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_12 * __pyx_v_test_indptr.strides[0]) )))) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":181 + /* "implicit/evaluation.pyx":187 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -4359,14 +4380,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #endif /*try:*/ { - /* "implicit/evaluation.pyx":182 + /* "implicit/evaluation.pyx":188 * if test_indptr[u] == test_indptr[u+1]: * with gil: * progress.update(1) # <<<<<<<<<<<<<< * continue * memset(ids, 0, sizeof(int) * K) */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 182, __pyx_L25_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 188, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -4380,13 +4401,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } __pyx_t_5 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_4, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_int_1); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 182, __pyx_L25_error) + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 188, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } - /* "implicit/evaluation.pyx":181 + /* "implicit/evaluation.pyx":187 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -4410,7 +4431,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } } - /* "implicit/evaluation.pyx":183 + /* "implicit/evaluation.pyx":189 * with gil: * progress.update(1) * continue # <<<<<<<<<<<<<< @@ -4419,7 +4440,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ goto __pyx_L17_continue; - /* "implicit/evaluation.pyx":180 + /* "implicit/evaluation.pyx":186 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -4428,7 +4449,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ } - /* "implicit/evaluation.pyx":184 + /* "implicit/evaluation.pyx":190 * progress.update(1) * continue * memset(ids, 0, sizeof(int) * K) # <<<<<<<<<<<<<< @@ -4437,7 +4458,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ (void)(memset(__pyx_v_ids, 0, ((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":186 + /* "implicit/evaluation.pyx":192 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -4450,18 +4471,18 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #endif /*try:*/ { - /* "implicit/evaluation.pyx":187 + /* "implicit/evaluation.pyx":193 * * with gil: * recs = model.recommend(u, train_user_items, N=K) # <<<<<<<<<<<<<< * for i in range(len(recs)): * ids[i] = recs[i][0] */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); @@ -4469,13 +4490,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __Pyx_GIVEREF(__pyx_v_train_user_items); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_train_user_items); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_13) < 0) __PYX_ERR(0, 187, __pyx_L30_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_13) < 0) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 187, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 193, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; @@ -4483,43 +4504,43 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __Pyx_XDECREF_SET(__pyx_v_recs, __pyx_t_13); __pyx_t_13 = 0; - /* "implicit/evaluation.pyx":188 + /* "implicit/evaluation.pyx":194 * with gil: * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): # <<<<<<<<<<<<<< * ids[i] = recs[i][0] * progress.update(1) */ - __pyx_t_14 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 188, __pyx_L30_error) + __pyx_t_14 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 194, __pyx_L30_error) __pyx_t_15 = __pyx_t_14; for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) { __pyx_v_i = __pyx_t_16; - /* "implicit/evaluation.pyx":189 + /* "implicit/evaluation.pyx":195 * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): * ids[i] = recs[i][0] # <<<<<<<<<<<<<< * progress.update(1) * */ - __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 189, __pyx_L30_error) + __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 195, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_13, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 189, __pyx_L30_error) + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_13, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 195, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __pyx_t_17 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_17 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 189, __pyx_L30_error) + __pyx_t_17 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_17 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L30_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; (__pyx_v_ids[__pyx_v_i]) = __pyx_t_17; } - /* "implicit/evaluation.pyx":190 + /* "implicit/evaluation.pyx":196 * for i in range(len(recs)): * ids[i] = recs[i][0] * progress.update(1) # <<<<<<<<<<<<<< * * # mostly we're going to be blocked on the gil here, */ - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 190, __pyx_L30_error) + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 196, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_13); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { @@ -4533,13 +4554,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_13, __pyx_t_4, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_int_1); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 190, __pyx_L30_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 196, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } - /* "implicit/evaluation.pyx":186 + /* "implicit/evaluation.pyx":192 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -4563,7 +4584,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } } - /* "implicit/evaluation.pyx":194 + /* "implicit/evaluation.pyx":200 * # mostly we're going to be blocked on the gil here, * # so try to do actual scoring without it * likes.clear() # <<<<<<<<<<<<<< @@ -4572,7 +4593,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ __pyx_v_likes->clear(); - /* "implicit/evaluation.pyx":195 + /* "implicit/evaluation.pyx":201 * # so try to do actual scoring without it * likes.clear() * for i in range(test_indptr[u], test_indptr[u+1]): # <<<<<<<<<<<<<< @@ -4588,7 +4609,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY for (__pyx_t_20 = (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_19 * __pyx_v_test_indptr.strides[0]) ))); __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":196 + /* "implicit/evaluation.pyx":202 * likes.clear() * for i in range(test_indptr[u], test_indptr[u+1]): * likes.insert(test_indices[i]) # <<<<<<<<<<<<<< @@ -4600,7 +4621,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY (void)(__pyx_v_likes->insert((*((int *) ( /* dim=0 */ (__pyx_v_test_indices.data + __pyx_t_21 * __pyx_v_test_indices.strides[0]) ))))); } - /* "implicit/evaluation.pyx":198 + /* "implicit/evaluation.pyx":204 * likes.insert(test_indices[i]) * * ap = 0 # <<<<<<<<<<<<<< @@ -4609,7 +4630,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ __pyx_v_ap = 0.0; - /* "implicit/evaluation.pyx":199 + /* "implicit/evaluation.pyx":205 * * ap = 0 * relevant = 0 # <<<<<<<<<<<<<< @@ -4618,7 +4639,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ __pyx_v_relevant = 0.0; - /* "implicit/evaluation.pyx":200 + /* "implicit/evaluation.pyx":206 * ap = 0 * relevant = 0 * for i in range(K): # <<<<<<<<<<<<<< @@ -4630,7 +4651,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY for (__pyx_t_20 = 0; __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":201 + /* "implicit/evaluation.pyx":207 * relevant = 0 * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< @@ -4640,7 +4661,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __pyx_t_2 = ((__pyx_v_likes->find((__pyx_v_ids[__pyx_v_i])) != __pyx_v_likes->end()) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":202 + /* "implicit/evaluation.pyx":208 * for i in range(K): * if likes.find(ids[i]) != likes.end(): * relevant = relevant + 1 # <<<<<<<<<<<<<< @@ -4649,7 +4670,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ __pyx_v_relevant = (__pyx_v_relevant + 1.0); - /* "implicit/evaluation.pyx":203 + /* "implicit/evaluation.pyx":209 * if likes.find(ids[i]) != likes.end(): * relevant = relevant + 1 * ap = ap + relevant / (i + 1) # <<<<<<<<<<<<<< @@ -4665,11 +4686,11 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __PYX_ERR(0, 203, __pyx_L19_error) + __PYX_ERR(0, 209, __pyx_L19_error) } __pyx_v_ap = (__pyx_v_ap + (__pyx_v_relevant / ((double)__pyx_t_22))); - /* "implicit/evaluation.pyx":201 + /* "implicit/evaluation.pyx":207 * relevant = 0 * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< @@ -4679,7 +4700,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } } - /* "implicit/evaluation.pyx":204 + /* "implicit/evaluation.pyx":210 * relevant = relevant + 1 * ap = ap + relevant / (i + 1) * mean_ap += ap / fmin(K, likes.size()) # <<<<<<<<<<<<<< @@ -4695,11 +4716,11 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __PYX_ERR(0, 204, __pyx_L19_error) + __PYX_ERR(0, 210, __pyx_L19_error) } __pyx_v_mean_ap = (__pyx_v_mean_ap + (__pyx_v_ap / __pyx_t_23)); - /* "implicit/evaluation.pyx":205 + /* "implicit/evaluation.pyx":211 * ap = ap + relevant / (i + 1) * mean_ap += ap / fmin(K, likes.size()) * total += 1 # <<<<<<<<<<<<<< @@ -4778,7 +4799,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } } - /* "implicit/evaluation.pyx":207 + /* "implicit/evaluation.pyx":213 * total += 1 * finally: * free(ids) # <<<<<<<<<<<<<< @@ -4789,7 +4810,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY /*normal exit:*/{ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":208 + /* "implicit/evaluation.pyx":214 * finally: * free(ids) * del likes # <<<<<<<<<<<<<< @@ -4829,7 +4850,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #endif { - /* "implicit/evaluation.pyx":207 + /* "implicit/evaluation.pyx":213 * total += 1 * finally: * free(ids) # <<<<<<<<<<<<<< @@ -4838,7 +4859,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY */ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":208 + /* "implicit/evaluation.pyx":214 * finally: * free(ids) * del likes # <<<<<<<<<<<<<< @@ -4956,7 +4977,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY #endif } - /* "implicit/evaluation.pyx":174 + /* "implicit/evaluation.pyx":180 * progress = tqdm(total=users, disable=not show_progress) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -4982,14 +5003,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } } - /* "implicit/evaluation.pyx":210 + /* "implicit/evaluation.pyx":216 * del likes * * progress.close() # <<<<<<<<<<<<<< * return mean_ap / total * */ - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 210, __pyx_L1_error) + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 216, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_13); __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { @@ -5003,12 +5024,12 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY } __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_13); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 210, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 216, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":211 + /* "implicit/evaluation.pyx":217 * * progress.close() * return mean_ap / total # <<<<<<<<<<<<<< @@ -5018,15 +5039,15 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY __Pyx_XDECREF(__pyx_r); if (unlikely(__pyx_v_total == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 211, __pyx_L1_error) + __PYX_ERR(0, 217, __pyx_L1_error) } - __pyx_t_1 = PyFloat_FromDouble((__pyx_v_mean_ap / ((double)__pyx_v_total))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 211, __pyx_L1_error) + __pyx_t_1 = PyFloat_FromDouble((__pyx_v_mean_ap / ((double)__pyx_v_total))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 217, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "implicit/evaluation.pyx":131 + /* "implicit/evaluation.pyx":135 * * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -5055,7 +5076,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY return __pyx_r; } -/* "implicit/evaluation.pyx":215 +/* "implicit/evaluation.pyx":221 * * @cython.boundscheck(False) * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -5065,7 +5086,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_4mean_average_precision_at_k(CY /* Python wrapper */ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8implicit_10evaluation_6ndcg_at_k[] = " Calculates ndcg@K for a given trained model\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n Returns\n -------\n float\n the calculated ndcg@k\n "; +static char __pyx_doc_8implicit_10evaluation_6ndcg_at_k[] = " Calculates ndcg@K for a given trained model\n\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n\n Returns\n -------\n float\n the calculated ndcg@k\n "; static PyMethodDef __pyx_mdef_8implicit_10evaluation_7ndcg_at_k = {"ndcg_at_k", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8implicit_10evaluation_7ndcg_at_k, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8implicit_10evaluation_6ndcg_at_k}; static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_model = 0; @@ -5081,12 +5102,12 @@ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_model,&__pyx_n_s_train_user_items,&__pyx_n_s_test_user_items,&__pyx_n_s_K,&__pyx_n_s_show_progress,&__pyx_n_s_num_threads,0}; PyObject* values[6] = {0,0,0,0,0,0}; - /* "implicit/evaluation.pyx":216 + /* "implicit/evaluation.pyx":222 * @cython.boundscheck(False) * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, * show_progress=True, int num_threads=1): # <<<<<<<<<<<<<< * """ Calculates ndcg@K for a given trained model - * Parameters + * */ values[4] = ((PyObject *)Py_True); if (unlikely(__pyx_kwds)) { @@ -5117,13 +5138,13 @@ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self case 1: if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_train_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, 1); __PYX_ERR(0, 215, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, 1); __PYX_ERR(0, 221, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test_user_items)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, 2); __PYX_ERR(0, 215, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, 2); __PYX_ERR(0, 221, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: @@ -5145,7 +5166,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ndcg_at_k") < 0)) __PYX_ERR(0, 215, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ndcg_at_k") < 0)) __PYX_ERR(0, 221, __pyx_L3_error) } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { @@ -5166,20 +5187,20 @@ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self __pyx_v_train_user_items = values[1]; __pyx_v_test_user_items = values[2]; if (values[3]) { - __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error) + __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 221, __pyx_L3_error) } else { __pyx_v_K = ((int)10); } __pyx_v_show_progress = values[4]; if (values[5]) { - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 216, __pyx_L3_error) + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 222, __pyx_L3_error) } else { __pyx_v_num_threads = ((int)1); } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 215, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("ndcg_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 221, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("implicit.evaluation.ndcg_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); @@ -5187,7 +5208,7 @@ static PyObject *__pyx_pw_8implicit_10evaluation_7ndcg_at_k(PyObject *__pyx_self __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_8implicit_10evaluation_6ndcg_at_k(__pyx_self, __pyx_v_model, __pyx_v_train_user_items, __pyx_v_test_user_items, __pyx_v_K, __pyx_v_show_progress, __pyx_v_num_threads); - /* "implicit/evaluation.pyx":215 + /* "implicit/evaluation.pyx":221 * * @cython.boundscheck(False) * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< @@ -5257,28 +5278,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __Pyx_INCREF(__pyx_v_train_user_items); __Pyx_INCREF(__pyx_v_test_user_items); - /* "implicit/evaluation.pyx":240 + /* "implicit/evaluation.pyx":248 * the calculated ndcg@k * """ * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< * train_user_items = train_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 240, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 248, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 240, __pyx_L1_error) + __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 248, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { - /* "implicit/evaluation.pyx":241 + /* "implicit/evaluation.pyx":249 * """ * if not isinstance(train_user_items, csr_matrix): * train_user_items = train_user_items.tocsr() # <<<<<<<<<<<<<< * * if not isinstance(test_user_items, csr_matrix): */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 241, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 249, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -5292,13 +5313,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 241, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 249, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_train_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":240 + /* "implicit/evaluation.pyx":248 * the calculated ndcg@k * """ * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -5307,28 +5328,28 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ } - /* "implicit/evaluation.pyx":243 + /* "implicit/evaluation.pyx":251 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< * test_user_items = test_user_items.tocsr() * */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 243, __pyx_L1_error) + __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 251, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":244 + /* "implicit/evaluation.pyx":252 * * if not isinstance(test_user_items, csr_matrix): * test_user_items = test_user_items.tocsr() # <<<<<<<<<<<<<< * * cdef int users = test_user_items.shape[0], u, i */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 244, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 252, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -5342,13 +5363,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 244, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 252, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF_SET(__pyx_v_test_user_items, __pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":243 + /* "implicit/evaluation.pyx":251 * train_user_items = train_user_items.tocsr() * * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< @@ -5357,23 +5378,23 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ } - /* "implicit/evaluation.pyx":246 + /* "implicit/evaluation.pyx":254 * test_user_items = test_user_items.tocsr() * * cdef int users = test_user_items.shape[0], u, i # <<<<<<<<<<<<<< * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 246, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 254, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 246, __pyx_L1_error) + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 254, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 246, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 254, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_users = __pyx_t_6; - /* "implicit/evaluation.pyx":247 + /* "implicit/evaluation.pyx":255 * * cdef int users = test_user_items.shape[0], u, i * cdef double relevant = 0, total = 0 # <<<<<<<<<<<<<< @@ -5383,54 +5404,54 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_v_relevant = 0.0; __pyx_v_total = 0.0; - /* "implicit/evaluation.pyx":248 + /* "implicit/evaluation.pyx":256 * cdef int users = test_user_items.shape[0], u, i * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr # <<<<<<<<<<<<<< * cdef int[:] test_indices = test_user_items.indices * */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 248, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 256, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 248, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 256, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indptr = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":249 + /* "implicit/evaluation.pyx":257 * cdef double relevant = 0, total = 0 * cdef int[:] test_indptr = test_user_items.indptr * cdef int[:] test_indices = test_user_items.indices # <<<<<<<<<<<<<< * * cdef int * ids */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 249, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 257, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 249, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_4, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 257, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_test_indices = __pyx_t_7; __pyx_t_7.memview = NULL; __pyx_t_7.data = NULL; - /* "implicit/evaluation.pyx":253 + /* "implicit/evaluation.pyx":261 * cdef int * ids * cdef unordered_set[int] * likes * cdef double[:] cg = (1.0 / np.log2(np.arange(2, K + 2))) # <<<<<<<<<<<<<< * cdef double[:] cg_sum = np.cumsum(cg) * cdef double idcg */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 253, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_log2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_log2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_np); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 253, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_np); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_arange); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_arange); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_t_8 = __Pyx_PyInt_From_long((__pyx_v_K + 2)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_8 = __Pyx_PyInt_From_long((__pyx_v_K + 2)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); __pyx_t_10 = NULL; __pyx_t_6 = 0; @@ -5447,7 +5468,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #if CYTHON_FAST_PYCALL if (PyFunction_Check(__pyx_t_9)) { PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_int_2, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_9, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_9, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; @@ -5456,14 +5477,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #if CYTHON_FAST_PYCCALL if (__Pyx_PyFastCFunction_Check(__pyx_t_9)) { PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_int_2, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_9, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_9, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; } else #endif { - __pyx_t_11 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_11 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); if (__pyx_t_10) { __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_10); __pyx_t_10 = NULL; @@ -5474,7 +5495,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_6, __pyx_t_8); __pyx_t_8 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; } @@ -5492,31 +5513,31 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_t_4 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_9, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_1); __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 253, __pyx_L1_error) + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyFloat_TrueDivideCObj(__pyx_float_1_0, __pyx_t_4, 1.0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyFloat_TrueDivideCObj(__pyx_float_1_0, __pyx_t_4, 1.0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_12.memview)) __PYX_ERR(0, 253, __pyx_L1_error) + __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_12.memview)) __PYX_ERR(0, 261, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_cg = __pyx_t_12; __pyx_t_12.memview = NULL; __pyx_t_12.data = NULL; - /* "implicit/evaluation.pyx":254 + /* "implicit/evaluation.pyx":262 * cdef unordered_set[int] * likes * cdef double[:] cg = (1.0 / np.log2(np.arange(2, K + 2))) * cdef double[:] cg_sum = np.cumsum(cg) # <<<<<<<<<<<<<< * cdef double idcg * progress = tqdm(total=users, disable=not show_progress) */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 262, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_cumsum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 254, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_cumsum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 262, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_cg, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 254, __pyx_L1_error) + __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_cg, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 262, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_9 = NULL; if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) { @@ -5531,43 +5552,43 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_t_5 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_9, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 254, __pyx_L1_error) + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 262, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_12.memview)) __PYX_ERR(0, 254, __pyx_L1_error) + __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_12.memview)) __PYX_ERR(0, 262, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_cg_sum = __pyx_t_12; __pyx_t_12.memview = NULL; __pyx_t_12.data = NULL; - /* "implicit/evaluation.pyx":256 + /* "implicit/evaluation.pyx":264 * cdef double[:] cg_sum = np.cumsum(cg) * cdef double idcg * progress = tqdm(total=users, disable=not show_progress) # <<<<<<<<<<<<<< * * with nogil, parallel(num_threads=num_threads): */ - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 256, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 256, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_4) < 0) __PYX_ERR(0, 256, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_total, __pyx_t_4) < 0) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 256, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 256, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 264, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_4) < 0) __PYX_ERR(0, 256, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_disable, __pyx_t_4) < 0) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 256, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_progress = __pyx_t_4; __pyx_t_4 = 0; - /* "implicit/evaluation.pyx":258 + /* "implicit/evaluation.pyx":266 * progress = tqdm(total=users, disable=not show_progress) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -5606,7 +5627,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_v_ids = ((int *)1); __pyx_v_likes = ((std::unordered_set *)1); - /* "implicit/evaluation.pyx":259 + /* "implicit/evaluation.pyx":267 * * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) # <<<<<<<<<<<<<< @@ -5615,7 +5636,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ __pyx_v_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":260 + /* "implicit/evaluation.pyx":268 * with nogil, parallel(num_threads=num_threads): * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() # <<<<<<<<<<<<<< @@ -5632,11 +5653,11 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __PYX_ERR(0, 260, __pyx_L10_error) + __PYX_ERR(0, 268, __pyx_L10_error) } __pyx_v_likes = __pyx_t_13; - /* "implicit/evaluation.pyx":261 + /* "implicit/evaluation.pyx":269 * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() * try: # <<<<<<<<<<<<<< @@ -5645,7 +5666,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ /*try:*/ { - /* "implicit/evaluation.pyx":262 + /* "implicit/evaluation.pyx":270 * likes = new unordered_set[int]() * try: * for u in prange(users, schedule='guided'): # <<<<<<<<<<<<<< @@ -5678,7 +5699,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_v_i = ((int)0xbad0bad0); __pyx_v_idcg = ((double)__PYX_NAN()); - /* "implicit/evaluation.pyx":264 + /* "implicit/evaluation.pyx":272 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -5692,7 +5713,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_t_2 = (((*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_16 * __pyx_v_test_indptr.strides[0]) ))) == (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_17 * __pyx_v_test_indptr.strides[0]) )))) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":265 + /* "implicit/evaluation.pyx":273 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -5705,14 +5726,14 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #endif /*try:*/ { - /* "implicit/evaluation.pyx":266 + /* "implicit/evaluation.pyx":274 * if test_indptr[u] == test_indptr[u+1]: * with gil: * progress.update(1) # <<<<<<<<<<<<<< * continue * memset(ids, 0, sizeof(int) * K) */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 266, __pyx_L25_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 274, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -5726,13 +5747,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_5, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_int_1); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 266, __pyx_L25_error) + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 274, __pyx_L25_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } - /* "implicit/evaluation.pyx":265 + /* "implicit/evaluation.pyx":273 * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: * with gil: # <<<<<<<<<<<<<< @@ -5756,7 +5777,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } } - /* "implicit/evaluation.pyx":267 + /* "implicit/evaluation.pyx":275 * with gil: * progress.update(1) * continue # <<<<<<<<<<<<<< @@ -5765,7 +5786,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ goto __pyx_L17_continue; - /* "implicit/evaluation.pyx":264 + /* "implicit/evaluation.pyx":272 * for u in prange(users, schedule='guided'): * # if we don't have any test items, skip this user * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< @@ -5774,7 +5795,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ } - /* "implicit/evaluation.pyx":268 + /* "implicit/evaluation.pyx":276 * progress.update(1) * continue * memset(ids, 0, sizeof(int) * K) # <<<<<<<<<<<<<< @@ -5783,7 +5804,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ (void)(memset(__pyx_v_ids, 0, ((sizeof(int)) * __pyx_v_K))); - /* "implicit/evaluation.pyx":270 + /* "implicit/evaluation.pyx":278 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -5796,18 +5817,18 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #endif /*try:*/ { - /* "implicit/evaluation.pyx":271 + /* "implicit/evaluation.pyx":279 * * with gil: * recs = model.recommend(u, train_user_items, N=K) # <<<<<<<<<<<<<< * for i in range(len(recs)): * ids[i] = recs[i][0] */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); @@ -5815,13 +5836,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __Pyx_GIVEREF(__pyx_v_train_user_items); PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_train_user_items); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_9 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_9 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_9); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_9) < 0) __PYX_ERR(0, 271, __pyx_L30_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_N, __pyx_t_9) < 0) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 271, __pyx_L30_error) + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 279, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; @@ -5829,43 +5850,43 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __Pyx_XDECREF_SET(__pyx_v_recs, __pyx_t_9); __pyx_t_9 = 0; - /* "implicit/evaluation.pyx":272 + /* "implicit/evaluation.pyx":280 * with gil: * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): # <<<<<<<<<<<<<< * ids[i] = recs[i][0] * progress.update(1) */ - __pyx_t_18 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_18 == ((Py_ssize_t)-1))) __PYX_ERR(0, 272, __pyx_L30_error) + __pyx_t_18 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_18 == ((Py_ssize_t)-1))) __PYX_ERR(0, 280, __pyx_L30_error) __pyx_t_19 = __pyx_t_18; for (__pyx_t_20 = 0; __pyx_t_20 < __pyx_t_19; __pyx_t_20+=1) { __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":273 + /* "implicit/evaluation.pyx":281 * recs = model.recommend(u, train_user_items, N=K) * for i in range(len(recs)): * ids[i] = recs[i][0] # <<<<<<<<<<<<<< * progress.update(1) * */ - __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 273, __pyx_L30_error) + __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 281, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_9, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 273, __pyx_L30_error) + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_9, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 281, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_t_21 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_21 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 273, __pyx_L30_error) + __pyx_t_21 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_21 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 281, __pyx_L30_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; (__pyx_v_ids[__pyx_v_i]) = __pyx_t_21; } - /* "implicit/evaluation.pyx":274 + /* "implicit/evaluation.pyx":282 * for i in range(len(recs)): * ids[i] = recs[i][0] * progress.update(1) # <<<<<<<<<<<<<< * * # mostly we're going to be blocked on the gil here, */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 274, __pyx_L30_error) + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 282, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_9))) { @@ -5879,13 +5900,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_9, __pyx_t_5, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_int_1); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 274, __pyx_L30_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 282, __pyx_L30_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } - /* "implicit/evaluation.pyx":270 + /* "implicit/evaluation.pyx":278 * memset(ids, 0, sizeof(int) * K) * * with gil: # <<<<<<<<<<<<<< @@ -5909,7 +5930,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } } - /* "implicit/evaluation.pyx":278 + /* "implicit/evaluation.pyx":286 * # mostly we're going to be blocked on the gil here, * # so try to do actual scoring without it * likes.clear() # <<<<<<<<<<<<<< @@ -5918,7 +5939,7 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje */ __pyx_v_likes->clear(); - /* "implicit/evaluation.pyx":280 + /* "implicit/evaluation.pyx":288 * likes.clear() * * for i in range(test_indptr[u], test_indptr[u+1]): # <<<<<<<<<<<<<< @@ -5934,92 +5955,1387 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje for (__pyx_t_24 = (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_23 * __pyx_v_test_indptr.strides[0]) ))); __pyx_t_24 < __pyx_t_21; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24; - /* "implicit/evaluation.pyx":281 - * + /* "implicit/evaluation.pyx":289 + * + * for i in range(test_indptr[u], test_indptr[u+1]): + * likes.insert(test_indices[i]) # <<<<<<<<<<<<<< + * + * idcg = cg_sum[min(K, likes.size()) - 1] + */ + __pyx_t_25 = __pyx_v_i; + if (__pyx_t_25 < 0) __pyx_t_25 += __pyx_v_test_indices.shape[0]; + (void)(__pyx_v_likes->insert((*((int *) ( /* dim=0 */ (__pyx_v_test_indices.data + __pyx_t_25 * __pyx_v_test_indices.strides[0]) ))))); + } + + /* "implicit/evaluation.pyx":291 + * likes.insert(test_indices[i]) + * + * idcg = cg_sum[min(K, likes.size()) - 1] # <<<<<<<<<<<<<< + * for i in range(K): + * if likes.find(ids[i]) != likes.end(): + */ + __pyx_t_26 = __pyx_v_likes->size(); + __pyx_t_20 = __pyx_v_K; + if (((__pyx_t_26 < __pyx_t_20) != 0)) { + __pyx_t_27 = __pyx_t_26; + } else { + __pyx_t_27 = __pyx_t_20; + } + __pyx_t_26 = (__pyx_t_27 - 1); + __pyx_v_idcg = (*((double *) ( /* dim=0 */ (__pyx_v_cg_sum.data + __pyx_t_26 * __pyx_v_cg_sum.strides[0]) ))); + + /* "implicit/evaluation.pyx":292 + * + * idcg = cg_sum[min(K, likes.size()) - 1] + * for i in range(K): # <<<<<<<<<<<<<< + * if likes.find(ids[i]) != likes.end(): + * relevant += cg[i] / idcg + */ + __pyx_t_20 = __pyx_v_K; + __pyx_t_21 = __pyx_t_20; + for (__pyx_t_24 = 0; __pyx_t_24 < __pyx_t_21; __pyx_t_24+=1) { + __pyx_v_i = __pyx_t_24; + + /* "implicit/evaluation.pyx":293 + * idcg = cg_sum[min(K, likes.size()) - 1] + * for i in range(K): + * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< + * relevant += cg[i] / idcg + * total += 1 + */ + __pyx_t_2 = ((__pyx_v_likes->find((__pyx_v_ids[__pyx_v_i])) != __pyx_v_likes->end()) != 0); + if (__pyx_t_2) { + + /* "implicit/evaluation.pyx":294 + * for i in range(K): + * if likes.find(ids[i]) != likes.end(): + * relevant += cg[i] / idcg # <<<<<<<<<<<<<< + * total += 1 + * finally: + */ + __pyx_t_28 = __pyx_v_i; + if (__pyx_t_28 < 0) __pyx_t_28 += __pyx_v_cg.shape[0]; + __pyx_t_29 = (*((double *) ( /* dim=0 */ (__pyx_v_cg.data + __pyx_t_28 * __pyx_v_cg.strides[0]) ))); + if (unlikely(__pyx_v_idcg == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + __PYX_ERR(0, 294, __pyx_L19_error) + } + __pyx_v_relevant = (__pyx_v_relevant + (__pyx_t_29 / __pyx_v_idcg)); + + /* "implicit/evaluation.pyx":293 + * idcg = cg_sum[min(K, likes.size()) - 1] + * for i in range(K): + * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< + * relevant += cg[i] / idcg + * total += 1 + */ + } + } + + /* "implicit/evaluation.pyx":295 + * if likes.find(ids[i]) != likes.end(): + * relevant += cg[i] / idcg + * total += 1 # <<<<<<<<<<<<<< + * finally: + * free(ids) + */ + __pyx_v_total = (__pyx_v_total + 1.0); + goto __pyx_L40; + __pyx_L17_continue:; + goto __pyx_L40; + __pyx_L19_error:; + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + #ifdef _OPENMP + #pragma omp flush(__pyx_parallel_exc_type) + #endif /* _OPENMP */ + if (!__pyx_parallel_exc_type) { + __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb); + __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno; + __Pyx_GOTREF(__pyx_parallel_exc_type); + } + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + } + __pyx_parallel_why = 4; + goto __pyx_L39; + __pyx_L39:; + #ifdef _OPENMP + #pragma omp critical(__pyx_parallel_lastprivates2) + #endif /* _OPENMP */ + { + __pyx_parallel_temp0 = __pyx_v_i; + __pyx_parallel_temp1 = __pyx_v_idcg; + __pyx_parallel_temp2 = __pyx_v_relevant; + __pyx_parallel_temp3 = __pyx_v_total; + __pyx_parallel_temp4 = __pyx_v_u; + } + __pyx_L40:; + #ifdef _OPENMP + #pragma omp flush(__pyx_parallel_why) + #endif /* _OPENMP */ + } + } + } + if (__pyx_parallel_exc_type) { + /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */ + __pyx_parallel_why = 4; + } + if (__pyx_parallel_why) { + __pyx_v_i = __pyx_parallel_temp0; + __pyx_v_idcg = __pyx_parallel_temp1; + __pyx_v_relevant = __pyx_parallel_temp2; + __pyx_v_total = __pyx_parallel_temp3; + __pyx_v_u = __pyx_parallel_temp4; + switch (__pyx_parallel_why) { + case 4: + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_GIVEREF(__pyx_parallel_exc_type); + __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb); + __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + } + goto __pyx_L15_error; + } + } + } + } + + /* "implicit/evaluation.pyx":297 + * total += 1 + * finally: + * free(ids) # <<<<<<<<<<<<<< + * del likes + * + */ + /*finally:*/ { + /*normal exit:*/{ + free(__pyx_v_ids); + + /* "implicit/evaluation.pyx":298 + * finally: + * free(ids) + * del likes # <<<<<<<<<<<<<< + * + * progress.close() + */ + delete __pyx_v_likes; + goto __pyx_L16; + } + __pyx_L15_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save; + #endif + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_PyThreadState_assign + __pyx_t_31 = 0; __pyx_t_32 = 0; __pyx_t_33 = 0; __pyx_t_34 = 0; __pyx_t_35 = 0; __pyx_t_36 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_34, &__pyx_t_35, &__pyx_t_36); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_31, &__pyx_t_32, &__pyx_t_33) < 0)) __Pyx_ErrFetch(&__pyx_t_31, &__pyx_t_32, &__pyx_t_33); + __Pyx_XGOTREF(__pyx_t_31); + __Pyx_XGOTREF(__pyx_t_32); + __Pyx_XGOTREF(__pyx_t_33); + __Pyx_XGOTREF(__pyx_t_34); + __Pyx_XGOTREF(__pyx_t_35); + __Pyx_XGOTREF(__pyx_t_36); + __pyx_t_15 = __pyx_lineno; __pyx_t_14 = __pyx_clineno; __pyx_t_30 = __pyx_filename; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + { + + /* "implicit/evaluation.pyx":297 + * total += 1 + * finally: + * free(ids) # <<<<<<<<<<<<<< + * del likes + * + */ + free(__pyx_v_ids); + + /* "implicit/evaluation.pyx":298 + * finally: + * free(ids) + * del likes # <<<<<<<<<<<<<< + * + * progress.close() + */ + delete __pyx_v_likes; + } + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_34); + __Pyx_XGIVEREF(__pyx_t_35); + __Pyx_XGIVEREF(__pyx_t_36); + __Pyx_ExceptionReset(__pyx_t_34, __pyx_t_35, __pyx_t_36); + } + __Pyx_XGIVEREF(__pyx_t_31); + __Pyx_XGIVEREF(__pyx_t_32); + __Pyx_XGIVEREF(__pyx_t_33); + __Pyx_ErrRestore(__pyx_t_31, __pyx_t_32, __pyx_t_33); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + __pyx_t_31 = 0; __pyx_t_32 = 0; __pyx_t_33 = 0; __pyx_t_34 = 0; __pyx_t_35 = 0; __pyx_t_36 = 0; + __pyx_lineno = __pyx_t_15; __pyx_clineno = __pyx_t_14; __pyx_filename = __pyx_t_30; + goto __pyx_L10_error; + } + __pyx_L16:; + } + goto __pyx_L46; + __pyx_L10_error:; + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + #ifdef _OPENMP + #pragma omp flush(__pyx_parallel_exc_type) + #endif /* _OPENMP */ + if (!__pyx_parallel_exc_type) { + __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb); + __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno; + __Pyx_GOTREF(__pyx_parallel_exc_type); + } + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + } + __pyx_parallel_why = 4; + goto __pyx_L46; + __pyx_L46:; + #ifdef _OPENMP + Py_END_ALLOW_THREADS + #else +{ +#ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + #endif /* _OPENMP */ + /* Clean up any temporaries */ + __Pyx_XDECREF(__pyx_t_1); + __pyx_t_1 = NULL; + __Pyx_XDECREF(__pyx_t_31); + __pyx_t_31 = NULL; + __Pyx_XDECREF(__pyx_t_32); + __pyx_t_32 = NULL; + __Pyx_XDECREF(__pyx_t_33); + __pyx_t_33 = NULL; + __Pyx_XDECREF(__pyx_t_34); + __pyx_t_34 = NULL; + __Pyx_XDECREF(__pyx_t_35); + __pyx_t_35 = NULL; + __Pyx_XDECREF(__pyx_t_36); + __pyx_t_36 = NULL; + __Pyx_XDECREF(__pyx_t_4); + __pyx_t_4 = NULL; + __Pyx_XDECREF(__pyx_t_5); + __pyx_t_5 = NULL; + __Pyx_XDECREF(__pyx_t_9); + __pyx_t_9 = NULL; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + #ifndef _OPENMP +} +#endif /* _OPENMP */ + } + if (__pyx_parallel_exc_type) { + /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */ + __pyx_parallel_why = 4; + } + if (__pyx_parallel_why) { + switch (__pyx_parallel_why) { + case 4: + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_GIVEREF(__pyx_parallel_exc_type); + __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb); + __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + } + goto __pyx_L6_error; + } + } + } + #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) + #undef likely + #undef unlikely + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) + #endif + } + + /* "implicit/evaluation.pyx":266 + * progress = tqdm(total=users, disable=not show_progress) + * + * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< + * ids = malloc(sizeof(int) * K) + * likes = new unordered_set[int]() + */ + /*finally:*/ { + /*normal exit:*/{ + #ifdef WITH_THREAD + __Pyx_FastGIL_Forget(); + Py_BLOCK_THREADS + #endif + goto __pyx_L7; + } + __pyx_L6_error: { + #ifdef WITH_THREAD + __Pyx_FastGIL_Forget(); + Py_BLOCK_THREADS + #endif + goto __pyx_L1_error; + } + __pyx_L7:; + } + } + + /* "implicit/evaluation.pyx":300 + * del likes + * + * progress.close() # <<<<<<<<<<<<<< + * return relevant / total + * + */ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + } + } + __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "implicit/evaluation.pyx":301 + * + * progress.close() + * return relevant / total # <<<<<<<<<<<<<< + * + * @cython.boundscheck(False) + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_total == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 301, __pyx_L1_error) + } + __pyx_t_1 = PyFloat_FromDouble((__pyx_v_relevant / __pyx_v_total)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 301, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "implicit/evaluation.pyx":221 + * + * @cython.boundscheck(False) + * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): + * """ Calculates ndcg@K for a given trained model + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1); + __Pyx_AddTraceback("implicit.evaluation.ndcg_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __PYX_XDEC_MEMVIEW(&__pyx_v_test_indptr, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_test_indices, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_cg, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_cg_sum, 1); + __Pyx_XDECREF(__pyx_v_progress); + __Pyx_XDECREF(__pyx_v_recs); + __Pyx_XDECREF(__pyx_v_train_user_items); + __Pyx_XDECREF(__pyx_v_test_user_items); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "implicit/evaluation.pyx":304 + * + * @cython.boundscheck(False) + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): + * """ Calculates ndcg@K for a given trained model + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_8implicit_10evaluation_9AUC_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_8implicit_10evaluation_8AUC_at_k[] = " Calculates ndcg@K for a given trained model\n\n Parameters\n ----------\n model : RecommenderBase\n The fitted recommendation model to test\n train_user_items : csr_matrix\n Sparse matrix of user by item that contains elements that were used in training the model\n test_user_items : csr_matrix\n Sparse matrix of user by item that contains withheld elements to test on\n K : int\n Number of items to test on\n show_progress : bool, optional\n Whether to show a progress bar\n num_threads : int, optional\n The number of threads to use for testing. Specifying 0 means to default\n to the number of cores on the machine. Note: aside from the ALS and BPR\n models, setting this to more than 1 will likely hurt performance rather than\n help.\n\n Returns\n -------\n float\n the calculated ndcg@k\n "; +static PyMethodDef __pyx_mdef_8implicit_10evaluation_9AUC_at_k = {"AUC_at_k", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8implicit_10evaluation_9AUC_at_k, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8implicit_10evaluation_8AUC_at_k}; +static PyObject *__pyx_pw_8implicit_10evaluation_9AUC_at_k(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_model = 0; + PyObject *__pyx_v_train_user_items = 0; + PyObject *__pyx_v_test_user_items = 0; + int __pyx_v_K; + PyObject *__pyx_v_show_progress = 0; + int __pyx_v_num_threads; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("AUC_at_k (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_model,&__pyx_n_s_train_user_items,&__pyx_n_s_test_user_items,&__pyx_n_s_K,&__pyx_n_s_show_progress,&__pyx_n_s_num_threads,0}; + PyObject* values[6] = {0,0,0,0,0,0}; + + /* "implicit/evaluation.pyx":305 + * @cython.boundscheck(False) + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, + * show_progress=True, int num_threads=1): # <<<<<<<<<<<<<< + * """ Calculates ndcg@K for a given trained model + * + */ + values[4] = ((PyObject *)Py_True); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + 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_model)) != 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_train_user_items)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("AUC_at_k", 0, 3, 6, 1); __PYX_ERR(0, 304, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test_user_items)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("AUC_at_k", 0, 3, 6, 2); __PYX_ERR(0, 304, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_K); + if (value) { values[3] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_show_progress); + if (value) { values[4] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 5: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_num_threads); + if (value) { values[5] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "AUC_at_k") < 0)) __PYX_ERR(0, 304, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + 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_model = values[0]; + __pyx_v_train_user_items = values[1]; + __pyx_v_test_user_items = values[2]; + if (values[3]) { + __pyx_v_K = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_K == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 304, __pyx_L3_error) + } else { + __pyx_v_K = ((int)10); + } + __pyx_v_show_progress = values[4]; + if (values[5]) { + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 305, __pyx_L3_error) + } else { + __pyx_v_num_threads = ((int)1); + } + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("AUC_at_k", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 304, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("implicit.evaluation.AUC_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_8implicit_10evaluation_8AUC_at_k(__pyx_self, __pyx_v_model, __pyx_v_train_user_items, __pyx_v_test_user_items, __pyx_v_K, __pyx_v_show_progress, __pyx_v_num_threads); + + /* "implicit/evaluation.pyx":304 + * + * @cython.boundscheck(False) + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): + * """ Calculates ndcg@K for a given trained model + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_8implicit_10evaluation_8AUC_at_k(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_model, PyObject *__pyx_v_train_user_items, PyObject *__pyx_v_test_user_items, int __pyx_v_K, PyObject *__pyx_v_show_progress, int __pyx_v_num_threads) { + int __pyx_v_users; + int __pyx_v_u; + int __pyx_v_i; + int __pyx_v_items; + double __pyx_v_total; + __Pyx_memviewslice __pyx_v_test_indptr = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_test_indices = { 0, 0, { 0 }, { 0 }, { 0 } }; + int *__pyx_v_ids; + std::unordered_set *__pyx_v_likes; + PyObject *__pyx_v_progress = NULL; + float *__pyx_v__auc_list; + int __pyx_v___auc; + int __pyx_v___relevant; + int __pyx_v___miss; + int __pyx_v___num_pos_items; + int __pyx_v___num_neg_items; + float __pyx_v_auc; + PyObject *__pyx_v_recs = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } }; + std::unordered_set *__pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + Py_ssize_t __pyx_t_11; + Py_ssize_t __pyx_t_12; + PyObject *__pyx_t_13 = NULL; + Py_ssize_t __pyx_t_14; + Py_ssize_t __pyx_t_15; + int __pyx_t_16; + int __pyx_t_17; + Py_ssize_t __pyx_t_18; + Py_ssize_t __pyx_t_19; + int __pyx_t_20; + Py_ssize_t __pyx_t_21; + int __pyx_t_22; + float __pyx_t_23; + char const *__pyx_t_24; + PyObject *__pyx_t_25 = NULL; + PyObject *__pyx_t_26 = NULL; + PyObject *__pyx_t_27 = NULL; + PyObject *__pyx_t_28 = NULL; + PyObject *__pyx_t_29 = NULL; + PyObject *__pyx_t_30 = NULL; + __Pyx_RefNannySetupContext("AUC_at_k", 0); + __Pyx_INCREF(__pyx_v_train_user_items); + __Pyx_INCREF(__pyx_v_test_user_items); + + /* "implicit/evaluation.pyx":331 + * the calculated ndcg@k + * """ + * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< + * train_user_items = train_user_items.tocsr() + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_IsInstance(__pyx_v_train_user_items, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); + if (__pyx_t_3) { + + /* "implicit/evaluation.pyx":332 + * """ + * if not isinstance(train_user_items, csr_matrix): + * train_user_items = train_user_items.tocsr() # <<<<<<<<<<<<<< + * + * if not isinstance(test_user_items, csr_matrix): + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_train_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF_SET(__pyx_v_train_user_items, __pyx_t_1); + __pyx_t_1 = 0; + + /* "implicit/evaluation.pyx":331 + * the calculated ndcg@k + * """ + * if not isinstance(train_user_items, csr_matrix): # <<<<<<<<<<<<<< + * train_user_items = train_user_items.tocsr() + * + */ + } + + /* "implicit/evaluation.pyx":334 + * train_user_items = train_user_items.tocsr() + * + * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< + * test_user_items = test_user_items.tocsr() + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_csr_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_IsInstance(__pyx_v_test_user_items, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 334, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); + if (__pyx_t_2) { + + /* "implicit/evaluation.pyx":335 + * + * if not isinstance(test_user_items, csr_matrix): + * test_user_items = test_user_items.tocsr() # <<<<<<<<<<<<<< + * + * cdef int users = test_user_items.shape[0], u, i + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_tocsr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 335, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF_SET(__pyx_v_test_user_items, __pyx_t_1); + __pyx_t_1 = 0; + + /* "implicit/evaluation.pyx":334 + * train_user_items = train_user_items.tocsr() + * + * if not isinstance(test_user_items, csr_matrix): # <<<<<<<<<<<<<< + * test_user_items = test_user_items.tocsr() + * + */ + } + + /* "implicit/evaluation.pyx":337 + * test_user_items = test_user_items.tocsr() + * + * cdef int users = test_user_items.shape[0], u, i # <<<<<<<<<<<<<< + * cdef int items = test_user_items.shape[1] + * cdef double total = 0 + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 337, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_users = __pyx_t_6; + + /* "implicit/evaluation.pyx":338 + * + * cdef int users = test_user_items.shape[0], u, i + * cdef int items = test_user_items.shape[1] # <<<<<<<<<<<<<< + * cdef double total = 0 + * cdef int[:] test_indptr = test_user_items.indptr + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 338, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_4, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 338, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 338, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_items = __pyx_t_6; + + /* "implicit/evaluation.pyx":339 + * cdef int users = test_user_items.shape[0], u, i + * cdef int items = test_user_items.shape[1] + * cdef double total = 0 # <<<<<<<<<<<<<< + * cdef int[:] test_indptr = test_user_items.indptr + * cdef int[:] test_indices = test_user_items.indices + */ + __pyx_v_total = 0.0; + + /* "implicit/evaluation.pyx":340 + * cdef int items = test_user_items.shape[1] + * cdef double total = 0 + * cdef int[:] test_indptr = test_user_items.indptr # <<<<<<<<<<<<<< + * cdef int[:] test_indices = test_user_items.indices + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indptr); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 340, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_test_indptr = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + + /* "implicit/evaluation.pyx":341 + * cdef double total = 0 + * cdef int[:] test_indptr = test_user_items.indptr + * cdef int[:] test_indices = test_user_items.indices # <<<<<<<<<<<<<< + * + * cdef int * ids + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_test_user_items, __pyx_n_s_indices); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 341, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 341, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_test_indices = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + + /* "implicit/evaluation.pyx":346 + * cdef unordered_set[int] * likes + * + * progress = tqdm(total=users, disable=not show_progress) # <<<<<<<<<<<<<< + * cdef float* _auc_list + * cdef int __auc = 0, __relevant = 1, __miss = 2, __num_pos_items = 3, __num_neg_items = 4 + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_tqdm); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_users); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_total, __pyx_t_5) < 0) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_show_progress); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 346, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_disable, __pyx_t_5) < 0) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_progress = __pyx_t_5; + __pyx_t_5 = 0; + + /* "implicit/evaluation.pyx":348 + * progress = tqdm(total=users, disable=not show_progress) + * cdef float* _auc_list + * cdef int __auc = 0, __relevant = 1, __miss = 2, __num_pos_items = 3, __num_neg_items = 4 # <<<<<<<<<<<<<< + * cdef float auc + * with nogil, parallel(num_threads=num_threads): + */ + __pyx_v___auc = 0; + __pyx_v___relevant = 1; + __pyx_v___miss = 2; + __pyx_v___num_pos_items = 3; + __pyx_v___num_neg_items = 4; + + /* "implicit/evaluation.pyx":350 + * cdef int __auc = 0, __relevant = 1, __miss = 2, __num_pos_items = 3, __num_neg_items = 4 + * cdef float auc + * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< + * ids = malloc(sizeof(int) * K) + * likes = new unordered_set[int]() + */ + { + #ifdef WITH_THREAD + PyThreadState *_save; + Py_UNBLOCK_THREADS + __Pyx_FastGIL_Remember(); + #endif + /*try:*/ { + { + const char *__pyx_parallel_filename = NULL; int __pyx_parallel_lineno = 0, __pyx_parallel_clineno = 0; + PyObject *__pyx_parallel_exc_type = NULL, *__pyx_parallel_exc_value = NULL, *__pyx_parallel_exc_tb = NULL; + int __pyx_parallel_why; + __pyx_parallel_why = 0; + #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) + #undef likely + #undef unlikely + #define likely(x) (x) + #define unlikely(x) (x) + #endif + #ifdef _OPENMP + #pragma omp parallel private(__pyx_v__auc_list, __pyx_v_ids, __pyx_v_likes) reduction(+:__pyx_v_auc) reduction(+:__pyx_v_total) private(__pyx_t_10, __pyx_t_11, __pyx_t_12, __pyx_t_14, __pyx_t_15, __pyx_t_16, __pyx_t_17, __pyx_t_18, __pyx_t_19, __pyx_t_2, __pyx_t_20, __pyx_t_21, __pyx_t_22, __pyx_t_23, __pyx_t_24, __pyx_t_6, __pyx_t_8, __pyx_t_9) firstprivate(__pyx_t_1, __pyx_t_13, __pyx_t_25, __pyx_t_26, __pyx_t_27, __pyx_t_28, __pyx_t_29, __pyx_t_30, __pyx_t_4, __pyx_t_5) private(__pyx_filename, __pyx_lineno, __pyx_clineno) shared(__pyx_parallel_why, __pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb) num_threads(__pyx_v_num_threads) + #endif /* _OPENMP */ + { + #ifdef _OPENMP + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + Py_BEGIN_ALLOW_THREADS + #endif /* _OPENMP */ + /* Initialize private variables to invalid values */ + __pyx_v__auc_list = ((float *)1); + __pyx_v_ids = ((int *)1); + __pyx_v_likes = ((std::unordered_set *)1); + + /* "implicit/evaluation.pyx":351 + * cdef float auc + * with nogil, parallel(num_threads=num_threads): + * ids = malloc(sizeof(int) * K) # <<<<<<<<<<<<<< + * likes = new unordered_set[int]() + * _auc_list = malloc(sizeof(float) * 5) + */ + __pyx_v_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_K))); + + /* "implicit/evaluation.pyx":352 + * with nogil, parallel(num_threads=num_threads): + * ids = malloc(sizeof(int) * K) + * likes = new unordered_set[int]() # <<<<<<<<<<<<<< + * _auc_list = malloc(sizeof(float) * 5) + * try: + */ + try { + __pyx_t_8 = new std::unordered_set (); + } catch(...) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_CppExn2PyErr(); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + __PYX_ERR(0, 352, __pyx_L10_error) + } + __pyx_v_likes = __pyx_t_8; + + /* "implicit/evaluation.pyx":353 + * ids = malloc(sizeof(int) * K) + * likes = new unordered_set[int]() + * _auc_list = malloc(sizeof(float) * 5) # <<<<<<<<<<<<<< + * try: + * for u in prange(users, schedule='guided'): + */ + __pyx_v__auc_list = ((float *)malloc(((sizeof(float)) * 5))); + + /* "implicit/evaluation.pyx":354 + * likes = new unordered_set[int]() + * _auc_list = malloc(sizeof(float) * 5) + * try: # <<<<<<<<<<<<<< + * for u in prange(users, schedule='guided'): + * # if we don't have any test items, skip this user + */ + /*try:*/ { + + /* "implicit/evaluation.pyx":355 + * _auc_list = malloc(sizeof(float) * 5) + * try: + * for u in prange(users, schedule='guided'): # <<<<<<<<<<<<<< + * # if we don't have any test items, skip this user + * if test_indptr[u] == test_indptr[u+1]: + */ + __pyx_t_6 = __pyx_v_users; + if (1 == 0) abort(); + { + float __pyx_parallel_temp0 = ((float)__PYX_NAN()); + int __pyx_parallel_temp1 = ((int)0xbad0bad0); + double __pyx_parallel_temp2 = ((double)__PYX_NAN()); + int __pyx_parallel_temp3 = ((int)0xbad0bad0); + const char *__pyx_parallel_filename = NULL; int __pyx_parallel_lineno = 0, __pyx_parallel_clineno = 0; + PyObject *__pyx_parallel_exc_type = NULL, *__pyx_parallel_exc_value = NULL, *__pyx_parallel_exc_tb = NULL; + int __pyx_parallel_why; + __pyx_parallel_why = 0; + __pyx_t_10 = (__pyx_t_6 - 0 + 1 - 1/abs(1)) / 1; + if (__pyx_t_10 > 0) + { + #ifdef _OPENMP + #pragma omp for lastprivate(__pyx_v_i) firstprivate(__pyx_v_u) lastprivate(__pyx_v_u) schedule(guided) + #endif /* _OPENMP */ + for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_10; __pyx_t_9++){ + if (__pyx_parallel_why < 2) + { + __pyx_v_u = (int)(0 + 1 * __pyx_t_9); + /* Initialize private variables to invalid values */ + __pyx_v_i = ((int)0xbad0bad0); + + /* "implicit/evaluation.pyx":357 + * for u in prange(users, schedule='guided'): + * # if we don't have any test items, skip this user + * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< + * with gil: + * progress.update(1) + */ + __pyx_t_11 = __pyx_v_u; + if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_test_indptr.shape[0]; + __pyx_t_12 = (__pyx_v_u + 1); + if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_test_indptr.shape[0]; + __pyx_t_2 = (((*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_11 * __pyx_v_test_indptr.strides[0]) ))) == (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_12 * __pyx_v_test_indptr.strides[0]) )))) != 0); + if (__pyx_t_2) { + + /* "implicit/evaluation.pyx":358 + * # if we don't have any test items, skip this user + * if test_indptr[u] == test_indptr[u+1]: + * with gil: # <<<<<<<<<<<<<< + * progress.update(1) + * continue + */ + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + /*try:*/ { + + /* "implicit/evaluation.pyx":359 + * if test_indptr[u] == test_indptr[u+1]: + * with gil: + * progress.update(1) # <<<<<<<<<<<<<< + * continue + * memset(ids, 0, sizeof(int) * K) + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 359, __pyx_L25_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_5 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_1, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_int_1); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 359, __pyx_L25_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + + /* "implicit/evaluation.pyx":358 + * # if we don't have any test items, skip this user + * if test_indptr[u] == test_indptr[u+1]: + * with gil: # <<<<<<<<<<<<<< + * progress.update(1) + * continue + */ + /*finally:*/ { + /*normal exit:*/{ + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + goto __pyx_L26; + } + __pyx_L25_error: { + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + goto __pyx_L19_error; + } + __pyx_L26:; + } + } + + /* "implicit/evaluation.pyx":360 + * with gil: + * progress.update(1) + * continue # <<<<<<<<<<<<<< + * memset(ids, 0, sizeof(int) * K) + * memset(_auc_list, 0, sizeof(float) * 5) + */ + goto __pyx_L17_continue; + + /* "implicit/evaluation.pyx":357 + * for u in prange(users, schedule='guided'): + * # if we don't have any test items, skip this user + * if test_indptr[u] == test_indptr[u+1]: # <<<<<<<<<<<<<< + * with gil: + * progress.update(1) + */ + } + + /* "implicit/evaluation.pyx":361 + * progress.update(1) + * continue + * memset(ids, 0, sizeof(int) * K) # <<<<<<<<<<<<<< + * memset(_auc_list, 0, sizeof(float) * 5) + * with gil: + */ + (void)(memset(__pyx_v_ids, 0, ((sizeof(int)) * __pyx_v_K))); + + /* "implicit/evaluation.pyx":362 + * continue + * memset(ids, 0, sizeof(int) * K) + * memset(_auc_list, 0, sizeof(float) * 5) # <<<<<<<<<<<<<< + * with gil: + * recs = model.recommend(u, train_user_items, N=K) + */ + (void)(memset(__pyx_v__auc_list, 0, ((sizeof(float)) * 5))); + + /* "implicit/evaluation.pyx":363 + * memset(ids, 0, sizeof(int) * K) + * memset(_auc_list, 0, sizeof(float) * 5) + * with gil: # <<<<<<<<<<<<<< + * recs = model.recommend(u, train_user_items, N=K) + * for i in range(len(recs)): + */ + { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + /*try:*/ { + + /* "implicit/evaluation.pyx":364 + * memset(_auc_list, 0, sizeof(float) * 5) + * with gil: + * recs = model.recommend(u, train_user_items, N=K) # <<<<<<<<<<<<<< + * for i in range(len(recs)): + * ids[i] = recs[i][0] + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_model, __pyx_n_s_recommend); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_u); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4); + __Pyx_INCREF(__pyx_v_train_user_items); + __Pyx_GIVEREF(__pyx_v_train_user_items); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_train_user_items); + __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_K); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_13); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_N, __pyx_t_13) < 0) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 364, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_recs, __pyx_t_13); + __pyx_t_13 = 0; + + /* "implicit/evaluation.pyx":365 + * with gil: + * recs = model.recommend(u, train_user_items, N=K) + * for i in range(len(recs)): # <<<<<<<<<<<<<< + * ids[i] = recs[i][0] + * progress.update(1) + */ + __pyx_t_14 = PyObject_Length(__pyx_v_recs); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 365, __pyx_L30_error) + __pyx_t_15 = __pyx_t_14; + for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) { + __pyx_v_i = __pyx_t_16; + + /* "implicit/evaluation.pyx":366 + * recs = model.recommend(u, train_user_items, N=K) + * for i in range(len(recs)): + * ids[i] = recs[i][0] # <<<<<<<<<<<<<< + * progress.update(1) + * + */ + __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_recs, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 366, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_13, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 366, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_17 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_17 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 366, __pyx_L30_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + (__pyx_v_ids[__pyx_v_i]) = __pyx_t_17; + } + + /* "implicit/evaluation.pyx":367 + * for i in range(len(recs)): + * ids[i] = recs[i][0] + * progress.update(1) # <<<<<<<<<<<<<< + * + * # mostly we're going to be blocked on the gil here, + */ + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_update); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 367, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_1 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_13); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_13, function); + } + } + __pyx_t_4 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_13, __pyx_t_1, __pyx_int_1) : __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_int_1); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 367, __pyx_L30_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + + /* "implicit/evaluation.pyx":363 + * memset(ids, 0, sizeof(int) * K) + * memset(_auc_list, 0, sizeof(float) * 5) + * with gil: # <<<<<<<<<<<<<< + * recs = model.recommend(u, train_user_items, N=K) + * for i in range(len(recs)): + */ + /*finally:*/ { + /*normal exit:*/{ + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + goto __pyx_L31; + } + __pyx_L30_error: { + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + goto __pyx_L19_error; + } + __pyx_L31:; + } + } + + /* "implicit/evaluation.pyx":371 + * # mostly we're going to be blocked on the gil here, + * # so try to do actual scoring without it + * likes.clear() # <<<<<<<<<<<<<< + * + * for i in range(test_indptr[u], test_indptr[u+1]): + */ + __pyx_v_likes->clear(); + + /* "implicit/evaluation.pyx":373 + * likes.clear() + * + * for i in range(test_indptr[u], test_indptr[u+1]): # <<<<<<<<<<<<<< + * likes.insert(test_indices[i]) + * _auc_list[__num_pos_items] = likes.size() + */ + __pyx_t_18 = (__pyx_v_u + 1); + if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_test_indptr.shape[0]; + __pyx_t_16 = (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_18 * __pyx_v_test_indptr.strides[0]) ))); + __pyx_t_19 = __pyx_v_u; + if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_test_indptr.shape[0]; + __pyx_t_17 = __pyx_t_16; + for (__pyx_t_20 = (*((int *) ( /* dim=0 */ (__pyx_v_test_indptr.data + __pyx_t_19 * __pyx_v_test_indptr.strides[0]) ))); __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { + __pyx_v_i = __pyx_t_20; + + /* "implicit/evaluation.pyx":374 + * + * for i in range(test_indptr[u], test_indptr[u+1]): + * likes.insert(test_indices[i]) # <<<<<<<<<<<<<< + * _auc_list[__num_pos_items] = likes.size() + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] + */ + __pyx_t_21 = __pyx_v_i; + if (__pyx_t_21 < 0) __pyx_t_21 += __pyx_v_test_indices.shape[0]; + (void)(__pyx_v_likes->insert((*((int *) ( /* dim=0 */ (__pyx_v_test_indices.data + __pyx_t_21 * __pyx_v_test_indices.strides[0]) ))))); + } + + /* "implicit/evaluation.pyx":375 * for i in range(test_indptr[u], test_indptr[u+1]): - * likes.insert(test_indices[i]) # <<<<<<<<<<<<<< - * - * + * likes.insert(test_indices[i]) + * _auc_list[__num_pos_items] = likes.size() # <<<<<<<<<<<<<< + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] + * for i in range(K): */ - __pyx_t_25 = __pyx_v_i; - if (__pyx_t_25 < 0) __pyx_t_25 += __pyx_v_test_indices.shape[0]; - (void)(__pyx_v_likes->insert((*((int *) ( /* dim=0 */ (__pyx_v_test_indices.data + __pyx_t_25 * __pyx_v_test_indices.strides[0]) ))))); - } + (__pyx_v__auc_list[__pyx_v___num_pos_items]) = __pyx_v_likes->size(); - /* "implicit/evaluation.pyx":284 - * - * - * idcg = cg_sum[min(K, likes.size())] # <<<<<<<<<<<<<< + /* "implicit/evaluation.pyx":376 + * likes.insert(test_indices[i]) + * _auc_list[__num_pos_items] = likes.size() + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] # <<<<<<<<<<<<<< * for i in range(K): * if likes.find(ids[i]) != likes.end(): */ - __pyx_t_26 = __pyx_v_likes->size(); - __pyx_t_20 = __pyx_v_K; - if (((__pyx_t_26 < __pyx_t_20) != 0)) { - __pyx_t_27 = __pyx_t_26; - } else { - __pyx_t_27 = __pyx_t_20; - } - __pyx_t_26 = __pyx_t_27; - __pyx_v_idcg = (*((double *) ( /* dim=0 */ (__pyx_v_cg_sum.data + __pyx_t_26 * __pyx_v_cg_sum.strides[0]) ))); + (__pyx_v__auc_list[__pyx_v___num_neg_items]) = (__pyx_v_items - (__pyx_v__auc_list[__pyx_v___num_pos_items])); - /* "implicit/evaluation.pyx":285 - * - * idcg = cg_sum[min(K, likes.size())] + /* "implicit/evaluation.pyx":377 + * _auc_list[__num_pos_items] = likes.size() + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] * for i in range(K): # <<<<<<<<<<<<<< * if likes.find(ids[i]) != likes.end(): - * relevant += cg[i] / idcg + * _auc_list[__relevant] += 1 */ - __pyx_t_20 = __pyx_v_K; - __pyx_t_21 = __pyx_t_20; - for (__pyx_t_24 = 0; __pyx_t_24 < __pyx_t_21; __pyx_t_24+=1) { - __pyx_v_i = __pyx_t_24; + __pyx_t_16 = __pyx_v_K; + __pyx_t_17 = __pyx_t_16; + for (__pyx_t_20 = 0; __pyx_t_20 < __pyx_t_17; __pyx_t_20+=1) { + __pyx_v_i = __pyx_t_20; - /* "implicit/evaluation.pyx":286 - * idcg = cg_sum[min(K, likes.size())] + /* "implicit/evaluation.pyx":378 + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< - * relevant += cg[i] / idcg - * #total += cg[i] + * _auc_list[__relevant] += 1 + * else: */ __pyx_t_2 = ((__pyx_v_likes->find((__pyx_v_ids[__pyx_v_i])) != __pyx_v_likes->end()) != 0); if (__pyx_t_2) { - /* "implicit/evaluation.pyx":287 + /* "implicit/evaluation.pyx":379 * for i in range(K): * if likes.find(ids[i]) != likes.end(): - * relevant += cg[i] / idcg # <<<<<<<<<<<<<< - * #total += cg[i] - * total += 1 + * _auc_list[__relevant] += 1 # <<<<<<<<<<<<<< + * else: + * _auc_list[__miss] += 1 */ - __pyx_t_28 = __pyx_v_i; - if (__pyx_t_28 < 0) __pyx_t_28 += __pyx_v_cg.shape[0]; - __pyx_t_29 = (*((double *) ( /* dim=0 */ (__pyx_v_cg.data + __pyx_t_28 * __pyx_v_cg.strides[0]) ))); - if (unlikely(__pyx_v_idcg == 0)) { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - __PYX_ERR(0, 287, __pyx_L19_error) - } - __pyx_v_relevant = (__pyx_v_relevant + (__pyx_t_29 / __pyx_v_idcg)); + __pyx_t_22 = __pyx_v___relevant; + (__pyx_v__auc_list[__pyx_t_22]) = ((__pyx_v__auc_list[__pyx_t_22]) + 1.0); - /* "implicit/evaluation.pyx":286 - * idcg = cg_sum[min(K, likes.size())] + /* "implicit/evaluation.pyx":378 + * _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] * for i in range(K): * if likes.find(ids[i]) != likes.end(): # <<<<<<<<<<<<<< - * relevant += cg[i] / idcg - * #total += cg[i] + * _auc_list[__relevant] += 1 + * else: */ + goto __pyx_L38; + } + + /* "implicit/evaluation.pyx":381 + * _auc_list[__relevant] += 1 + * else: + * _auc_list[__miss] += 1 # <<<<<<<<<<<<<< + * _auc_list[__auc] += _auc_list[__relevant] + * _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) * (_auc_list[__num_neg_items] - _auc_list[__miss]) + */ + /*else*/ { + __pyx_t_22 = __pyx_v___miss; + (__pyx_v__auc_list[__pyx_t_22]) = ((__pyx_v__auc_list[__pyx_t_22]) + 1.0); + + /* "implicit/evaluation.pyx":382 + * else: + * _auc_list[__miss] += 1 + * _auc_list[__auc] += _auc_list[__relevant] # <<<<<<<<<<<<<< + * _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) * (_auc_list[__num_neg_items] - _auc_list[__miss]) + * _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) + */ + __pyx_t_22 = __pyx_v___auc; + (__pyx_v__auc_list[__pyx_t_22]) = ((__pyx_v__auc_list[__pyx_t_22]) + (__pyx_v__auc_list[__pyx_v___relevant])); } + __pyx_L38:; } - /* "implicit/evaluation.pyx":289 - * relevant += cg[i] / idcg - * #total += cg[i] + /* "implicit/evaluation.pyx":383 + * _auc_list[__miss] += 1 + * _auc_list[__auc] += _auc_list[__relevant] + * _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) * (_auc_list[__num_neg_items] - _auc_list[__miss]) # <<<<<<<<<<<<<< + * _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) + * auc += _auc_list[__auc] + */ + __pyx_t_16 = __pyx_v___auc; + (__pyx_v__auc_list[__pyx_t_16]) = ((__pyx_v__auc_list[__pyx_t_16]) + ((((double)((__pyx_v__auc_list[__pyx_v___relevant]) + (__pyx_v__auc_list[__pyx_v___num_pos_items]))) / 2.0) * ((__pyx_v__auc_list[__pyx_v___num_neg_items]) - (__pyx_v__auc_list[__pyx_v___miss])))); + + /* "implicit/evaluation.pyx":384 + * _auc_list[__auc] += _auc_list[__relevant] + * _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) * (_auc_list[__num_neg_items] - _auc_list[__miss]) + * _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) # <<<<<<<<<<<<<< + * auc += _auc_list[__auc] + * total += 1 + */ + __pyx_t_16 = __pyx_v___auc; + __pyx_t_23 = ((__pyx_v__auc_list[__pyx_v___num_pos_items]) * (__pyx_v__auc_list[__pyx_v___num_neg_items])); + if (unlikely(__pyx_t_23 == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + __PYX_ERR(0, 384, __pyx_L19_error) + } + (__pyx_v__auc_list[__pyx_t_16]) = ((__pyx_v__auc_list[__pyx_t_16]) / __pyx_t_23); + + /* "implicit/evaluation.pyx":385 + * _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) * (_auc_list[__num_neg_items] - _auc_list[__miss]) + * _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) + * auc += _auc_list[__auc] # <<<<<<<<<<<<<< + * total += 1 + * finally: + */ + __pyx_v_auc = (__pyx_v_auc + (__pyx_v__auc_list[__pyx_v___auc])); + + /* "implicit/evaluation.pyx":386 + * _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) + * auc += _auc_list[__auc] * total += 1 # <<<<<<<<<<<<<< * finally: * free(ids) @@ -6049,14 +7365,13 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje goto __pyx_L39; __pyx_L39:; #ifdef _OPENMP - #pragma omp critical(__pyx_parallel_lastprivates2) + #pragma omp critical(__pyx_parallel_lastprivates3) #endif /* _OPENMP */ { - __pyx_parallel_temp0 = __pyx_v_i; - __pyx_parallel_temp1 = __pyx_v_idcg; - __pyx_parallel_temp2 = __pyx_v_relevant; - __pyx_parallel_temp3 = __pyx_v_total; - __pyx_parallel_temp4 = __pyx_v_u; + __pyx_parallel_temp0 = __pyx_v_auc; + __pyx_parallel_temp1 = __pyx_v_i; + __pyx_parallel_temp2 = __pyx_v_total; + __pyx_parallel_temp3 = __pyx_v_u; } __pyx_L40:; #ifdef _OPENMP @@ -6070,11 +7385,10 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_parallel_why = 4; } if (__pyx_parallel_why) { - __pyx_v_i = __pyx_parallel_temp0; - __pyx_v_idcg = __pyx_parallel_temp1; - __pyx_v_relevant = __pyx_parallel_temp2; - __pyx_v_total = __pyx_parallel_temp3; - __pyx_v_u = __pyx_parallel_temp4; + __pyx_v_auc = __pyx_parallel_temp0; + __pyx_v_i = __pyx_parallel_temp1; + __pyx_v_total = __pyx_parallel_temp2; + __pyx_v_u = __pyx_parallel_temp3; switch (__pyx_parallel_why) { case 4: { @@ -6094,20 +7408,29 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } } - /* "implicit/evaluation.pyx":291 + /* "implicit/evaluation.pyx":388 * total += 1 * finally: * free(ids) # <<<<<<<<<<<<<< + * free(_auc_list) * del likes - * */ /*finally:*/ { /*normal exit:*/{ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":292 + /* "implicit/evaluation.pyx":389 * finally: * free(ids) + * free(_auc_list) # <<<<<<<<<<<<<< + * del likes + * + */ + free(__pyx_v__auc_list); + + /* "implicit/evaluation.pyx":390 + * free(ids) + * free(_auc_list) * del likes # <<<<<<<<<<<<<< * * progress.close() @@ -6125,42 +7448,47 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif __Pyx_PyThreadState_assign - __pyx_t_31 = 0; __pyx_t_32 = 0; __pyx_t_33 = 0; __pyx_t_34 = 0; __pyx_t_35 = 0; __pyx_t_36 = 0; + __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0; __pyx_t_28 = 0; __pyx_t_29 = 0; __pyx_t_30 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1); + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_34, &__pyx_t_35, &__pyx_t_36); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_31, &__pyx_t_32, &__pyx_t_33) < 0)) __Pyx_ErrFetch(&__pyx_t_31, &__pyx_t_32, &__pyx_t_33); - __Pyx_XGOTREF(__pyx_t_31); - __Pyx_XGOTREF(__pyx_t_32); - __Pyx_XGOTREF(__pyx_t_33); - __Pyx_XGOTREF(__pyx_t_34); - __Pyx_XGOTREF(__pyx_t_35); - __Pyx_XGOTREF(__pyx_t_36); - __pyx_t_15 = __pyx_lineno; __pyx_t_14 = __pyx_clineno; __pyx_t_30 = __pyx_filename; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_28, &__pyx_t_29, &__pyx_t_30); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_25, &__pyx_t_26, &__pyx_t_27) < 0)) __Pyx_ErrFetch(&__pyx_t_25, &__pyx_t_26, &__pyx_t_27); + __Pyx_XGOTREF(__pyx_t_25); + __Pyx_XGOTREF(__pyx_t_26); + __Pyx_XGOTREF(__pyx_t_27); + __Pyx_XGOTREF(__pyx_t_28); + __Pyx_XGOTREF(__pyx_t_29); + __Pyx_XGOTREF(__pyx_t_30); + __pyx_t_10 = __pyx_lineno; __pyx_t_9 = __pyx_clineno; __pyx_t_24 = __pyx_filename; #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif { - /* "implicit/evaluation.pyx":291 + /* "implicit/evaluation.pyx":388 * total += 1 * finally: * free(ids) # <<<<<<<<<<<<<< + * free(_auc_list) * del likes - * */ free(__pyx_v_ids); - /* "implicit/evaluation.pyx":292 + /* "implicit/evaluation.pyx":389 * finally: * free(ids) + * free(_auc_list) # <<<<<<<<<<<<<< + * del likes + * + */ + free(__pyx_v__auc_list); + + /* "implicit/evaluation.pyx":390 + * free(ids) + * free(_auc_list) * del likes # <<<<<<<<<<<<<< * * progress.close() @@ -6171,20 +7499,20 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_34); - __Pyx_XGIVEREF(__pyx_t_35); - __Pyx_XGIVEREF(__pyx_t_36); - __Pyx_ExceptionReset(__pyx_t_34, __pyx_t_35, __pyx_t_36); + __Pyx_XGIVEREF(__pyx_t_28); + __Pyx_XGIVEREF(__pyx_t_29); + __Pyx_XGIVEREF(__pyx_t_30); + __Pyx_ExceptionReset(__pyx_t_28, __pyx_t_29, __pyx_t_30); } - __Pyx_XGIVEREF(__pyx_t_31); - __Pyx_XGIVEREF(__pyx_t_32); - __Pyx_XGIVEREF(__pyx_t_33); - __Pyx_ErrRestore(__pyx_t_31, __pyx_t_32, __pyx_t_33); + __Pyx_XGIVEREF(__pyx_t_25); + __Pyx_XGIVEREF(__pyx_t_26); + __Pyx_XGIVEREF(__pyx_t_27); + __Pyx_ErrRestore(__pyx_t_25, __pyx_t_26, __pyx_t_27); #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif - __pyx_t_31 = 0; __pyx_t_32 = 0; __pyx_t_33 = 0; __pyx_t_34 = 0; __pyx_t_35 = 0; __pyx_t_36 = 0; - __pyx_lineno = __pyx_t_15; __pyx_clineno = __pyx_t_14; __pyx_filename = __pyx_t_30; + __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0; __pyx_t_28 = 0; __pyx_t_29 = 0; __pyx_t_30 = 0; + __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_9; __pyx_filename = __pyx_t_24; goto __pyx_L10_error; } __pyx_L16:; @@ -6221,24 +7549,24 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje /* Clean up any temporaries */ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = NULL; - __Pyx_XDECREF(__pyx_t_31); - __pyx_t_31 = NULL; - __Pyx_XDECREF(__pyx_t_32); - __pyx_t_32 = NULL; - __Pyx_XDECREF(__pyx_t_33); - __pyx_t_33 = NULL; - __Pyx_XDECREF(__pyx_t_34); - __pyx_t_34 = NULL; - __Pyx_XDECREF(__pyx_t_35); - __pyx_t_35 = NULL; - __Pyx_XDECREF(__pyx_t_36); - __pyx_t_36 = NULL; + __Pyx_XDECREF(__pyx_t_13); + __pyx_t_13 = NULL; + __Pyx_XDECREF(__pyx_t_25); + __pyx_t_25 = NULL; + __Pyx_XDECREF(__pyx_t_26); + __pyx_t_26 = NULL; + __Pyx_XDECREF(__pyx_t_27); + __pyx_t_27 = NULL; + __Pyx_XDECREF(__pyx_t_28); + __pyx_t_28 = NULL; + __Pyx_XDECREF(__pyx_t_29); + __pyx_t_29 = NULL; + __Pyx_XDECREF(__pyx_t_30); + __pyx_t_30 = NULL; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = NULL; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = NULL; - __Pyx_XDECREF(__pyx_t_9); - __pyx_t_9 = NULL; #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif @@ -6276,9 +7604,9 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje #endif } - /* "implicit/evaluation.pyx":258 - * progress = tqdm(total=users, disable=not show_progress) - * + /* "implicit/evaluation.pyx":350 + * cdef int __auc = 0, __relevant = 1, __miss = 2, __num_pos_items = 3, __num_neg_items = 4 + * cdef float auc * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< * ids = malloc(sizeof(int) * K) * likes = new unordered_set[int]() @@ -6302,52 +7630,52 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje } } - /* "implicit/evaluation.pyx":294 + /* "implicit/evaluation.pyx":392 * del likes * * progress.close() # <<<<<<<<<<<<<< - * return relevant / total + * return auc / total */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 294, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_9))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); - __Pyx_INCREF(__pyx_t_5); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_progress, __pyx_n_s_close); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 392, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_1 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_13))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_13); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13); + __Pyx_INCREF(__pyx_t_1); __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_9, function); + __Pyx_DECREF_SET(__pyx_t_13, function); } } - __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = (__pyx_t_1) ? __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_1) : __Pyx_PyObject_CallNoArg(__pyx_t_13); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 392, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "implicit/evaluation.pyx":295 + /* "implicit/evaluation.pyx":393 * * progress.close() - * return relevant / total # <<<<<<<<<<<<<< + * return auc / total # <<<<<<<<<<<<<< */ __Pyx_XDECREF(__pyx_r); if (unlikely(__pyx_v_total == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 295, __pyx_L1_error) + __PYX_ERR(0, 393, __pyx_L1_error) } - __pyx_t_1 = PyFloat_FromDouble((__pyx_v_relevant / __pyx_v_total)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; + __pyx_t_4 = PyFloat_FromDouble((((double)__pyx_v_auc) / __pyx_v_total)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 393, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; goto __pyx_L0; - /* "implicit/evaluation.pyx":215 + /* "implicit/evaluation.pyx":304 * * @cython.boundscheck(False) - * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< - * show_progress=True, int num_threads=1): + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): * """ Calculates ndcg@K for a given trained model */ @@ -6357,18 +7685,12 @@ static PyObject *__pyx_pf_8implicit_10evaluation_6ndcg_at_k(CYTHON_UNUSED PyObje __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1); - __Pyx_AddTraceback("implicit.evaluation.ndcg_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("implicit.evaluation.AUC_at_k", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __PYX_XDEC_MEMVIEW(&__pyx_v_test_indptr, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_test_indices, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_cg, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_cg_sum, 1); __Pyx_XDECREF(__pyx_v_progress); __Pyx_XDECREF(__pyx_v_recs); __Pyx_XDECREF(__pyx_v_train_user_items); @@ -19328,6 +20650,9 @@ static PyTypeObject __pyx_type___pyx_array = { #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif }; static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { @@ -19436,6 +20761,9 @@ static PyTypeObject __pyx_type___pyx_MemviewEnum = { #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif }; static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; @@ -19686,6 +21014,9 @@ static PyTypeObject __pyx_type___pyx_memoryview = { #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif }; static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; @@ -19821,6 +21152,9 @@ static PyTypeObject __pyx_type___pyx_memoryviewslice = { #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif }; static PyMethodDef __pyx_methods[] = { @@ -19870,6 +21204,7 @@ static struct PyModuleDef __pyx_moduledef = { static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, + {&__pyx_n_s_AUC_at_k, __pyx_k_AUC_at_k, sizeof(__pyx_k_AUC_at_k), 0, 0, 1, 1}, {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, {&__pyx_kp_s_Cannot_assign_to_read_only_memor, __pyx_k_Cannot_assign_to_read_only_memor, sizeof(__pyx_k_Cannot_assign_to_read_only_memor), 0, 0, 1, 0}, @@ -19897,6 +21232,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, {&__pyx_n_s_ap, __pyx_k_ap, sizeof(__pyx_k_ap), 0, 0, 1, 1}, {&__pyx_n_s_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 0, 0, 1, 1}, + {&__pyx_n_s_auc, __pyx_k_auc, sizeof(__pyx_k_auc), 0, 0, 1, 1}, + {&__pyx_n_s_auc_2, __pyx_k_auc_2, sizeof(__pyx_k_auc_2), 0, 0, 1, 1}, + {&__pyx_n_s_auc_list, __pyx_k_auc_list, sizeof(__pyx_k_auc_list), 0, 0, 1, 1}, {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, @@ -19935,6 +21273,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, {&__pyx_n_s_indices, __pyx_k_indices, sizeof(__pyx_k_indices), 0, 0, 1, 1}, {&__pyx_n_s_indptr, __pyx_k_indptr, sizeof(__pyx_k_indptr), 0, 0, 1, 1}, + {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, {&__pyx_n_s_likes, __pyx_k_likes, sizeof(__pyx_k_likes), 0, 0, 1, 1}, @@ -19943,6 +21282,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_mean_ap, __pyx_k_mean_ap, sizeof(__pyx_k_mean_ap), 0, 0, 1, 1}, {&__pyx_n_s_mean_average_precision_at_k, __pyx_k_mean_average_precision_at_k, sizeof(__pyx_k_mean_average_precision_at_k), 0, 0, 1, 1}, {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, + {&__pyx_n_s_miss, __pyx_k_miss, sizeof(__pyx_k_miss), 0, 0, 1, 1}, {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, {&__pyx_n_s_model, __pyx_k_model, sizeof(__pyx_k_model), 0, 0, 1, 1}, {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, @@ -19952,6 +21292,8 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_num_neg_items, __pyx_k_num_neg_items, sizeof(__pyx_k_num_neg_items), 0, 0, 1, 1}, + {&__pyx_n_s_num_pos_items, __pyx_k_num_pos_items, sizeof(__pyx_k_num_pos_items), 0, 0, 1, 1}, {&__pyx_n_s_num_threads, __pyx_k_num_threads, sizeof(__pyx_k_num_threads), 0, 0, 1, 1}, {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, @@ -19977,6 +21319,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, {&__pyx_n_s_relevant, __pyx_k_relevant, sizeof(__pyx_k_relevant), 0, 0, 1, 1}, + {&__pyx_n_s_relevant_2, __pyx_k_relevant_2, sizeof(__pyx_k_relevant_2), 0, 0, 1, 1}, {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, {&__pyx_n_s_scipy_sparse, __pyx_k_scipy_sparse, sizeof(__pyx_k_scipy_sparse), 0, 0, 1, 1}, {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, @@ -20017,7 +21360,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, 107, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 111, __pyx_L1_error) __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 133, __pyx_L1_error) __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 148, __pyx_L1_error) __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(1, 151, __pyx_L1_error) @@ -20231,48 +21574,60 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * def train_test_split(ratings, train_percentage=0.8): # <<<<<<<<<<<<<< * """ Randomly splits the ratings matrix into two matrices for training/testing. - * Parameters + * */ __pyx_tuple__19 = PyTuple_Pack(7, __pyx_n_s_ratings, __pyx_n_s_train_percentage, __pyx_n_s_random_index, __pyx_n_s_train_index, __pyx_n_s_test_index, __pyx_n_s_train, __pyx_n_s_test); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__19); __Pyx_GIVEREF(__pyx_tuple__19); __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_train_test_split, 17, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 17, __pyx_L1_error) - /* "implicit/evaluation.pyx":50 + /* "implicit/evaluation.pyx":52 * * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates P@K for a given trained model */ - __pyx_tuple__21 = PyTuple_Pack(17, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_relevant, __pyx_n_s_total, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 50, __pyx_L1_error) + __pyx_tuple__21 = PyTuple_Pack(17, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_relevant, __pyx_n_s_total, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 52, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__21); __Pyx_GIVEREF(__pyx_tuple__21); - __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(6, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_precision_at_k, 50, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(0, 50, __pyx_L1_error) + __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(6, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_precision_at_k, 52, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(0, 52, __pyx_L1_error) - /* "implicit/evaluation.pyx":131 + /* "implicit/evaluation.pyx":135 * * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates MAP@K for a given trained model */ - __pyx_tuple__23 = PyTuple_Pack(19, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_total, __pyx_n_s_mean_ap, __pyx_n_s_ap, __pyx_n_s_relevant, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 131, __pyx_L1_error) + __pyx_tuple__23 = PyTuple_Pack(19, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_total, __pyx_n_s_mean_ap, __pyx_n_s_ap, __pyx_n_s_relevant, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 135, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__23); __Pyx_GIVEREF(__pyx_tuple__23); - __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(6, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_mean_average_precision_at_k, 131, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 131, __pyx_L1_error) + __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(6, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_mean_average_precision_at_k, 135, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 135, __pyx_L1_error) - /* "implicit/evaluation.pyx":215 + /* "implicit/evaluation.pyx":221 * * @cython.boundscheck(False) * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates ndcg@K for a given trained model */ - __pyx_tuple__25 = PyTuple_Pack(20, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_relevant, __pyx_n_s_total, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_cg, __pyx_n_s_cg_sum, __pyx_n_s_idcg, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 215, __pyx_L1_error) + __pyx_tuple__25 = PyTuple_Pack(20, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_relevant, __pyx_n_s_total, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_cg, __pyx_n_s_cg_sum, __pyx_n_s_idcg, __pyx_n_s_progress, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 221, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__25); __Pyx_GIVEREF(__pyx_tuple__25); - __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(6, 0, 20, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_ndcg_at_k, 215, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 215, __pyx_L1_error) + __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(6, 0, 20, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_ndcg_at_k, 221, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 221, __pyx_L1_error) + + /* "implicit/evaluation.pyx":304 + * + * @cython.boundscheck(False) + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): + * """ Calculates ndcg@K for a given trained model + */ + __pyx_tuple__27 = PyTuple_Pack(24, __pyx_n_s_model, __pyx_n_s_train_user_items, __pyx_n_s_test_user_items, __pyx_n_s_K, __pyx_n_s_show_progress, __pyx_n_s_num_threads, __pyx_n_s_users, __pyx_n_s_u, __pyx_n_s_i, __pyx_n_s_items, __pyx_n_s_total, __pyx_n_s_test_indptr, __pyx_n_s_test_indices, __pyx_n_s_ids, __pyx_n_s_likes, __pyx_n_s_progress, __pyx_n_s_auc_list, __pyx_n_s_auc, __pyx_n_s_relevant_2, __pyx_n_s_miss, __pyx_n_s_num_pos_items, __pyx_n_s_num_neg_items, __pyx_n_s_auc_2, __pyx_n_s_recs); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 304, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__27); + __Pyx_GIVEREF(__pyx_tuple__27); + __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(6, 0, 24, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_implicit_evaluation_pyx, __pyx_n_s_AUC_at_k, 304, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) __PYX_ERR(0, 304, __pyx_L1_error) /* "View.MemoryView":286 * return self.name @@ -20281,9 +21636,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef strided = Enum("") # default * cdef indirect = Enum("") */ - __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 286, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__27); - __Pyx_GIVEREF(__pyx_tuple__27); + __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 286, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__29); + __Pyx_GIVEREF(__pyx_tuple__29); /* "View.MemoryView":287 * @@ -20292,9 +21647,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef indirect = Enum("") * */ - __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__28); - __Pyx_GIVEREF(__pyx_tuple__28); + __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__30); + __Pyx_GIVEREF(__pyx_tuple__30); /* "View.MemoryView":288 * cdef generic = Enum("") @@ -20303,9 +21658,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * */ - __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 288, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__29); - __Pyx_GIVEREF(__pyx_tuple__29); + __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(1, 288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__31); + __Pyx_GIVEREF(__pyx_tuple__31); /* "View.MemoryView":291 * @@ -20314,9 +21669,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef indirect_contiguous = Enum("") * */ - __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 291, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__30); - __Pyx_GIVEREF(__pyx_tuple__30); + __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(1, 291, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__32); + __Pyx_GIVEREF(__pyx_tuple__32); /* "View.MemoryView":292 * @@ -20325,19 +21680,19 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * */ - __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(1, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__31); - __Pyx_GIVEREF(__pyx_tuple__31); + __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(1, 292, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__33); + __Pyx_GIVEREF(__pyx_tuple__33); /* "(tree fragment)":1 * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< * cdef object __pyx_PickleError * cdef object __pyx_result */ - __pyx_tuple__32 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__32); - __Pyx_GIVEREF(__pyx_tuple__32); - __pyx_codeobj__33 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__32, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__33)) __PYX_ERR(1, 1, __pyx_L1_error) + __pyx_tuple__34 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__34); + __Pyx_GIVEREF(__pyx_tuple__34); + __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; @@ -20410,12 +21765,16 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_vtabptr_array = &__pyx_vtable_array; __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; if (PyType_Ready(&__pyx_type___pyx_array) < 0) __PYX_ERR(1, 105, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 __pyx_type___pyx_array.tp_print = 0; + #endif if (__Pyx_SetVtable(__pyx_type___pyx_array.tp_dict, __pyx_vtabptr_array) < 0) __PYX_ERR(1, 105, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_array) < 0) __PYX_ERR(1, 105, __pyx_L1_error) __pyx_array_type = &__pyx_type___pyx_array; if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(1, 279, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 __pyx_type___pyx_MemviewEnum.tp_print = 0; + #endif if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_MemviewEnum.tp_dictoffset && __pyx_type___pyx_MemviewEnum.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type___pyx_MemviewEnum.tp_getattro = __Pyx_PyObject_GenericGetAttr; } @@ -20430,7 +21789,9 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(1, 330, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 __pyx_type___pyx_memoryview.tp_print = 0; + #endif if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryview.tp_dictoffset && __pyx_type___pyx_memoryview.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type___pyx_memoryview.tp_getattro = __Pyx_PyObject_GenericGetAttr; } @@ -20443,7 +21804,9 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type; if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(1, 961, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 __pyx_type___pyx_memoryviewslice.tp_print = 0; + #endif if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryviewslice.tp_dictoffset && __pyx_type___pyx_memoryviewslice.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type___pyx_memoryviewslice.tp_getattro = __Pyx_PyObject_GenericGetAttr; } @@ -20664,9 +22027,9 @@ if (!__Pyx_RefNanny) { } #endif /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error; /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error; /*--- Global type/function init code ---*/ (void)__Pyx_modinit_global_init_code(); (void)__Pyx_modinit_variable_export_code(); @@ -20746,47 +22109,59 @@ if (!__Pyx_RefNanny) { * * def train_test_split(ratings, train_percentage=0.8): # <<<<<<<<<<<<<< * """ Randomly splits the ratings matrix into two matrices for training/testing. - * Parameters + * */ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_1train_test_split, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_train_test_split, __pyx_t_1) < 0) __PYX_ERR(0, 17, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":50 + /* "implicit/evaluation.pyx":52 * * @cython.boundscheck(False) * def precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates P@K for a given trained model */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_3precision_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 50, __pyx_L1_error) + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_3precision_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_precision_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 50, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_precision_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 52, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":131 + /* "implicit/evaluation.pyx":135 * * @cython.boundscheck(False) * def mean_average_precision_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates MAP@K for a given trained model */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_5mean_average_precision_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 131, __pyx_L1_error) + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_5mean_average_precision_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 135, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean_average_precision_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 131, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean_average_precision_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 135, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "implicit/evaluation.pyx":215 + /* "implicit/evaluation.pyx":221 * * @cython.boundscheck(False) * def ndcg_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< * show_progress=True, int num_threads=1): * """ Calculates ndcg@K for a given trained model */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_7ndcg_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error) + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_7ndcg_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_ndcg_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "implicit/evaluation.pyx":304 + * + * @cython.boundscheck(False) + * def AUC_at_k(model, train_user_items, test_user_items, int K=10, # <<<<<<<<<<<<<< + * show_progress=True, int num_threads=1): + * """ Calculates ndcg@K for a given trained model + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8implicit_10evaluation_9AUC_at_k, NULL, __pyx_n_s_implicit_evaluation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 304, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_ndcg_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 215, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_AUC_at_k, __pyx_t_1) < 0) __PYX_ERR(0, 304, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "implicit/evaluation.pyx":1 @@ -20819,7 +22194,7 @@ if (!__Pyx_RefNanny) { * cdef strided = Enum("") # default * cdef indirect = Enum("") */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 286, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 286, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(generic); __Pyx_DECREF_SET(generic, __pyx_t_1); @@ -20833,7 +22208,7 @@ if (!__Pyx_RefNanny) { * cdef indirect = Enum("") * */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 287, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 287, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(strided); __Pyx_DECREF_SET(strided, __pyx_t_1); @@ -20847,7 +22222,7 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 288, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 288, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(indirect); __Pyx_DECREF_SET(indirect, __pyx_t_1); @@ -20861,7 +22236,7 @@ if (!__Pyx_RefNanny) { * cdef indirect_contiguous = Enum("") * */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 291, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 291, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(contiguous); __Pyx_DECREF_SET(contiguous, __pyx_t_1); @@ -20875,7 +22250,7 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 292, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 292, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(indirect_contiguous); __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1); @@ -21196,7 +22571,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args return result; } #if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) { +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); @@ -21267,12 +22642,12 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, } #if PY_MAJOR_VERSION >= 3 result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, nargs, + args, (int)nargs, k, (int)nk, d, (int)nd, kwdefs, closure); #else result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, nargs, + args, (int)nargs, k, (int)nk, d, (int)nd, closure); #endif diff --git a/implicit/evaluation.pyx b/implicit/evaluation.pyx index a0c755e7..622acc90 100644 --- a/implicit/evaluation.pyx +++ b/implicit/evaluation.pyx @@ -299,3 +299,97 @@ def ndcg_at_k(model, train_user_items, test_user_items, int K=10, progress.close() return relevant / total + + +@cython.boundscheck(False) +def AUC_at_k(model, train_user_items, test_user_items, int K=10, + show_progress=True, int num_threads=1): + """ Calculate limited AUC for a given trained model + + Parameters + ---------- + model : RecommenderBase + The fitted recommendation model to test + train_user_items : csr_matrix + Sparse matrix of user by item that contains elements that were used in training the model + test_user_items : csr_matrix + Sparse matrix of user by item that contains withheld elements to test on + K : int + Number of items to test on + show_progress : bool, optional + Whether to show a progress bar + num_threads : int, optional + The number of threads to use for testing. Specifying 0 means to default + to the number of cores on the machine. Note: aside from the ALS and BPR + models, setting this to more than 1 will likely hurt performance rather than + help. + + Returns + ------- + float + the calculated ndcg@k + """ + if not isinstance(train_user_items, csr_matrix): + train_user_items = train_user_items.tocsr() + + if not isinstance(test_user_items, csr_matrix): + test_user_items = test_user_items.tocsr() + + cdef int users = test_user_items.shape[0], u, i + cdef int items = test_user_items.shape[1] + cdef double total = 0 + cdef int[:] test_indptr = test_user_items.indptr + cdef int[:] test_indices = test_user_items.indices + + cdef int * ids + cdef unordered_set[int] * likes + + progress = tqdm(total=users, disable=not show_progress) + cdef double* _auc_list + cdef int __auc = 0, __relevant = 1, __miss = 2, __num_pos_items = 3, __num_neg_items = 4 + cdef double auc + with nogil, parallel(num_threads=num_threads): + ids = malloc(sizeof(int) * K) + likes = new unordered_set[int]() + _auc_list = malloc(sizeof(double) * 5) + try: + for u in prange(users, schedule='guided'): + # if we don't have any test items, skip this user + if test_indptr[u] == test_indptr[u+1]: + with gil: + progress.update(1) + continue + memset(ids, 0, sizeof(int) * K) + memset(_auc_list, 0, sizeof(double) * 5) + with gil: + recs = model.recommend(u, train_user_items, N=K) + for i in range(len(recs)): + ids[i] = recs[i][0] + progress.update(1) + + # mostly we're going to be blocked on the gil here, + # so try to do actual scoring without it + likes.clear() + + for i in range(test_indptr[u], test_indptr[u+1]): + likes.insert(test_indices[i]) + _auc_list[__num_pos_items] = likes.size() + _auc_list[__num_neg_items] = items - _auc_list[__num_pos_items] + for i in range(K): + if likes.find(ids[i]) != likes.end(): + _auc_list[__relevant] += 1 + else: + _auc_list[__miss] += 1 + _auc_list[__auc] += _auc_list[__relevant] + _auc_list[__auc] += ((_auc_list[__relevant] + _auc_list[__num_pos_items]) / 2.0) \ + * (_auc_list[__num_neg_items] - _auc_list[__miss]) + _auc_list[__auc] /= (_auc_list[__num_pos_items] * _auc_list[__num_neg_items]) + auc += _auc_list[__auc] + total += 1 + finally: + free(ids) + free(_auc_list) + del likes + + progress.close() + return auc / total