# reco

`reco`

is an R package which implements several algrithms for matrix factorization targeting recommender systems.

- Weighted Regularized Matrix Factorization (WRMF) from Collaborative Filtering for Implicit Feedback Datasets (by Yifan Hu, Yehuda Koren, Chris Volinsky). One of the most efficient (benchmarks below) solvers.
- Linear-Flow from Practical Linear Models for Large-Scale One-Class Collaborative Filtering. This algorithm is similar to SLIM but looks for factorized low-rank item-item similarity matrix.
- Regularized Matrix Factorization (MF) - classic approch for "rating" prediction.

Package is **quite fast**:

- Built on top of
`RcppArmadillo`

- extensively use
**BLAS**and parallelized with**OpenMP** - implements
**Conjugate Gradient solver**as dicribed in Applications of the Conjugate Gradient Method for Implicit Feedback Collaborative Filtering and Faster Implicit Matrix Factorization - Top-k items inference is
`O(n*log(k))`

and use**BLAS**+**OpenMP**

# Tutorials

- Introduction to matrix factorization with Weighted-ALS algorithm - collaborative filtering for implicit feedback datasets.
- Music recommendations using LastFM-360K dataset
- evaluation metrics for ranking
- setting up proper cross-validation
- possible issues with nested parallelism and thread contention
- making recommendations for new users
- complimentary item-to-item recommendations

- Benchmark against other good implementations

# API

We follow mlapi conventions.

# Notes on multithreading and BLAS

**VERY IMPORTANT** if you use multithreaded BLAS (you generally should) such as OpenBLAS, Intel MKL, Apple Accelerate, I **highly recommend disable its internal multithreading ability**. This leads to **substantial speedups** for this package (can be easily 10x and more). Matrix factorization is already parallelized in package with OpenMP. This can be done by setting corresponding environment variables **before starting R**:

- OpenBLAS:
`export OPENBLAS_NUM_THREADS=1`

. - Intel MKL:
`export MKL_NUM_THREADS=1`

- Apple Accelerate:
`export VECLIB_MAXIMUM_THREADS=1`

It it also possible to change number of threads in runtime, see for example following packages: