Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/gbolmier/funk-svd

:zap: A python fast implementation of the famous SVD algorithm popularized by Simon Funk during Netflix Prize
https://github.com/gbolmier/funk-svd

numba recommendation-algorithm

Last synced: 10 days ago
JSON representation

:zap: A python fast implementation of the famous SVD algorithm popularized by Simon Funk during Netflix Prize

Awesome Lists containing this project

README

        

# :zap: funk-svd [![Build Status](https://img.shields.io/travis/gbolmier/funk-svd/master.svg?style=flat)](https://travis-ci.com/gbolmier/funk-svd) [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT)

`funk-svd` is a Python 3 library implementing a fast version of the famous SVD algorithm [popularized](http://sifter.org/simon/journal/20061211.html) by Simon Funk during the [Neflix Prize](http://en.wikipedia.org/wiki/Netflix_Prize) contest.

[`Numba`](http://numba.pydata.org/) is used to speed up our algorithm, enabling us to run over 10 times faster than [`Surprise`](http://surpriselib.com)'s Cython implementation (cf. [benchmark notebook](http://nbviewer.jupyter.org/github/gbolmier/funk-svd/blob/master/benchmark.ipynb)).

| Movielens 20M | RMSE | MAE | Time |
|:--------------|:------:|:------:|--------------:|
| Surprise | 0.88 | 0.68 | 10 min 40 sec |
| Funk-svd | 0.88 | 0.68 | 42 sec |

## Installation

Run `pip install git+https://github.com/gbolmier/funk-svd` in your terminal.

## Contributing

All contributions, bug reports, bug fixes, enhancements, and ideas are welcome.

A detailed overview on how to contribute can be found in the [contributor guide](CONTRIBUTING.md).

## Quick example

[run_experiment.py](run_experiment.py):

```python
>>> from funk_svd.dataset import fetch_ml_ratings
>>> from funk_svd import SVD

>>> from sklearn.metrics import mean_absolute_error

>>> df = fetch_ml_ratings(variant='100k')

>>> train = df.sample(frac=0.8, random_state=7)
>>> val = df.drop(train.index.tolist()).sample(frac=0.5, random_state=8)
>>> test = df.drop(train.index.tolist()).drop(val.index.tolist())

>>> svd = SVD(lr=0.001, reg=0.005, n_epochs=100, n_factors=15,
... early_stopping=True, shuffle=False, min_rating=1, max_rating=5)

>>> svd.fit(X=train, X_val=val)
Preprocessing data...

Epoch 1/...

>>> pred = svd.predict(test)
>>> mae = mean_absolute_error(test['rating'], pred)

>>> print(f'Test MAE: {mae:.2f}')
Test MAE: 0.75

```

## Funk SVD for recommendation in a nutshell

We have a huge sparse matrix:

storing known ratings for a set of users and items:

The idea is to estimate unknown ratings by factorizing the rating matrix into two smaller matrices representing user and item characteristics:

We call these two matrices users and items latent factors. Then, by applying the dot product between both matrices we can reconstruct our rating matrix. The trick is that the empty values will now contain estimated ratings.

In order to get more accurate results, the global average rating as well as the user and item biases are used in addition:

where K stands for known ratings.

Then, we can estimate any rating by applying:

The learning step consists in performing the SGD algorithm where for each known rating the biases and latent factors are updated as follows:

where alpha is the learning rate and lambda is the regularization term.

## References

- [Collaborative filtering](https://en.wikipedia.org/wiki/Collaborative_filtering)
- [Matrix completion](https://en.wikipedia.org/wiki/Matrix_completion)
- [Matrix factorization (recommender systems)](https://en.wikipedia.org/wiki/Matrix_factorization_(recommender_systems))
- [Recommender Systems Handbook](https://www.cse.iitk.ac.in/users/nsrivast/HCC/Recommender_systems_handbook.pdf)
- [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition)
- [Surprise library for recommender systems](http://surpriselib.com/)

## License

MIT license, [see here](LICENSE).