Skip to content
Extraits de code Groupes Projets
Valider 21d876e1 rédigé par Nathanaël Kindidi's avatar Nathanaël Kindidi
Parcourir les fichiers

Hmm

parents 12c8b310 5385c4bc
Branches ContentBased
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
# Group 5 - Projet de Recommender System # Group 5 - Hackathon - contentbased for MLSMM2156 Recommender System
## Overview
This repository contains a content-based recomsys model designed for the Hackathon. The system leverages various feature extraction methods and regression algorithms to provide personalized movie recommendations based on user ratings and movie attributes.
Ce projet vise à développer des outils d'analyse de données et de recommandation.
Ce README présente la structure et résume notre projet.
## Python Libraries : ## Python Libraries :
...@@ -18,179 +19,144 @@ pip install scikit-surprise ...@@ -18,179 +19,144 @@ pip install scikit-surprise
pip install collections pip install collections
pip install random pip install random
pip install tabulate pip install tabulate
pip install xgboost
pip install lightgbm
``` ```
## Codes Python de Base
Ces codes se trouveront dans le même dossier que chacun des jupyter notebook (.ipynb).
### configs.py
Ce code définit une **classe EvalConfig** qui stocke les **configurations** pour évaluer plusieurs **modèles de recommandation**. Il spécifie une liste de modèles, chacun avec son nom, sa classe et ses paramètres. Les **métriques** sont définies pour évaluer les **performances** des modèles dans différents scénarios : **évaluation par fractionnement**, **Leave-One-Out** et sur l'ensemble du **jeu de données**. D'autres paramètres incluent la taille de l'ensemble de test et le nombre de **recommandations** à considérer.
### constants.py
Ce code définit une **classe Constant** qui stocke les **chemins** vers les **datasets** et les noms de **colonnes** pour les données de **contenu** et de **preuve**. Les chemins vers les **répertoires** de contenu, de preuve et d'évaluation sont définis en fonction du chemin vers le répertoire de données. Les noms de fichiers et de colonnes pour les données d'**articles** et de **notes** sont spécifiés, ainsi que l'**échelle de notation**.
### loaders.py
Ce code **charge** les données de **notes** et d'articles à partir de fichiers **CSV** spécifiés dans la **classe Constant** du module constants. La fonction `load_ratings()` charge les données de notes, et la fonction `load_items()` charge les données d'articles. Une autre fonction, `export_evaluation_report()`, **fusionne** les données de notes et d'articles, puis exporte le rapport d'évaluation vers un fichier CSV. Les données sont chargées dans des **DataFrames** pandas, et une option est disponible pour charger les données de notes au format attendu par la **bibliothèque Surprise** si nécessaire.
### models.py
Ce code **définit** plusieurs **algorithmes** de base de **recommandation** pour la bibliothèque **Surprise**. La fonction `get_top_n()` prend une liste de **prédictions** et retourne les meilleures recommandations pour chaque **utilisateur**. Les algorithmes de recommandation sont définis comme des classes héritant de la classe `AlgoBase` de **Surprise**, chacun implémentant une méthode `estimate` pour prédire les **évaluations** des utilisateurs pour les articles.
## Datasets
### Small
<<<<<<< HEAD
Le **small dataset** de données contient les données traditionnelles de **MovieLens** et est celui que nous devons utiliser lors de l'**évaluation** des modèles et de la construction de notre **système de recommandation**.
### Test
Le **test dataset** est une version encore plus petite **(6 utilisateurs et 10 articles)** et contient l'exemple utilisé dans les diapositives de la conférence. Nous utilisons ce dataset afin de **mieux comprendre** le fonctionnement des algorithmes lors du développement de nos modèles.
### Tiny
Le **tiny dataset** est une version plus petite du small dataset et est utilisé pour **déboguer** notre code. Cela est utile lorsque certains modèles prennent beaucoup de temps à s'exécuter et que nous voulons **accélérer** le temps de calcul.
=======
Le **small dataset** de données contient les données traditionnelles de **MovieLens** et est celui que nous devons utiliser lors de l'**évaluation** des modèles et de la construction de notre **système de recommandation**. ## Project Structure
The project is organized into the following key components:
### Test
Le **test dataset** est une version encore plus petite **(6 utilisateurs et 10 articles)** et contient l'exemple utilisé dans les diapositives de la conférence. Nous utilisons ce dataset afin de **mieux comprendre** le fonctionnement des algorithmes lors du développement de nos modèles.
### Tiny
Le **tiny dataset** est une version plus petite du small dataset et est utilisé pour **déboguer** notre code. Cela est utile lorsque certains modèles prennent beaucoup de temps à s'exécuter et que nous voulons **accélérer** le temps de calcul.
>>>>>>> Evaluator
### Configuration and Constants
1. ***configs.py***
- Defines an `EvalConfig` class for storing configurations for evaluating multiple recommendation models.
- Specifies a list of models, each with its name, class, and parameters.
## Rendu - Defines metrics to evaluate model performance under different scenarios: split evaluation, Leave-One-Out, and on the entire dataset.
<<<<<<< HEAD - Other parameters include test set size and the number of recommendations to consider.
### Analytics_UI
Lors de ce rendu, différentes analyses ont pu être effectuées sur les datasets disponibles afin de mieux comprendre les différentes données auxquelles nous allons faire face tout au long du projet. Une description détaillée des différentes analyses, menées dans les jupyter notebook, est décrite ci-dessous. Les jupyter notebook peuvent être lancés (run) indépendamment de tout autre fichier (.py) ou (.ipynb). 2. ***constants.py***
======= - This code defines a Constant class that stores paths to datasets and column names for content and evidence data. Paths to content, evidence, and evaluation directories are defined based on the data directory path. File names and column names for article and rating data are specified, along with the rating scale.
### Evaluator block
Le Jupyter Notebook peut être lancé indépendemment de tout autre code. ### Data Loaders
>>>>>>> Evaluator 3. ***loaders.py***
- Loads rating and item data from specified CSV files in the Constant class of the constants module.
- The `load_ratings` function loads rating data.
- The `load_items` function loads item data.
- The `export_evaluation_report` function merges rating and item data, then exports the evaluation report to a CSV file.
- The data is loaded into pandas DataFrames, with an option available to load rating data in the format expected by the Surprise library if needed.
- **evaluator.ipynb** ### Recommender Models
4. ***models.py***
- Defines several basic recommendation algorithms for the Surprise library.
- The `get_top n` function takes a list of predictions and returns the top recommendations for each user.
Pour ce jupyter notebook Evaluator.ipynb, l'importation de certains **packages** et modules clés est essentielle. Dans notre cas, nous avons importé les packages `model_selection` et `accuracy` de **Surprise**, ce dernier étant nécessaire pour effectuer une **validation croisée** et utiliser des **métriques** prédéfinies pour **évaluer les modèles**. Cela nous permettra d'obtenir des informations précieuses sur les performances de nos modèles de recommandation. - Recommendation algorithms are defined as classes inheriting from Surprise's `AlgoBase` class, each implementing an `estimate` method to predict user ratings for items.
En ce qui concerne l'adaptation des **loaders**, nous avons apporté des modifications à la fonction `load_ratings()`. Cette fonction a été ajustée pour permettre le chargement de données dans un **format** compatible avec **Surprise**. Un argument supplémentaire, `surprise_format`, a été ajouté pour conditionner le chargement en un objet **Dataset** compatible Surprise à partir d'un **DataFrame Pandas**. Cela simplifie grandement le processus de préparation des données pour l'entraînement des modèles.
Pour évaluer nos modèles, nous avons mis en œuvre trois méthodes de **validation croisée**. La première méthode, `generate_split_predictions()`, divise l'ensemble de données en un ensemble d'entraînement et un ensemble de test en utilisant `train_test_split` de Surprise. Ensuite, avec `generate_loo_top_n()`, nous appliquons un processus **"leave-one-out"** pour générer des recommandations top-N et évaluer les performances du modèle. Enfin, `generate_full_top_n()` utilise l'**ensemble complet de données** pour **générer des recommandations** top-N sans division. Ces approches nous offrent une vision complète des performances de nos modèles dans différents scénarios. ### Features and Models
Pour améliorer notre évaluation, nous avons également introduit trois **nouvelles métriques**. La **première**, `rmse (split type)`, représente la racine carrée de l'erreur quadratique moyenne pour évaluer les prédictions. **Ensuite**, `hit rate (loo type)` mesure le taux de succès, indiquant le pourcentage d'utilisateurs pour lesquels l'un des films recommandés correspond à ceux notés dans l'ensemble de test. **Enfin**, `novelty (full type)` évalue la nouveauté des recommandations en fonction de la popularité des films recommandés, fournissant ainsi des informations sur la diversité et la pertinence des suggestions. ***models.py*** and ***content_based.ipynb***
<<<<<<< HEAD 1. ***Feature Extraction Methods***
- analytics_tiny.ipynb The system supports the following feature extraction methods:
- `genre`: Extracts genres of the movies using TF-IDF vectorization.
- `movie_year`: Extracts the release year of the movies.
- `avg_rating`: Computes the average rating for each movie.
- `title_length`: Computes the length of the movie title.
Dans le notebook "analytics_tiny.ipynb", plusieurs analyses ont été menées sur un ensemble de données, surnommé "tiny", étant un dataset réduit du dataset "small". Tout d'abord, le nombre total de notes a été calculé, permettant ainsi d'avoir une vue d'ensemble de la taille de l'ensemble de données. Ensuite, le nombre d'utilisateurs uniques a été déterminé, offrant ainsi un aperçu de la diversité des utilisateurs qui ont contribué aux évaluations des films. De même, le nombre de films uniques dans la matrice des notes a été extrait, ce qui donne un aperçu du nombre de films différents présents dans l'ensemble de données. 2. ***Regression Models***
The system supports the following regression models for predicting user ratings:
Une analyse a également été réalisée pour identifier le(s) film(s) le(s) plus noté(s), ainsi que le(s) film(s) le(s) moins noté(s). Ces informations permettent de repérer les tendances de popularité et les cas exceptionnels dans les données. Ensuite, toutes les valeurs de notation possibles ont été recueillies, de la plus petite à la plus grande valeur. Cette étape est importante pour comprendre la gamme des évaluations et identifier d'éventuelles anomalies ou biais dans les données. - `linear_regression`
- `random_forest`
- `lasso_regression`
- `gradient_boosting`
- `ridge_regression`
- `svr_regression`
- `elastic_net`
- `knn_regression`
- `decision_tree`
- `adaboost`
- `xgboost`
- `lightgbm`
Un autre aspect exploré était le nombre de films qui n'ont reçu aucune note. Cette mesure offre un aperçu de la couverture des évaluations dans l'ensemble de données et peut révéler des lacunes potentielles. En ce qui concerne la section "Long-tail property", une évaluation de la sparsité de la matrice a été réalisée. Cela impliquait le calcul d'une métrique de sparsité ainsi qu'une observation visuelle de la distribution des notes dans la matrice. Cette analyse permet de déterminer dans quelle mesure les données suivent la propriété de la longue traîne, souvent observée dans les systèmes de recommandation.
En complément des analyses mentionnées, une distribution des 'ratings' par films a été effectuée. Cette distribution offre un aperçu détaillé de la manière dont les différentes notes sont réparties entre les films, mettant en lumière les tendances de notation et les variations de popularité parmi les films. De plus, une matrice de sparsité a été calculée pour évaluer la densité des données. Cette matrice montre la proportion de cases vides ou non renseignées dans la matrice des notes, ce qui est crucial pour comprendre la disponibilité des données et leur potentiel pour l'analyse et la modélisation. ### evaluator.ipynb
- analytics_test.ipynb `generate_split_predictions`: This function splits the dataset into training and testing sets, trains the model on the training set, and generates predictions on the test set.
Dans le notebook "analytics_test.ipynb", plusieurs analyses ont été menées sur un ensemble de données, surnommé "test", qui comprend 6 utilisateurs et 10 éléments (films) permettant ainsi . Tout d'abord, le nombre total de notes a été calculé, permettant ainsi d'avoir une vue d'ensemble de la taille de l'ensemble de données. Ensuite, le nombre d'utilisateurs uniques a été déterminé, offrant ainsi un aperçu de la diversité des utilisateurs qui ont contribué aux évaluations des films. De même, le nombre de films uniques dans la matrice des notes a été extrait, ce qui donne un aperçu du nombre de films différents présents dans l'ensemble de données. `generate_loo_top_n`: This function performs a leave-one-out (LOO) split of the dataset, then generates top-n recommendations for each user.
Une analyse a également été réalisée pour identifier le(s) film(s) le(s) plus noté(s), ainsi que le(s) film(s) le(s) moins noté(s). Ces informations permettent de repérer les tendances de popularité et les cas exceptionnels dans les données. Ensuite, toutes les valeurs de notation possibles ont été recueillies, de la plus petite à la plus grande valeur. Cette étape est importante pour comprendre la gamme des évaluations et identifier d'éventuelles anomalies ou biais dans les données. `generate_full_top_n`: This function generates top-n recommendations for each user using the full dataset.
precomputed_information: This function precomputes relevant information for evaluation in full mode.
Un autre aspect exploré était le nombre de films qui n'ont reçu aucune note. Cette mesure offre un aperçu de la couverture des évaluations dans l'ensemble de données et peut révéler des lacunes potentielles. En ce qui concerne la section "Long-tail property", une évaluation de la sparsité de la matrice a été réalisée. Cela impliquait le calcul d'une métrique de sparsité ainsi qu'une observation visuelle de la distribution des notes dans la matrice. Cette analyse permet de déterminer dans quelle mesure les données suivent la propriété de la longue traîne, souvent observée dans les systèmes de recommandation. `create_evaluation_report`: This function creates a DataFrame evaluating various models on metrics specified in an evaluation configuration.
En complément des analyses mentionnées, une distribution des 'ratings' par films a été effectuée. Cette distribution offre un aperçu détaillé de la manière dont les différentes notes sont réparties entre les films, mettant en lumière les tendances de notation et les variations de popularité parmi les films. De plus, une matrice de sparsité a été calculée pour évaluer la densité des données. Cette matrice montre la proportion de cases vides ou non renseignées dans la matrice des notes, ce qui est crucial pour comprendre la disponibilité des données et leur potentiel pour l'analyse et la modélisation. `get_hit_rate`: Computes the average hit rate of top-n recommendations.
### Evaluator block `get_novelty`: Computes the average novelty of top-n recommendations.
- **evaluator.ipynb** Definition of a dictionary containing available metrics for different evaluation steps (splits, LOO, full).
Pour ce jupyter notebook Evaluator.ipynb, l'importation de certains **packages** et modules clés est essentielle. Dans notre cas, nous avons importé les packages `model_selection` et `accuracy` de **Surprise**, ce dernier étant nécessaire pour effectuer une **validation croisée** et utiliser des **métriques** prédéfinies pour **évaluer les modèles**. Cela nous permettra d'obtenir des informations précieuses sur les performances de nos modèles de recommandation. Loading data, generating evaluation reports for different models, and saving experimental outcomes.
En ce qui concerne l'adaptation des **loaders**, nous avons apporté des modifications à la fonction `load_ratings()`. Cette fonction a été ajustée pour permettre le chargement de données dans un **format** compatible avec **Surprise**. Un argument supplémentaire, `surprise_format`, a été ajouté pour conditionner le chargement en un objet **Dataset** compatible Surprise à partir d'un **DataFrame Pandas**. Cela simplifie grandement le processus de préparation des données pour l'entraînement des modèles. ### Hackathon_make_predictions.ipynb
Pour évaluer nos modèles, nous avons mis en œuvre trois méthodes de **validation croisée**. La première méthode, `generate_split_predictions()`, divise l'ensemble de données en un ensemble d'entraînement et un ensemble de test en utilisant `train_test_split` de Surprise. Ensuite, avec `generate_loo_top_n()`, nous appliquons un processus **"leave-one-out"** pour générer des recommandations top-N et évaluer les performances du modèle. Enfin, `generate_full_top_n()` utilise l'**ensemble complet de données** pour **générer des recommandations** top-N sans division. Ces approches nous offrent une vision complète des performances de nos modèles dans différents scénarios. Define a function make_hackathon_prediction that takes feature_method and regressor_method as input.
Pour améliorer notre évaluation, nous avons également introduit trois **nouvelles métriques**. La **première**, `rmse (split type)`, représente la racine carrée de l'erreur quadratique moyenne pour évaluer les prédictions. **Ensuite**, `hit rate (loo type)` mesure le taux de succès, indiquant le pourcentage d'utilisateurs pour lesquels l'un des films recommandés correspond à ceux notés dans l'ensemble de test. **Enfin**, `novelty (full type)` évalue la nouveauté des recommandations en fonction de la popularité des films recommandés, fournissant ainsi des informations sur la diversité et la pertinence des suggestions. Inside this function:
Pour conclure notre processus d'évaluation, nous avons mis en place une fonction `export_evaluation_report()`. Cette fonction permet d'**exporter le rapport** d'évaluation vers un **fichier CSV** dans un répertoire spécifié. Cela facilite le partage et la consultation des résultats, ce qui est crucial pour optimiser nos modèles et affiner nos stratégies de recommandation. - Load the training data and converts it into the format suitable for Surprise.
- Train a Content-Based model (ContentBased) on the training set using the specified feature and regressor methods.
- Make predictions on the test set by loading the test data from a CSV file and converting it into records.
Converts the predictions into a DataFrame and saves them as a CSV file.
It then calls this function with specific parameters and prints the generated predictions.
### User_based (à compléter)
### Recommender_UI (à compléter) ### Dataset
======= Organized under the data/test/ directory, which contains three subdirectories:
Pour conclure notre processus d'évaluation, nous avons mis en place une fonction `export_evaluation_report()`. Cette fonction permet d'**exporter le rapport** d'évaluation vers un **fichier CSV** dans un répertoire spécifié. Cela facilite le partage et la consultation des résultats, ce qui est crucial pour optimiser nos modèles et affiner nos stratégies de recommandation. - content: Contains movies.csv & tags.csv files.
>>>>>>> Evaluator - evidence: Contains ratings.csv file.
- evaluations: Directory reserved for evaluation results
## Contact ## Contact
Pour toute question, suggestion, ou demande de collaboration sur ce projet, n'hésitez pas à nous contacter. Pour des discussions plus approfondies sur notre recherche et notre méthodologie, nous pouvez contacter :
- Audrey Ghilain à audrey.ghilain@student.uclouvain.be
- Nathanaël Kindidi à nathanael.kindidi@student.uclouvain.be
- Charles Addae à charles.addae@student.uclouvain.be
- Adrien Payen à adrien.payen@student.uclouvain.be
## Remerciements For questions or collaboration requests, please contact:
Nous tenons à exprimer notre gratitude envers plusieurs parties qui ont jouées un rôle crucial dans la réalisation de ce projet :
- **Professeur Vande Kerckhove Corentin** : Pour son enseignement en recommender system. Son soutien et ses conseils ont été essentiels pour l'adaptation et l'amélioration de nos codes dans notre projet. - Audrey Ghilain: audrey.ghilain@student.uclouvain.be
- Nathanaël Kindidi: nathanael.kindidi@student.uclouvain.be
- Charles Addae: charles.addae@student.uclouvain.be
- Adrien Payen: adrien.payen@student.uclouvain.be
- **Else...** ## Acknowledgements
We thank Professor Vande Kerckhove Corentin for his guidance on recommender systems, which was crucial in adapting and improving our project.
## Auteurs
## Authors
- Audrey Ghilain - Audrey Ghilain
- Nathanaël Kindidi - Nathanaël Kindidi
- Charles Addae - Charles Addae
- Adrien Payen - Adrien Payen
## References
## Références - [Surprise Documentation](https://surprise.readthedocs.io/en/stable/)
- [Pandas Documentation](https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html)
### Evaluator_block - [Numpy Documentation](https://numpy.org/doc/stable/user/quickstart.html)
- [MLSMM2156 Course Materials](https://forge.uclouvain.be/cvandekerckh/mlsmm2156)
- https://forge.uclouvain.be/cvandekerckh/mlsmm2156 - [Extra Reference 1](https://bit.ly/3qnwKXa)
- https://bit.ly/3qnwKXa - [Extra Reference 2](https://bit.ly/4cBLxDM)
- https://bit.ly/4cBLxDM
- https://numpy.org/doc/stable/user/quickstart.html
- https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html
- https://pandas.pydata.org/docs/reference/frame.html
<<<<<<< HEAD
- https://www.jillcates.com/pydata-workshop/html/tutorial.html
2. **Evaluator_block**
- https://forge.uclouvain.be/cvandekerckh/mlsmm2156
- https://bit.ly/3qnwKXa
- https://bit.ly/4cBLxDM
- https://numpy.org/doc/stable/user/quickstart.html
- https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html
- https://pandas.pydata.org/docs/reference/frame.html
- https://surprise.readthedocs.io/en/stable/
3. **User_based** (à compléter)
4. **Recommender_UI** (à compléter)
=======
- https://surprise.readthedocs.io/en/stable/
>>>>>>> Evaluator
# local imports # local imports
from models import * from models import *
from itertools import combinations
# Available feature extraction methods
features_methods = [
'genre', 'movie_year', 'avg_rating',
'title_length'
]
# Available regression methods
regressor_methods = [
'linear_regression','random_forest', 'lasso_regression','gradient_boosting',
'ridge_regression', 'svr_regression'
]
# Generate all possible combinations of feature extraction methods
feature_combinations = []
for r in range(1, len(features_methods) + 1):
feature_combinations.extend(combinations(features_methods, r))
# Generate all possible combinations of regression methods and feature extraction methods
model_combinations = []
for feature_set in feature_combinations:
for regressor in regressor_methods:
# Create a unique model name for the combination
model_name = f"combination_{regressor}_{'_'.join(feature_set)}"
# Define the arguments to be passed to the model
arguments = {
"features_method": list(feature_set),
"regressor_method": regressor
}
# Append the combination to the list
model_combinations.append((model_name, ContentBased, arguments))
class EvalConfig: class EvalConfig:
"""Configuration settings for evaluation.""" """Configuration settings for evaluation."""
# List of models to evaluate, each tuple containing model_name, model class, and model parameters (dict) # List of models to evaluate, each tuple containing model_name, model class, and model parameters (dict)
models = [ models = [
("baseline_1", ModelBaseline1, {}), ("baseline_1", ModelBaseline1, {}),
("baseline_2", ModelBaseline2, {}), ("baseline_2", ModelBaseline2, {}),
("baseline_3", ModelBaseline3, {}), ("baseline_3", ModelBaseline3, {}),
("baseline_4", ModelBaseline4, {}), ("baseline_4", ModelBaseline4, {}),
<<<<<<< HEAD
("title_length_ContentBased_sample", ContentBased, {"title_length","random_sample"}), ("title_length_ContentBased_sample", ContentBased, {"title_length","random_sample"}),
("title_length_ContentBased_score", ContentBased, {"features_method" : ["title_length"], "regressor_method" : "random_score"}), ("title_length_ContentBased_score", ContentBased, {"features_method" : ["title_length"], "regressor_method" : "random_score"}),
...@@ -70,8 +100,17 @@ class EvalConfig: ...@@ -70,8 +100,17 @@ class EvalConfig:
#("timestamp_ContentBased_Lr", ContentBased, {"features_method" : "timestamp", "regressor_method" : "random_forest"}) #("timestamp_ContentBased_Lr", ContentBased, {"features_method" : "timestamp", "regressor_method" : "random_forest"})
# model_name, model class, model parameters (dict) # model_name, model class, model parameters (dict)
=======
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
] ]
# Add the combinations of ContentBased models to the list of models
models.extend(model_combinations)
# Print the models for verification
for model in models:
print(model)
# Metrics to compute for split evaluation # Metrics to compute for split evaluation
split_metrics = ["mae", "rmse"] split_metrics = ["mae", "rmse"]
...@@ -82,7 +121,7 @@ class EvalConfig: ...@@ -82,7 +121,7 @@ class EvalConfig:
full_metrics = ["novelty"] full_metrics = ["novelty"]
# Split parameters # Split parameters
test_size = 0.25 # -- configure the test_size (from 0 to 1) -- test_size = 0.25 # Configure the test size (from 0 to 1)
# Loo parameters # Loo parameters
top_n_value = 10 # -- configure the numer of recommendations (> 1) -- top_n_value = 10 # -- configure the numer of recommendations (> 1) --
......
...@@ -371,7 +371,11 @@ ...@@ -371,7 +371,11 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
<<<<<<< HEAD
"execution_count": 11, "execution_count": 11,
=======
"execution_count": 4,
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
"id": "69d12f7d", "id": "69d12f7d",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
......
mae,rmse,hit_rate,novelty
1.9375,2.084166500066633,1.0,6.033333333333333
0.8173909396336634,1.1059619047579765,1.0,6.033333333333333
1.3522727272727273,1.5529563914415012,1.0,6.033333333333333
0.6376592267695946,0.8042305457685027,1.0,6.033333333333333
1.6628239910214841,2.2525419495259897,1.0,6.033333333333333
1.20875,1.5240447828065946,0.6666666666666666,6.033333333333333
1.684375017708381,2.069155969305595,0.3333333333333333,6.033333333333333
2.4114596072893635,2.739605663857449,1.0,6.033333333333333
1.0217964071764583,1.2950828283650457,0.6666666666666666,6.033333333333333
2.163957610955193,2.2191386648373905,1.0,6.033333333333333
1.8845151413267085,2.1885660845816606,1.0,6.033333333333333
1.4457083333333334,1.6432018160692659,1.0,6.033333333333333
1.089495507947479,1.3199265934971351,1.0,6.033333333333333
2.1249701184262513,2.5124391721430093,1.0,6.033333333333333
1.9903037383177526,2.1648166502861743,1.0,6.033333333333333
2.1795543366291588,2.4475339850764137,0.5,6.033333333333333
1.042603806228374,1.3190440370243655,1.0,6.033333333333333
1.345,1.4879768143354923,0.5,6.033333333333333
1.625,1.8874586088176875,1.0,6.033333333333333
0.6250199210491658,0.7500066413785784,1.0,6.033333333333333
1.1889822134387353,1.3301663410286015,1.0,6.033333333333333
1.4260175787538103,1.7526331577875662,1.0,6.033333333333333
2.035956132879046,2.2392272260022303,1.0,6.033333333333333
2.4325,2.662808667553867,1.0,6.033333333333333
0.7577319587628866,0.9064878165466178,1.0,6.033333333333333
1.187507304384694,1.2869615072881615,1.0,6.033333333333333
1.9375,2.2306817014584404,1.0,6.033333333333333
1.6875,2.229069312515876,1.0,6.033333333333333
1.7437278923981316,2.066134061830712,1.0,6.033333333333333
2.0625,2.4302777619029476,0.5,6.033333333333333
1.0649275507979001,1.2600681842567545,1.0,6.033333333333333
2.3575953907918965,2.579745654168279,1.0,6.033333333333333
0.7556566691208932,0.885874687797249,1.0,6.033333333333333
1.1248590453156881,1.2989522624394272,1.0,6.033333333333333
1.3125000000000004,1.489546910976624,1.0,6.033333333333333
1.53125,1.8194264206062305,1.0,6.033333333333333
1.893838507776031,2.113561211368271,1.0,6.033333333333333
1.1897016346895573,1.4200974774733546,1.0,6.033333333333333
1.233798125149878,1.489803909706273,1.0,6.033333333333333
1.5,1.8027756377319946,1.0,6.033333333333333
0.6093750000000373,0.7856361415272141,1.0,6.033333333333333
0.96875,1.1312437845133116,1.0,6.033333333333333
1.5625,1.9445436482630056,1.0,6.033333333333333
1.2727272727272727,1.9370250684238652,1.0,6.033333333333333
0.7184952128466214,1.025968094911007,0.6666666666666666,6.033333333333333
1.9801136363636362,2.456635789209798,1.0,6.033333333333333
1.1112849044534425,1.2468827279310877,1.0,6.033333333333333
1.59875,2.037524045388714,0.6666666666666666,6.033333333333333
0.8178702441100469,0.9727394974975663,1.0,6.033333333333333
1.6609834638008552,1.995966032390679,1.0,6.033333333333333
1.3022621814756867,1.6778980104509307,1.0,6.033333333333333
1.4573863636363638,2.0809886944145064,1.0,6.033333333333333
2.303640828449435,2.6195931138116513,0.6666666666666666,6.033333333333333
2.1025,2.3433522995913356,1.0,6.033333333333333
1.6314960570270465,1.9830966443416194,1.0,6.033333333333333
2.125,2.7613402542968153,0.6666666666666666,6.033333333333333
1.528863932115172,1.9335257759117712,1.0,6.033333333333333
1.6875,1.9121323175972944,1.0,6.033333333333333
1.804380695153122,1.9228936489731094,1.0,6.033333333333333
1.1675,1.4070092394863654,0.5,6.033333333333333
0.6965952092290841,1.0836853872787664,1.0,6.033333333333333
1.6875,2.2430448056157952,1.0,6.033333333333333
1.1875,1.4684175155588413,1.0,6.033333333333333
1.479821340872148,1.9458984266330215,1.0,6.033333333333333
1.941197805013935,2.1183689843976246,1.0,6.033333333333333
1.6875,2.1578345627040085,1.0,6.033333333333333
1.7249653739612185,1.935503632631837,1.0,6.033333333333333
1.7914103483944959,2.0005640681138166,1.0,6.033333333333333
1.1797318479744767,1.4685570107218253,1.0,6.033333333333333
0.8756123537025489,1.1994977445758592,1.0,6.033333333333333
2.621407602118329,2.8927354609118647,1.0,6.033333333333333
1.5,1.984313483298443,0.3333333333333333,6.033333333333333
1.4573863636363638,1.7728547448341594,1.0,6.033333333333333
1.7580150767843947,1.9876898950935187,1.0,6.033333333333333
1.279906460486191,1.5536596229737014,0.6666666666666666,6.033333333333333
1.8125,2.2125265558475404,1.0,6.033333333333333
1.9261501478377108,2.1388848010836297,1.0,6.033333333333333
1.635,1.8516529777471804,0.6666666666666666,6.033333333333333
2.278125,2.369813415651114,0.5,6.033333333333333
1.875,2.48746859276655,1.0,6.033333333333333
0.9734840904749582,1.3788339278310844,0.5,6.033333333333333
0.8806818181818181,1.1731544324231358,1.0,6.033333333333333
2.5625,2.721442632134655,1.0,6.033333333333333
1.16875,1.3717347593467186,1.0,6.033333333333333
1.4631920887826695,1.8364514186307193,1.0,6.033333333333333
1.2395512370799229,1.6073871861317153,1.0,6.033333333333333
1.0625,1.489546910976623,1.0,6.033333333333333
2.5,2.7950849718747373,1.0,6.033333333333333
2.111741628375439,2.5341799606842312,1.0,6.033333333333333
1.51,1.57175061635108,1.0,6.033333333333333
2.25,2.75,1.0,6.033333333333333
1.559013760634053,1.79408180355516,1.0,6.033333333333333
0.9327974138411346,1.4123169289457636,1.0,6.033333333333333
1.5003782268968684,1.7144006301607126,1.0,6.033333333333333
Ce diff est replié.
Ce diff est replié.
...@@ -10,13 +10,25 @@ from surprise import PredictionImpossible ...@@ -10,13 +10,25 @@ from surprise import PredictionImpossible
from sklearn.metrics import mean_squared_error from sklearn.metrics import mean_squared_error
from pprint import pprint as pp from pprint import pprint as pp
# import local # import local
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import TfidfVectorizer
from loaders import load_items, load_ratings from loaders import load_items, load_ratings
from constants import Constant as C from constants import Constant as C
from sklearn.linear_model import LinearRegression from sklearn.linear_model import LinearRegression
from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor
<<<<<<< HEAD
from sklearn.ensemble import BaggingRegressor from sklearn.ensemble import BaggingRegressor
=======
from sklearn.linear_model import Lasso, Ridge, ElasticNet
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.feature_extraction.text import TfidfVectorizer
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
from sklearn.svm import SVR from sklearn.svm import SVR
...@@ -120,10 +132,14 @@ class ModelBaseline4(SVD): ...@@ -120,10 +132,14 @@ class ModelBaseline4(SVD):
# ContetnBased # ContetnBased
class ContentBased(AlgoBase): class ContentBased(AlgoBase):
def __init__(self, features_method, regressor_method): def __init__(self, features_method, regressor_method,is_hackathon=False):
AlgoBase.__init__(self) AlgoBase.__init__(self)
self.regressor_method = regressor_method self.regressor_method = regressor_method
self.features_methods = features_method self.features_methods = features_method
<<<<<<< HEAD
=======
self.is_hackathon = is_hackathon
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
self.content_features = self.create_content_features(features_method) self.content_features = self.create_content_features(features_method)
self.user_profile = {} self.user_profile = {}
self.user_profile_explain = {} self.user_profile_explain = {}
...@@ -164,6 +180,10 @@ class ContentBased(AlgoBase): ...@@ -164,6 +180,10 @@ class ContentBased(AlgoBase):
df_features.fillna(0, inplace=True) df_features.fillna(0, inplace=True)
return df_features return df_features
<<<<<<< HEAD
=======
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
def fit(self, trainset): def fit(self, trainset):
"""Profile Learner""" """Profile Learner"""
...@@ -205,6 +225,31 @@ class ContentBased(AlgoBase): ...@@ -205,6 +225,31 @@ class ContentBased(AlgoBase):
self.user_profile_explain[raw_user_id] = dict(zip(self.content_features.columns, feature_importance)) self.user_profile_explain[raw_user_id] = dict(zip(self.content_features.columns, feature_importance))
<<<<<<< HEAD
=======
self.user_profile_explain = {}
# Loop over all internal user IDs in the trainset
for u in trainset.all_users():
# Convert internal user ID to raw user ID
raw_user_id = trainset.to_raw_uid(u)
# Initialize feature importance dictionary for the raw user ID
self.user_profile_explain[raw_user_id] = {}
# Extract user ratings for the current user
user_ratings = np.array([rating for _, rating in trainset.ur[u]])
# Compute feature importance based on content features and user ratings
feature_values = self.content_features.values.astype(int)
weighted_features = feature_values / np.linalg.norm(feature_values)
feature_importance = weighted_features / np.sum(user_ratings)
# Map feature importance scores to feature names and store in user_profile_explain
self.user_profile_explain[raw_user_id] = dict(zip(self.content_features.columns, feature_importance))
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
if self.regressor_method == 'random_score': if self.regressor_method == 'random_score':
for u in self.user_profile: for u in self.user_profile:
self.user_profile[u] = rd.uniform(0.5, 5) self.user_profile[u] = rd.uniform(0.5, 5)
...@@ -225,7 +270,12 @@ class ContentBased(AlgoBase): ...@@ -225,7 +270,12 @@ class ContentBased(AlgoBase):
'knn_regression': KNeighborsRegressor(n_neighbors=1), 'knn_regression': KNeighborsRegressor(n_neighbors=1),
'decision_tree': DecisionTreeRegressor(max_depth=5), 'decision_tree': DecisionTreeRegressor(max_depth=5),
'adaboost': AdaBoostRegressor(n_estimators=50), 'adaboost': AdaBoostRegressor(n_estimators=50),
<<<<<<< HEAD
'xgboost': XGBRegressor(n_estimators=100, learning_rate=0.1, max_depth=3) 'xgboost': XGBRegressor(n_estimators=100, learning_rate=0.1, max_depth=3)
=======
'xgboost': XGBRegressor(n_estimators=100, learning_rate=0.1, max_depth=3),
'lightgbm': LGBMRegressor(n_estimators=100, learning_rate=0.1, max_depth=3)
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
} }
if self.regressor_method not in regressor_models: if self.regressor_method not in regressor_models:
...@@ -288,6 +338,7 @@ class ContentBased(AlgoBase): ...@@ -288,6 +338,7 @@ class ContentBased(AlgoBase):
rmse_value = np.sqrt(mse) rmse_value = np.sqrt(mse)
return rmse_value return rmse_value
<<<<<<< HEAD
# Example usage: # Example usage:
cb = ContentBased(["title_length", "movie_year","genre","avg_rating"], "ridge_regression") cb = ContentBased(["title_length", "movie_year","genre","avg_rating"], "ridge_regression")
...@@ -323,3 +374,16 @@ testset = trainset.build_anti_testset() ...@@ -323,3 +374,16 @@ testset = trainset.build_anti_testset()
# print(f"Utilisateur {user_id}:") # print(f"Utilisateur {user_id}:")
# for item_id, rating in user_recommendations: # for item_id, rating in user_recommendations:
# print(f" - Item {item_id}, estimation de note : {rating}") # print(f" - Item {item_id}, estimation de note : {rating}")
=======
def test_contentbased_class(feature_method, regressor_method):
"""Test the ContentBased class.
Tries to make a prediction on the first (user,item ) tuple of the anti_test_set
"""
sp_ratings = load_ratings(surprise_format=True)
train_set = sp_ratings.build_full_trainset()
content_algo = ContentBased(feature_method, regressor_method)
content_algo.fit(train_set)
anti_test_set_first = train_set.build_anti_testset()[0]
prediction = content_algo.predict(anti_test_set_first[0], anti_test_set_first[1])
print(prediction)
>>>>>>> 5385c4bc3a5802e1caec979d0d3a6bc7af3e970f
Ce diff est replié.
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter