DS MPSI - Système de recommandations - Analyse de notes de films

20 Mar 2026 20 Mar 2026 223 vues ESSADDOUKI Mostafa 6 min de lecture
Systèmes de recommandation Évaluations Structures imbriquées Intermédiaire
5 parties
12 questions
Python CPGE MPSI
~70 min

Système de recommandations - Analyse de notes de films

On modélise une plateforme où des utilisateurs notent des films. Les données sont représentées par un dictionnaire :

notes = {
    "Amina":  [("Inception", 5), ("Matrix", 4), ("Titanic", 3)],
    "Youssef": [("Inception", 4), ("Avatar", 5)],
    "Sara":   [("Matrix", 5), ("Avatar", 4), ("Titanic", 2)],
    "Hamza":  []
}

Chaque tuple (film, note) représente une évaluation (note sur 5).

1
Manipulation de base 2 questions
Q1

Écrire une fonction films_utilisateur(notes, nom) qui retourne la liste des films notés par nom.

Exemple

Entrée
films_utilisateur(notes, "Amina")
Sortie
["Inception", "Matrix", "Titanic"]
Solution — Films d'un utilisateur
def films_utilisateur(notes, nom):
    if nom not in notes:
        return []
    
    films = []
    for film, note in notes[nom]:
        films.append(film)
    
    return films
Q2

Écrire une fonction note_moyenne_utilisateur(notes, nom) qui retourne la moyenne des notes de nom. (Si aucune note → retourner None)

Exemple

Entrée
note_moyenne_utilisateur(notes, "Amina")
Sortie
4.0
Solution — Moyenne d'un utilisateur
def note_moyenne_utilisateur(notes, nom):
    if nom not in notes or not notes[nom]:
        return None
    
    total = 0
    for film, note in notes[nom]:
        total += note
    
    return total / len(notes[nom])
2
Agrégation globale 3 questions
Q3

Écrire ensemble_films(notes) qui retourne l'ensemble de tous les films notés.

Solution — Ensemble des films
def ensemble_films(notes):
    films = set()
    for utilisateur, evaluations in notes.items():
        for film, note in evaluations:
            films.add(film)
    return films
Q4

Écrire notes_film(notes, film) qui retourne la liste des notes attribuées au film.

Exemple

Entrée
notes_film(notes, "Matrix")
Sortie
[4, 5]
Solution — Notes d'un film
def notes_film(notes, film):
    notes_list = []
    for utilisateur, evaluations in notes.items():
        for f, note in evaluations:
            if f == film:
                notes_list.append(note)
    return notes_list
Q5

Écrire moyenne_film(notes, film) qui retourne la moyenne des notes du film. (Si le film n'a aucune note → retourner None)

Solution — Moyenne d'un film
def moyenne_film(notes, film):
    notes_list = notes_film(notes, film)
    if not notes_list:
        return None
    return sum(notes_list) / len(notes_list)
3
Analyse avancée 3 questions
Q6

Écrire meilleur_film(notes) qui retourne le film ayant la meilleure moyenne. (égalité → plus petit nom lexicographiquement)

Solution — Meilleur film
def meilleur_film(notes):
    max_moyenne = -1
    meilleur = None
    
    for film in ensemble_films(notes):
        moy = moyenne_film(notes, film)
        if moy is not None:
            if moy > max_moyenne:
                max_moyenne = moy
                meilleur = film
            elif moy == max_moyenne:
                if meilleur is None or film < meilleur:
                    meilleur = film
    
    return meilleur
Q7

Écrire utilisateurs_ayant_note(notes, film) qui retourne la liste triée des utilisateurs ayant noté film.

Solution — Utilisateurs ayant noté un film
def utilisateurs_ayant_note(notes, film):
    utilisateurs = []
    for user, evaluations in notes.items():
        for f, note in evaluations:
            if f == film:
                utilisateurs.append(user)
                break
    
    utilisateurs.sort()
    return utilisateurs
Q8

Écrire matrice_utilisateur_film(notes) qui retourne un dictionnaire de dictionnaires tel que : $$\text{res}[u][f] = \text{note de } u \text{ pour } f$$ (si aucune note → absence de clé)

Exemple (partiel attendu)

Sortie
{
    "Amina": {"Inception": 5, "Matrix": 4, "Titanic": 3},
    "Youssef": {"Inception": 4, "Avatar": 5},
    "Sara": {"Matrix": 5, "Avatar": 4, "Titanic": 2},
    "Hamza": {}
}
Solution — Matrice utilisateur-film
def matrice_utilisateur_film(notes):
    matrice = {}
    for user, evaluations in notes.items():
        dico = {}
        for film, note in evaluations:
            dico[film] = note
        matrice[user] = dico
    return matrice
4
Recommandation 2 questions
Q9

Écrire films_non_vus(notes, nom) qui retourne l'ensemble des films que nom n'a pas encore notés.

Exemple

Entrée
films_non_vus(notes, "Youssef")
Sortie
{"Matrix", "Titanic"}
Solution — Films non vus
def films_non_vus(notes, nom):
    tous_les_films = ensemble_films(notes)
    films_vus = set(films_utilisateur(notes, nom))
    return tous_les_films - films_vus
Q10

Écrire recommandation(notes, nom) qui retourne le film non vu par nom ayant la meilleure moyenne globale. (Si aucun film → retourner None)

Exemple

Entrée
recommandation(notes, "Youssef")
Sortie
"Matrix"
Explication :
Films non vus : Matrix, Titanic
Moyennes : Matrix = 4.5, Titanic = 2.5
Solution — Recommandation
def recommandation(notes, nom):
    non_vus = films_non_vus(notes, nom)
    if not non_vus:
        return None
    
    max_moyenne = -1
    meilleur_film = None
    
    for film in non_vus:
        moy = moyenne_film(notes, film)
        if moy is not None:
            if moy > max_moyenne:
                max_moyenne = moy
                meilleur_film = film
            elif moy == max_moyenne:
                if meilleur_film is None or film < meilleur_film:
                    meilleur_film = film
    
    return meilleur_film
5
Extension - Recommandation collaborative 2 questions
Q11

Écrire utilisateur_plus_proche(notes, nom) qui retourne l'utilisateur ayant le plus de films en commun avec nom. (égalité → plus petit nom)

Solution — Utilisateur le plus proche
def utilisateur_plus_proche(notes, nom):
    if nom not in notes:
        return None
    
    films_nom = set(films_utilisateur(notes, nom))
    max_communs = -1
    plus_proche = None
    
    for user, evaluations in notes.items():
        if user != nom:
            films_user = set(films_utilisateur(notes, user))
            communs = len(films_nom & films_user)
            
            if communs > max_communs:
                max_communs = communs
                plus_proche = user
            elif communs == max_communs:
                if plus_proche is None or user < plus_proche:
                    plus_proche = user
    
    return plus_proche
Q12

Écrire recommandation_collaborative(notes, nom) qui recommande un film aimé (note ≥ 4) par l'utilisateur le plus proche, mais non vu par nom.

Solution — Recommandation collaborative
def recommandation_collaborative(notes, nom):
    # Trouver l'utilisateur le plus proche
    proche = utilisateur_plus_proche(notes, nom)
    if proche is None:
        return None
    
    # Films non vus par nom
    non_vus = films_non_vus(notes, nom)
    
    # Films aimés par l'utilisateur proche (note >= 4)
    films_aimes = []
    for film, note in notes[proche]:
        if note >= 4:
            films_aimes.append(film)
    
    # Trouver un film aimé par proche et non vu par nom
    for film in films_aimes:
        if film in non_vus:
            return film
    
    return None
Sortie
// La sortie apparaîtra ici…
Prêt · Ctrl+Entrée pour exécuter

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.