181 lines
7.7 KiB
Gherkin
181 lines
7.7 KiB
Gherkin
# language: fr
|
||
Fonctionnalité: Formule de scoring et recommandation
|
||
En tant que système de recommandation
|
||
Je veux calculer un score combiné pour chaque contenu
|
||
Afin de proposer les contenus les plus pertinents à l'utilisateur
|
||
|
||
Contexte:
|
||
Étant donné que l'API RoadWave est disponible
|
||
|
||
Scénario: Calcul du score géographique linéaire
|
||
Étant donné qu'un contenu existe à Paris
|
||
Et que la distance_max_km est configurée à 200 km
|
||
Quand un utilisateur est à 50 km du contenu
|
||
Alors le score_geo = 1 - (50 / 200) = 0.75
|
||
|
||
Scénario: Score géo à distance nulle (sur place)
|
||
Étant donné qu'un contenu existe à un point GPS précis
|
||
Quand un utilisateur est exactement au même point (0 km)
|
||
Alors le score_geo = 1.0 (maximum)
|
||
|
||
Scénario: Score géo à distance_max (200 km)
|
||
Étant donné qu'un contenu existe à Paris
|
||
Quand un utilisateur est à 200 km du contenu
|
||
Alors le score_geo = 1 - (200 / 200) = 0.0
|
||
|
||
Scénario: Score géo au-delà de distance_max
|
||
Étant donné qu'un contenu existe à Paris
|
||
Quand un utilisateur est à 250 km du contenu (au-delà de 200 km max)
|
||
Alors le score_geo = 0.0 (minimum)
|
||
Et le contenu a peu de chances d'être recommandé sauf engagement très élevé
|
||
|
||
Scénario: Calcul du score d'intérêts avec jauges utilisateur
|
||
Étant donné qu'un utilisateur a les jauges suivantes:
|
||
| categorie | niveau |
|
||
| Automobile | 80% |
|
||
| Voyage | 60% |
|
||
| Musique | 40% |
|
||
Et qu'un contenu est tagué "Automobile" et "Voyage"
|
||
Quand l'algorithme calcule le score_interets
|
||
Alors score_interets = (0.8 + 0.6) / 2 = 0.7
|
||
|
||
Scénario: Score d'intérêts avec un seul tag
|
||
Étant donné qu'un utilisateur a la jauge "Économie" à 90%
|
||
Et qu'un contenu est tagué uniquement "Économie"
|
||
Quand l'algorithme calcule le score_interets
|
||
Alors score_interets = 0.9
|
||
|
||
Scénario: Score d'intérêts avec tags non matchés
|
||
Étant donné qu'un utilisateur a des jauges "Sport" et "Politique" élevées
|
||
Et qu'un contenu est tagué "Musique" et "Philosophie"
|
||
Et que l'utilisateur n'a pas ces catégories
|
||
Quand l'algorithme calcule le score_interets
|
||
Alors score_interets = 0.5 (neutre par défaut pour catégories inconnues)
|
||
|
||
Scénario: Calcul du score d'engagement avec métriques
|
||
Étant donné qu'un contenu a:
|
||
| metrique | valeur |
|
||
| ecoutes | 1000 |
|
||
| ecoutes_completes | 700 |
|
||
| likes | 300 |
|
||
| abonnements_apres | 50 |
|
||
Quand l'algorithme calcule le score_engagement
|
||
Alors taux_completion = 700 / 1000 = 0.7
|
||
Et ratio_likes = 300 / 1000 = 0.3
|
||
Et ratio_abonnements = 50 / 1000 = 0.05
|
||
Et score_engagement = (0.7 × 0.5) + (0.3 × 0.3) + (0.05 × 0.2) = 0.35 + 0.09 + 0.01 = 0.45
|
||
|
||
Scénario: Contenu avec moins de 50 écoutes - score neutre
|
||
Étant donné qu'un contenu a seulement 30 écoutes
|
||
Quand l'algorithme calcule le score_engagement
|
||
Alors score_engagement = 0.5 (neutre par défaut)
|
||
Et le contenu n'est pas pénalisé pour manque de données
|
||
|
||
Scénario: Contenu avec exactement 50 écoutes - calcul réel
|
||
Étant donné qu'un contenu a exactement 50 écoutes
|
||
Et des métriques d'engagement complètes
|
||
Quand l'algorithme calcule le score_engagement
|
||
Alors le score est calculé normalement (pas de seuil neutre)
|
||
|
||
Scénario: Bonus aléatoire - 10% des recommandations
|
||
Étant donné qu'un utilisateur demande 10 recommandations
|
||
Et que la part_aleatoire_global est à 10%
|
||
Quand l'algorithme génère les recommandations
|
||
Alors 1 contenu sur 10 est tiré aléatoirement
|
||
Et 9 contenus sont calculés avec le score combiné
|
||
Et le contenu aléatoire n'est pas dans l'historique déjà écouté
|
||
|
||
Scénario: Curseur utilisateur découverte à 0% - aucun aléatoire
|
||
Étant donné qu'un utilisateur configure le curseur découverte à 0%
|
||
Quand l'utilisateur demande 20 recommandations
|
||
Alors les 20 contenus sont calculés avec le score combiné
|
||
Et aucun contenu aléatoire n'est proposé
|
||
|
||
Scénario: Curseur utilisateur découverte à 50% - découverte max
|
||
Étant donné qu'un utilisateur configure le curseur découverte à 50%
|
||
Quand l'utilisateur demande 20 recommandations
|
||
Alors 10 contenus sont tirés aléatoirement
|
||
Et 10 contenus sont calculés avec le score combiné
|
||
|
||
Scénario: Score final combiné pour contenu géo-ancré
|
||
Étant donné qu'un contenu "Géo-ancré" a:
|
||
| parametre | valeur |
|
||
| score_geo | 0.9 |
|
||
| score_interets | 0.6 |
|
||
| score_engagement | 0.45 |
|
||
| poids_geo | 0.7 |
|
||
| poids_interets | 0.1 |
|
||
| poids_engagement | 0.2 |
|
||
Quand l'algorithme calcule le score_final
|
||
Alors score_final = (0.9 × 0.7) + (0.6 × 0.1) + (0.45 × 0.2)
|
||
Et score_final = 0.63 + 0.06 + 0.09 = 0.78
|
||
|
||
Scénario: Score final combiné pour contenu géo-neutre
|
||
Étant donné qu'un contenu "Géo-neutre" a:
|
||
| parametre | valeur |
|
||
| score_geo | 0.3 |
|
||
| score_interets | 0.9 |
|
||
| score_engagement | 0.6 |
|
||
| poids_geo | 0.2 |
|
||
| poids_interets | 0.6 |
|
||
| poids_engagement | 0.2 |
|
||
Quand l'algorithme calcule le score_final
|
||
Alors score_final = (0.3 × 0.2) + (0.9 × 0.6) + (0.6 × 0.2)
|
||
Et score_final = 0.06 + 0.54 + 0.12 = 0.72
|
||
Et le contenu peut être recommandé malgré la distance
|
||
|
||
Scénario: Contenu viral lointain peut être recommandé
|
||
Étant donné qu'un contenu viral existe à Paris
|
||
Et qu'il a un score_engagement très élevé de 0.95
|
||
Et qu'un utilisateur est à Marseille (score_geo = 0.1)
|
||
Quand l'algorithme calcule le score_final
|
||
Alors le score_engagement élevé compense le score_geo faible
|
||
Et le contenu peut apparaître dans les recommandations
|
||
|
||
Scénario: Ordre de recommandation par score décroissant
|
||
Étant donné 5 contenus avec les scores suivants:
|
||
| contenu | score_final |
|
||
| Contenu A | 0.85 |
|
||
| Contenu B | 0.72 |
|
||
| Contenu C | 0.90 |
|
||
| Contenu D | 0.65 |
|
||
| Contenu E | 0.78 |
|
||
Quand l'utilisateur demande des recommandations
|
||
Alors l'ordre de proposition est:
|
||
| position | contenu |
|
||
| 1 | Contenu C |
|
||
| 2 | Contenu A |
|
||
| 3 | Contenu E |
|
||
| 4 | Contenu B |
|
||
| 5 | Contenu D |
|
||
|
||
Scénario: Exclusion de l'historique déjà écouté >80%
|
||
Étant donné qu'un utilisateur a écouté les contenus suivants:
|
||
| contenu | completion |
|
||
| Contenu A | 85% |
|
||
| Contenu B | 95% |
|
||
| Contenu C | 30% |
|
||
Quand l'algorithme génère les recommandations
|
||
Alors "Contenu A" et "Contenu B" ne sont jamais proposés
|
||
Mais "Contenu C" peut être reproposé
|
||
|
||
Scénario: Pré-calcul de 5 contenus suivants
|
||
Étant donné qu'un utilisateur écoute un contenu
|
||
Quand l'algorithme prépare les contenus suivants
|
||
Alors 5 contenus sont pré-calculés selon le score
|
||
Et ces contenus sont mis en cache pour performance
|
||
|
||
Scénario: Recalcul si déplacement >10 km
|
||
Étant donné que 5 contenus suivants sont pré-calculés
|
||
Et que l'utilisateur se déplace de 12 km
|
||
Quand l'utilisateur demande le contenu suivant
|
||
Alors l'algorithme recalcule les scores avec la nouvelle position
|
||
Et propose de nouveaux contenus plus pertinents géographiquement
|
||
|
||
Scénario: Recalcul après 10 minutes d'inactivité
|
||
Étant donné que 5 contenus suivants sont pré-calculés
|
||
Et que 11 minutes se sont écoulées sans action
|
||
Quand l'utilisateur demande le contenu suivant
|
||
Alors l'algorithme recalcule les scores
|
||
Et prend en compte les nouveaux contenus publiés
|