File size: 3,126 Bytes
6ec767d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import sqlite3
import pandas as pd
import pickle
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

class EduRecommender:
    def __init__(self, db_path="bourses_reco.db", vector_path="bourses_vectors.pkl"):
        self.db_path = db_path
        # 1. Chargement du modèle IA (Une seule fois)
        print("⏳ Chargement du modèle multilingue...")
        self.model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
        
        # 2. Chargement des vecteurs de bourses
        with open(vector_path, "rb") as f:
            data = pickle.load(f)
            self.bourse_ids = data["ids"]
            self.bourse_vectors = data["vectors"]

    def _get_connection(self):
        return sqlite3.connect(self.db_path)

    def recommander_tout(self, user_id, top_n=3):
        conn = self._get_connection()
        
        # --- RÉCUPÉRATION ÉTUDIANT ---
        user = pd.read_sql(f"SELECT * FROM etudiants WHERE user_id = '{user_id}'", conn).iloc[0]
        print(f"\n🎯 Analyse pour : {user['nom']} ({user['interet_majeur']})")

        # --- PARTIE 1 : BOURSES (Matching Sémantique) ---
        # On crée un texte riche pour la recherche
        texte_recherche = f"Bourse en {user['interet_majeur']} pour niveau {user['niveau_actuel']}"
        user_vector = self.model.encode([texte_recherche])
        
        sim_bourses = cosine_similarity(user_vector, self.bourse_vectors)[0]
        df_bourses_res = pd.DataFrame({'bourse_id': self.bourse_ids, 'score_ia': sim_bourses})
        
        # Jointure SQL pour avoir les détails et filtrer par Statut OUVERT
        bourses_final = pd.merge(df_bourses_res, pd.read_sql("SELECT * FROM bourses WHERE statut='OUVERT'", conn), on='bourse_id')
        top_bourses = bourses_final.sort_values(by='score_ia', ascending=False).head(top_n)

        # --- PARTIE 2 : FORMATIONS (Gap Filling) ---
        df_form = pd.read_sql("SELECT * FROM formations", conn)
        form_vectors = self.model.encode(df_form['competence_cible'].tolist())
        
        sim_form = cosine_similarity(user_interest_vec := self.model.encode([user['interet_majeur']]), form_vectors)[0]
        df_form['score_formation'] = sim_form
        top_formations = df_form.sort_values(by='score_formation', ascending=False).head(top_n)

        conn.close()
        return top_bourses, top_formations

# --- EXÉCUTION DU SYSTÈME ---
if __name__ == "__main__":
    # ICI : tu l'as appelé 'recommender' (anglais)
    recommender = EduRecommender() 
    
    conn = sqlite3.connect("bourses_reco.db")
    test_user_id = pd.read_sql("SELECT user_id FROM etudiants LIMIT 1", conn).iloc[0]['user_id']
    conn.close()

    # ERREUR ICI : Change 'recommander' en 'recommender' pour matcher l'objet ci-dessus
    bourses, formations = recommender.recommander_tout(test_user_id) 

    print("\n🏆 TOP BOURSES TROUVÉES :")
    print(bourses[['institution', 'domaine_principal', 'score_ia']])

    print("\n📚 FORMATIONS SUGGÉRÉES POUR VOTRE PROFIL :")
    print(formations[['titre', 'plateforme', 'score_formation']])