rankfmc


Namerankfmc JSON
Version 0.3.0 PyPI version JSON
download
home_pagehttps://github.com/ErraticO/rankfmc
Summarya python implementation of the generic factorization machines model class adapted for collaborative filtering recommendation problems with implicit feedback user-item interaction data and (optionally) additional user/item side features
upload_time2023-08-22 05:35:55
maintainer
docs_urlNone
authorErraticO
requires_python>=3.6
licenseGNU General Public License v3.0
keywords machine learning recommendation factorization machines implicit
VCS
bugtrack_url
requirements numpy pandas flake8 pytest
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # RankFM

[![PyPI version](https://badge.fury.io/py/rankfm.svg)](https://badge.fury.io/py/rankfm)
[![CircleCI](https://circleci.com/gh/etlundquist/rankfm.svg?style=shield)](https://circleci.com/gh/etlundquist/rankfm)
[![Documentation Status](https://readthedocs.org/projects/rankfm/badge/?version=latest)](https://rankfm.readthedocs.io/en/latest/?badge=latest)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

[[original author]](https://github.com/etlundquist/rankfm)

RankFM is a python implementation of the general [Factorization Machines](https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf) model class adapted for collaborative filtering recommendation/ranking problems with implicit feedback user/item interaction data. It uses [Bayesian Personalized Ranking (BPR)](https://arxiv.org/pdf/1205.2618.pdf) and a variant of [Weighted Approximate-Rank Pairwise (WARP)](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.587.3946&rep=rep1&type=pdf) loss to learn model weights via Stochastic Gradient Descent (SGD). It can (optionally) incorporate sample weights and user/item auxiliary features to augment the main interaction data.

The core (training, prediction, recommendation) methods are written in [Cython](https://cython.org/), making it possible to scale to millions of user/item interactions. Designed for ease-of-use, RankFM accepts both `pd.DataFrame` and `np.ndarray` inputs - you do not have to convert your data to `scipy.sparse` matrices or re-map user/item identifiers prior to use. RankFM internally maps all user/item identifiers to zero-based integer indexes, but always converts its output back to the original user/item identifiers from your data, which can be arbitrary (non-zero-based, non-consecutive) integers or even strings.

In addition to the familiar `fit()`, `predict()`, `recommend()` methods, RankFM includes additional utilities `similiar_users()` and `similar_items()` to find the most similar users/items to a given user/item based on latent factor space embeddings. A number of popular recommendation/ranking evaluation metric functions have been included in the separate `evaluation` module to streamline model tuning and validation.

* see the **Quickstart** section below to get started with the basic functionality
* see the `/examples` folder for more in-depth jupyter notebook walkthroughs with several popular open-source data sets
* see the [Online Documentation](https://rankfm.readthedocs.io/en/latest/) for more comprehensive documentation on the main model class and separate evaluation module
* see the [Medium Article](https://towardsdatascience.com/factorization-machines-for-item-recommendation-with-implicit-feedback-data-5655a7c749db) for contextual motivation and a detailed mathematical description of the algorithm

---
### Dependencies
* Python 3.6+
* numpy >= 1.15
* pandas >= 0.24

### Installation

#### Prerequisites

To install RankFM's C extensions you will need the [GNU Compiler Collection (GCC)](https://gcc.gnu.org/). Check to see whether you already have it installed:
```
gcc --version
```

If you don't have it already you can easily install it using [Homebrew](https://brew.sh/) on OSX or your default linux package manager:
```
# OSX
brew install gcc

# linux
sudo yum install gcc

# ensure [gcc] has been installed correctly and is on the system PATH
gcc --version
```

#### Package Installation

You can install the latest published version from PyPI using `pip`:
```
pip install rankfmc
```
Or alternatively install the current development build directly from GitHub:
```
pip install git+https://github.com/etlundquist/rankfm.git#egg=rankfm
```

It's highly recommended that you use an [Anaconda](https://www.anaconda.com/) base environment to ensure that all core numpy C extensions and linear algebra libraries have been installed and configured correctly. Anaconda: it just works.

### Quickstart
Let's work through a simple example of fitting a model, generating recommendations, evaluating performance, and assessing some item-item similarities. The data we'll be using here may already be somewhat familiar: you know it, you love it, it's the [MovieLens 1M](https://grouplens.org/datasets/movielens/1m/)!

Let's first look at the required shape of the interaction data:

| user_id | item_id |
|---------|---------|
| 3       | 233     |
| 5       | 377     |
| 8       | 610     |

It has just two columns: a `user_id` and an `item_id` (you can name these fields whatever you want or use a numpy array instead). Notice that there is no `rating` column - this library is for **implicit feedback** data (e.g. watches, page views, purchases, clicks) as opposed to **explicit feedback** data (e.g. 1-5 ratings, thumbs up/down). Implicit feedback is far more common in real-world recommendation contexts and doesn't suffer from the [missing-not-at-random problem](https://resources.bibblio.org/hubfs/share/2018-01-24-RecSysLDN-Ravelin.pdf) of pure explicit feedback approaches.

Now let's import the library, initialize our model, and fit on the training data:
```python
from rankfm.rankfm import RankFM
model = RankFM(factors=20, loss='warp', max_samples=20, alpha=0.01, sigma=0.1, learning_rate=0.1, learning_schedule='invscaling')
model.fit(interactions_train, epochs=20, verbose=True)
# NOTE: this takes about 30 seconds for 750,000 interactions on my 2.3 GHz i5 8GB RAM MacBook
```
If you set `verbose=True` the model will print the current epoch number as well as the epoch's log-likelihood during training. This can be useful to gauge both computational speed and training gains by epoch. If the log likelihood is not increasing then try upping the `learning_rate` or lowering the (`alpha`, `beta`) regularization strength terms. If the log likelihood is starting to bounce up and down try lowering the `learning_rate` or using `learning_schedule='invscaling'` to decrease the learning rate over time. If you run into overflow errors then decrease the feature and/or sample-weight magnitudes and try upping `beta`, especially if you have a small number of dense user-features and/or item-features. Selecting `BPR` loss will lead to faster training times, but `WARP` loss typically yields superior model performance.

Now let's generate some user-item model scores from the validation data:
```python
valid_scores = model.predict(interactions_valid, cold_start='nan')
```
this will produce an array of real-valued model scores generated using the Factorization Machines model equation. You can interpret it as a measure of the predicted utility of item (i) for user (u). The `cold_start='nan'` option can be used to set scores to `np.nan` for user/item pairs not found in the training data, or `cold_start='drop'` can be specified to drop those pairs so the results contain no missing values.

Now let's generate our topN recommended movies for each user:
```python
valid_recs = model.recommend(valid_users, n_items=10, filter_previous=True, cold_start='drop')
```
The input should be a `pd.Series`, `np.ndarray` or `list` of `user_id` values. You can use `filter_previous=True` to prevent generating recommendations that include any items observed by the user in the training data, which could be useful depending on your application context. The result will be a `pd.DataFrame` where `user_id` values will be the index and the rows will be each user's top recommended items in descending order (best item is in column 0):

|   |    0|    1|    2|    3|    4|    5|    6|    7|   8|    9|
|---|-----|-----|-----|-----|-----|-----|-----|-----|----|-----|
|3  | 2396| 1265|  357|   34| 2858| 3175|    1| 2028|  17|  356|
|5  |  608| 1617| 1610| 3418|  590|  474|  858|  377| 924| 1036|
|8  |  589| 1036| 2571| 2028| 2000| 1220| 1197|  110| 780| 1954|

Now let's see how the model is performing wrt the included validation metrics evaluated on the hold-out data:
```python
from rankfm.evaluation import hit_rate, reciprocal_rank, discounted_cumulative_gain, precision, recall

valid_hit_rate = hit_rate(model, interactions_valid, k=10)
valid_reciprocal_rank = reciprocal_rank(model, interactions_valid, k=10)
valid_dcg = discounted_cumulative_gain(model, interactions_valid, k=10)
valid_precision = precision(model, interactions_valid, k=10)
valid_recall = recall(model, interactions_valid, k=10)
```
```
hit_rate: 0.796
reciprocal_rank: 0.339
dcg: 0.734
precision: 0.159
recall: 0.077
```
[That's a Bingo!](https://www.youtube.com/watch?v=q5pESPQpXxE)

Now let's find the most similar other movies for a few movies based on their embedding representations in latent factor space:
```python
# Terminator 2: Judgment Day (1991)
model.similar_items(589, n_items=10)
```
```
2571                       Matrix, The (1999)
1527                Fifth Element, The (1997)
2916                      Total Recall (1990)
3527                          Predator (1987)
780             Independence Day (ID4) (1996)
1909    X-Files: Fight the Future, The (1998)
733                          Rock, The (1996)
1376     Star Trek IV: The Voyage Home (1986)
480                      Jurassic Park (1993)
1200                            Aliens (1986)
```
[I hope you like explosions...](https://www.youtube.com/watch?v=uENYMZNzg9w)

```python
# Being John Malkovich (1999)
model.similar_items(2997, n_items=10)
```
```
2599           Election (1999)
3174    Man on the Moon (1999)
2858    American Beauty (1999)
3317        Wonder Boys (2000)
223              Clerks (1994)
3897      Almost Famous (2000)
2395           Rushmore (1998)
2502       Office Space (1999)
2908     Boys Don't Cry (1999)
3481      High Fidelity (2000)
```
[Let's get weird...](https://www.youtube.com/watch?v=lIpev8JXJHQ&t=5s)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ErraticO/rankfmc",
    "name": "rankfmc",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "machine,learning,recommendation,factorization,machines,implicit",
    "author": "ErraticO",
    "author_email": "wyh123132@163.com",
    "download_url": "https://files.pythonhosted.org/packages/ca/4f/9d47afda50af2e7051aca671429f8b9a298f3275d85e08de5337d5543ae5/rankfmc-0.3.0.tar.gz",
    "platform": null,
    "description": "# RankFM\n\n[![PyPI version](https://badge.fury.io/py/rankfm.svg)](https://badge.fury.io/py/rankfm)\n[![CircleCI](https://circleci.com/gh/etlundquist/rankfm.svg?style=shield)](https://circleci.com/gh/etlundquist/rankfm)\n[![Documentation Status](https://readthedocs.org/projects/rankfm/badge/?version=latest)](https://rankfm.readthedocs.io/en/latest/?badge=latest)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\n[[original author]](https://github.com/etlundquist/rankfm)\n\nRankFM is a python implementation of the general [Factorization Machines](https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf) model class adapted for collaborative filtering recommendation/ranking problems with implicit feedback user/item interaction data. It uses [Bayesian Personalized Ranking (BPR)](https://arxiv.org/pdf/1205.2618.pdf) and a variant of [Weighted Approximate-Rank Pairwise (WARP)](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.587.3946&rep=rep1&type=pdf) loss to learn model weights via Stochastic Gradient Descent (SGD). It can (optionally) incorporate sample weights and user/item auxiliary features to augment the main interaction data.\n\nThe core (training, prediction, recommendation) methods are written in [Cython](https://cython.org/), making it possible to scale to millions of user/item interactions. Designed for ease-of-use, RankFM accepts both `pd.DataFrame` and `np.ndarray` inputs - you do not have to convert your data to `scipy.sparse` matrices or re-map user/item identifiers prior to use. RankFM internally maps all user/item identifiers to zero-based integer indexes, but always converts its output back to the original user/item identifiers from your data, which can be arbitrary (non-zero-based, non-consecutive) integers or even strings.\n\nIn addition to the familiar `fit()`, `predict()`, `recommend()` methods, RankFM includes additional utilities `similiar_users()` and `similar_items()` to find the most similar users/items to a given user/item based on latent factor space embeddings. A number of popular recommendation/ranking evaluation metric functions have been included in the separate `evaluation` module to streamline model tuning and validation.\n\n* see the **Quickstart** section below to get started with the basic functionality\n* see the `/examples` folder for more in-depth jupyter notebook walkthroughs with several popular open-source data sets\n* see the [Online Documentation](https://rankfm.readthedocs.io/en/latest/) for more comprehensive documentation on the main model class and separate evaluation module\n* see the [Medium Article](https://towardsdatascience.com/factorization-machines-for-item-recommendation-with-implicit-feedback-data-5655a7c749db) for contextual motivation and a detailed mathematical description of the algorithm\n\n---\n### Dependencies\n* Python 3.6+\n* numpy >= 1.15\n* pandas >= 0.24\n\n### Installation\n\n#### Prerequisites\n\nTo install RankFM's C extensions you will need the [GNU Compiler Collection (GCC)](https://gcc.gnu.org/). Check to see whether you already have it installed:\n```\ngcc --version\n```\n\nIf you don't have it already you can easily install it using [Homebrew](https://brew.sh/) on OSX or your default linux package manager:\n```\n# OSX\nbrew install gcc\n\n# linux\nsudo yum install gcc\n\n# ensure [gcc] has been installed correctly and is on the system PATH\ngcc --version\n```\n\n#### Package Installation\n\nYou can install the latest published version from PyPI using `pip`:\n```\npip install rankfmc\n```\nOr alternatively install the current development build directly from GitHub:\n```\npip install git+https://github.com/etlundquist/rankfm.git#egg=rankfm\n```\n\nIt's highly recommended that you use an [Anaconda](https://www.anaconda.com/) base environment to ensure that all core numpy C extensions and linear algebra libraries have been installed and configured correctly. Anaconda: it just works.\n\n### Quickstart\nLet's work through a simple example of fitting a model, generating recommendations, evaluating performance, and assessing some item-item similarities. The data we'll be using here may already be somewhat familiar: you know it, you love it, it's the [MovieLens 1M](https://grouplens.org/datasets/movielens/1m/)!\n\nLet's first look at the required shape of the interaction data:\n\n| user_id | item_id |\n|---------|---------|\n| 3       | 233     |\n| 5       | 377     |\n| 8       | 610     |\n\nIt has just two columns: a `user_id` and an `item_id` (you can name these fields whatever you want or use a numpy array instead). Notice that there is no `rating` column - this library is for **implicit feedback** data (e.g. watches, page views, purchases, clicks) as opposed to **explicit feedback** data (e.g. 1-5 ratings, thumbs up/down). Implicit feedback is far more common in real-world recommendation contexts and doesn't suffer from the [missing-not-at-random problem](https://resources.bibblio.org/hubfs/share/2018-01-24-RecSysLDN-Ravelin.pdf) of pure explicit feedback approaches.\n\nNow let's import the library, initialize our model, and fit on the training data:\n```python\nfrom rankfm.rankfm import RankFM\nmodel = RankFM(factors=20, loss='warp', max_samples=20, alpha=0.01, sigma=0.1, learning_rate=0.1, learning_schedule='invscaling')\nmodel.fit(interactions_train, epochs=20, verbose=True)\n# NOTE: this takes about 30 seconds for 750,000 interactions on my 2.3 GHz i5 8GB RAM MacBook\n```\nIf you set `verbose=True` the model will print the current epoch number as well as the epoch's log-likelihood during training. This can be useful to gauge both computational speed and training gains by epoch. If the log likelihood is not increasing then try upping the `learning_rate` or lowering the (`alpha`, `beta`) regularization strength terms. If the log likelihood is starting to bounce up and down try lowering the `learning_rate` or using `learning_schedule='invscaling'` to decrease the learning rate over time. If you run into overflow errors then decrease the feature and/or sample-weight magnitudes and try upping `beta`, especially if you have a small number of dense user-features and/or item-features. Selecting `BPR` loss will lead to faster training times, but `WARP` loss typically yields superior model performance.\n\nNow let's generate some user-item model scores from the validation data:\n```python\nvalid_scores = model.predict(interactions_valid, cold_start='nan')\n```\nthis will produce an array of real-valued model scores generated using the Factorization Machines model equation. You can interpret it as a measure of the predicted utility of item (i) for user (u). The `cold_start='nan'` option can be used to set scores to `np.nan` for user/item pairs not found in the training data, or `cold_start='drop'` can be specified to drop those pairs so the results contain no missing values.\n\nNow let's generate our topN recommended movies for each user:\n```python\nvalid_recs = model.recommend(valid_users, n_items=10, filter_previous=True, cold_start='drop')\n```\nThe input should be a `pd.Series`, `np.ndarray` or `list` of `user_id` values. You can use `filter_previous=True` to prevent generating recommendations that include any items observed by the user in the training data, which could be useful depending on your application context. The result will be a `pd.DataFrame` where `user_id` values will be the index and the rows will be each user's top recommended items in descending order (best item is in column 0):\n\n|   |    0|    1|    2|    3|    4|    5|    6|    7|   8|    9|\n|---|-----|-----|-----|-----|-----|-----|-----|-----|----|-----|\n|3  | 2396| 1265|  357|   34| 2858| 3175|    1| 2028|  17|  356|\n|5  |  608| 1617| 1610| 3418|  590|  474|  858|  377| 924| 1036|\n|8  |  589| 1036| 2571| 2028| 2000| 1220| 1197|  110| 780| 1954|\n\nNow let's see how the model is performing wrt the included validation metrics evaluated on the hold-out data:\n```python\nfrom rankfm.evaluation import hit_rate, reciprocal_rank, discounted_cumulative_gain, precision, recall\n\nvalid_hit_rate = hit_rate(model, interactions_valid, k=10)\nvalid_reciprocal_rank = reciprocal_rank(model, interactions_valid, k=10)\nvalid_dcg = discounted_cumulative_gain(model, interactions_valid, k=10)\nvalid_precision = precision(model, interactions_valid, k=10)\nvalid_recall = recall(model, interactions_valid, k=10)\n```\n```\nhit_rate: 0.796\nreciprocal_rank: 0.339\ndcg: 0.734\nprecision: 0.159\nrecall: 0.077\n```\n[That's a Bingo!](https://www.youtube.com/watch?v=q5pESPQpXxE)\n\nNow let's find the most similar other movies for a few movies based on their embedding representations in latent factor space:\n```python\n# Terminator 2: Judgment Day (1991)\nmodel.similar_items(589, n_items=10)\n```\n```\n2571                       Matrix, The (1999)\n1527                Fifth Element, The (1997)\n2916                      Total Recall (1990)\n3527                          Predator (1987)\n780             Independence Day (ID4) (1996)\n1909    X-Files: Fight the Future, The (1998)\n733                          Rock, The (1996)\n1376     Star Trek IV: The Voyage Home (1986)\n480                      Jurassic Park (1993)\n1200                            Aliens (1986)\n```\n[I hope you like explosions...](https://www.youtube.com/watch?v=uENYMZNzg9w)\n\n```python\n# Being John Malkovich (1999)\nmodel.similar_items(2997, n_items=10)\n```\n```\n2599           Election (1999)\n3174    Man on the Moon (1999)\n2858    American Beauty (1999)\n3317        Wonder Boys (2000)\n223              Clerks (1994)\n3897      Almost Famous (2000)\n2395           Rushmore (1998)\n2502       Office Space (1999)\n2908     Boys Don't Cry (1999)\n3481      High Fidelity (2000)\n```\n[Let's get weird...](https://www.youtube.com/watch?v=lIpev8JXJHQ&t=5s)\n",
    "bugtrack_url": null,
    "license": "GNU General Public License v3.0",
    "summary": "a python implementation of the generic factorization machines model class adapted for collaborative filtering recommendation problems with implicit feedback user-item interaction data and (optionally) additional user/item side features",
    "version": "0.3.0",
    "project_urls": {
        "Homepage": "https://github.com/ErraticO/rankfmc"
    },
    "split_keywords": [
        "machine",
        "learning",
        "recommendation",
        "factorization",
        "machines",
        "implicit"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "409d0339f58509737a78fd17c00c9ddb8fd3b780732f2c2b5835cc77d1917b24",
                "md5": "899fe5db5d8dfd5c2ea3ad5d33e42ce4",
                "sha256": "7604ea92e2480430728604d55dd11843a9d382496e3c3587e17dcb6114106490"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp310-cp310-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "899fe5db5d8dfd5c2ea3ad5d33e42ce4",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.6",
            "size": 632939,
            "upload_time": "2023-08-22T05:36:01",
            "upload_time_iso_8601": "2023-08-22T05:36:01.509692Z",
            "url": "https://files.pythonhosted.org/packages/40/9d/0339f58509737a78fd17c00c9ddb8fd3b780732f2c2b5835cc77d1917b24/rankfmc-0.3.0-cp310-cp310-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cce2aaeee0e92b4e02405cd482cba087f1affcb53d59843c8639f6655debbe52",
                "md5": "332de3af82219db09396e06db2d4d04f",
                "sha256": "705e1650be5bdcd66e861f0adee8297341015d894c1f9308205670195d3b5758"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "332de3af82219db09396e06db2d4d04f",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.6",
            "size": 128736,
            "upload_time": "2023-08-22T05:36:54",
            "upload_time_iso_8601": "2023-08-22T05:36:54.106522Z",
            "url": "https://files.pythonhosted.org/packages/cc/e2/aaeee0e92b4e02405cd482cba087f1affcb53d59843c8639f6655debbe52/rankfmc-0.3.0-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e906e7bdf3cc21368efdea8b0eb49353daa30d50cb2f92f2fb9fb8fd9d8e2e3c",
                "md5": "bb18cafa62b7ce999e12ac61c4932201",
                "sha256": "b7b9ee98d51dbf33dfef4c52ae0300cf6270043501bb86f4483a7ee1d50a41f9"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp311-cp311-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "bb18cafa62b7ce999e12ac61c4932201",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.6",
            "size": 679233,
            "upload_time": "2023-08-22T05:35:53",
            "upload_time_iso_8601": "2023-08-22T05:35:53.389694Z",
            "url": "https://files.pythonhosted.org/packages/e9/06/e7bdf3cc21368efdea8b0eb49353daa30d50cb2f92f2fb9fb8fd9d8e2e3c/rankfmc-0.3.0-cp311-cp311-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d25f8e1249ba256a8799f4832bbc2ca18071c2f9f820f476d8d37d937b927745",
                "md5": "7efcea1162ca6e1945fad5352f6a76d7",
                "sha256": "83563b26d67e6ee6765b5c7ef35ce611ad114abda463a57f9cc5bfac779550f6"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7efcea1162ca6e1945fad5352f6a76d7",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.6",
            "size": 129111,
            "upload_time": "2023-08-22T05:36:54",
            "upload_time_iso_8601": "2023-08-22T05:36:54.291568Z",
            "url": "https://files.pythonhosted.org/packages/d2/5f/8e1249ba256a8799f4832bbc2ca18071c2f9f820f476d8d37d937b927745/rankfmc-0.3.0-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f09f8991c5549afedcc57501165d6433644664177f57ebfee66c8b6631dc5175",
                "md5": "58f9575a15969c459ebafcfb9c707277",
                "sha256": "b8e6ea635cdc475477666dcf087ab24913ea7913b5adcbd4ce906f2b0693c59d"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp36-cp36m-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "58f9575a15969c459ebafcfb9c707277",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": ">=3.6",
            "size": 593507,
            "upload_time": "2023-08-22T05:36:05",
            "upload_time_iso_8601": "2023-08-22T05:36:05.007458Z",
            "url": "https://files.pythonhosted.org/packages/f0/9f/8991c5549afedcc57501165d6433644664177f57ebfee66c8b6631dc5175/rankfmc-0.3.0-cp36-cp36m-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ab0f78d85b0add2c63db29e439977871e8c1553c6e0b1de1b8489eb97b4b9e7f",
                "md5": "8ccb7a6fc8b3e2cac7f40fa49d22d18d",
                "sha256": "ade90b42630582d006ea2836c3300636cc6266ca3260959099220a10de2fb941"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp36-cp36m-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8ccb7a6fc8b3e2cac7f40fa49d22d18d",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": ">=3.6",
            "size": 137954,
            "upload_time": "2023-08-22T05:36:50",
            "upload_time_iso_8601": "2023-08-22T05:36:50.966925Z",
            "url": "https://files.pythonhosted.org/packages/ab/0f/78d85b0add2c63db29e439977871e8c1553c6e0b1de1b8489eb97b4b9e7f/rankfmc-0.3.0-cp36-cp36m-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b537d17d2ed072b32582a43fcc8166a99c1656fae4aa5bbb0f4108a97b51514b",
                "md5": "79b60770d9b2f636c04c97dcb77d5448",
                "sha256": "ce0b28fafe84d3d6d634acce48076f7501cefa27a55bc4da7de955b165505d13"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp37-cp37m-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "79b60770d9b2f636c04c97dcb77d5448",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.6",
            "size": 597765,
            "upload_time": "2023-08-22T05:35:58",
            "upload_time_iso_8601": "2023-08-22T05:35:58.681106Z",
            "url": "https://files.pythonhosted.org/packages/b5/37/d17d2ed072b32582a43fcc8166a99c1656fae4aa5bbb0f4108a97b51514b/rankfmc-0.3.0-cp37-cp37m-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c9015411512d9a14b473e84b282d42a32c220569f43606a72061b4c5460c5a55",
                "md5": "8fea5545c7b3f03284e188cf7c6ce310",
                "sha256": "cd9e18baca667eb34a7eb2f13cee0918c5f44d215a7767e11b9ce8eeece18f9d"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp37-cp37m-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8fea5545c7b3f03284e188cf7c6ce310",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.6",
            "size": 127434,
            "upload_time": "2023-08-22T05:38:29",
            "upload_time_iso_8601": "2023-08-22T05:38:29.223804Z",
            "url": "https://files.pythonhosted.org/packages/c9/01/5411512d9a14b473e84b282d42a32c220569f43606a72061b4c5460c5a55/rankfmc-0.3.0-cp37-cp37m-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6bcc569edf9d482a335379bc8608cd0627ff4986dc5223500168a5956570d8de",
                "md5": "36adf19e01629999fa92348e5bfdee6a",
                "sha256": "f6168d5d4b3894b5e3f6c0c6a33089691a2c90f6bb8c51b797e6c3d404f7c9fc"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp38-cp38-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "36adf19e01629999fa92348e5bfdee6a",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.6",
            "size": 678997,
            "upload_time": "2023-08-22T05:35:53",
            "upload_time_iso_8601": "2023-08-22T05:35:53.679811Z",
            "url": "https://files.pythonhosted.org/packages/6b/cc/569edf9d482a335379bc8608cd0627ff4986dc5223500168a5956570d8de/rankfmc-0.3.0-cp38-cp38-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e7956c03d3d2f0e09ce9bf59c629e7ecbcec175107dc0155229c692d71430d4e",
                "md5": "2c4bb53d3d1301c2944939f65f733064",
                "sha256": "2291cdf7efa0b7fdd0490d1f70bdc603f0a56b96b2f573efc8595278a561df51"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp38-cp38-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "2c4bb53d3d1301c2944939f65f733064",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.6",
            "size": 129294,
            "upload_time": "2023-08-22T05:36:57",
            "upload_time_iso_8601": "2023-08-22T05:36:57.600129Z",
            "url": "https://files.pythonhosted.org/packages/e7/95/6c03d3d2f0e09ce9bf59c629e7ecbcec175107dc0155229c692d71430d4e/rankfmc-0.3.0-cp38-cp38-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "923db5d6cdbcb7b9a156298cc7fc55044d4e8d8c493fac4866998c3b613e25ca",
                "md5": "7a4990eb694582a3cf0720b11da0e33d",
                "sha256": "4dd6aec019f5bc54f937995a93ba02edc730c2f3deeb6bf2a356907e134be171"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp39-cp39-manylinux1_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7a4990eb694582a3cf0720b11da0e33d",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.6",
            "size": 635374,
            "upload_time": "2023-08-22T05:36:02",
            "upload_time_iso_8601": "2023-08-22T05:36:02.722958Z",
            "url": "https://files.pythonhosted.org/packages/92/3d/b5d6cdbcb7b9a156298cc7fc55044d4e8d8c493fac4866998c3b613e25ca/rankfmc-0.3.0-cp39-cp39-manylinux1_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "453b83398dccb78b1238748d8370c083545a1c9efd983c10078564509df16812",
                "md5": "553965c9b4594b30e17fc457a185c533",
                "sha256": "ea553dc7b4003a8da118dfabd567743389ea509e619f0eed276527fc94fc0e42"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "553965c9b4594b30e17fc457a185c533",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.6",
            "size": 129283,
            "upload_time": "2023-08-22T05:38:27",
            "upload_time_iso_8601": "2023-08-22T05:38:27.645643Z",
            "url": "https://files.pythonhosted.org/packages/45/3b/83398dccb78b1238748d8370c083545a1c9efd983c10078564509df16812/rankfmc-0.3.0-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ca4f9d47afda50af2e7051aca671429f8b9a298f3275d85e08de5337d5543ae5",
                "md5": "b6e278ad42f2a808c2f2c974c9c8355f",
                "sha256": "4e70d8604072e494ffa58fbf7118745ed67c3681cc1ba146a90b45cc9a53e7dd"
            },
            "downloads": -1,
            "filename": "rankfmc-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b6e278ad42f2a808c2f2c974c9c8355f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 189355,
            "upload_time": "2023-08-22T05:35:55",
            "upload_time_iso_8601": "2023-08-22T05:35:55.385393Z",
            "url": "https://files.pythonhosted.org/packages/ca/4f/9d47afda50af2e7051aca671429f8b9a298f3275d85e08de5337d5543ae5/rankfmc-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-08-22 05:35:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ErraticO",
    "github_project": "rankfmc",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "numpy",
            "specs": [
                [
                    ">=",
                    "1.15"
                ]
            ]
        },
        {
            "name": "pandas",
            "specs": [
                [
                    ">=",
                    "0.24"
                ]
            ]
        },
        {
            "name": "flake8",
            "specs": [
                [
                    ">=",
                    "3.5"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    ">=",
                    "5.3"
                ]
            ]
        }
    ],
    "lcname": "rankfmc"
}
        
Elapsed time: 1.51601s