File size: 4,751 Bytes
bf5fb5f
 
 
 
 
 
 
 
43d4438
bf5fb5f
8ffb539
 
 
bf5fb5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43d4438
bf5fb5f
43d4438
bf5fb5f
1a758de
 
 
bf5fb5f
43d4438
bf5fb5f
 
 
 
 
 
1a758de
bf5fb5f
 
 
 
 
 
43d4438
bf5fb5f
1a758de
 
 
bf5fb5f
43d4438
bf5fb5f
 
 
 
43d4438
bf5fb5f
 
 
 
 
 
 
43d4438
bf5fb5f
 
1a758de
 
bf5fb5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# ===========================
# Fichier: cuml_trainer.py
# ===========================

from abc import ABC, abstractmethod
from typing import Union
import cupy as cp
from scipy.sparse import csr_matrix
import cudf

from config import Config
from base_trainer import BaseTrainer
from interfaces.vectorizer import Vectorizer


class CuMLTrainer(BaseTrainer, ABC):
    """
    Classe abstraite, héritée de BaseTrainer, représentant un entraîneur
    basé sur la librairie cuML. Elle ajoute notamment le concept de vectoriseur
    et force le passage de la matrice d'entrée en cupy.ndarray pour la plupart
    des opérations.

    Attributs:
        vectorizer (Vectorizer): Objet responsable de la vectorisation du texte.
    """

    def __init__(self, config: Config, data_path: str,
                 target_column: str) -> None:
        """
        Initialise un CuMLTrainer avec la configuration.
        Appelle également le constructeur de BaseTrainer.

        :param config: Configuration globale du système.
        :param data_path: Chemin vers le fichier de données.
        :param target_column: Nom de la colonne cible dans les données.
        """
        super().__init__(config, data_path, target_column)
        self.vectorizer: Vectorizer = None
        # self.classifier est déjà défini dans BaseTrainer.
        # On suppose que 'classifier' sera un modèle cuML (cuml.Base).

    @abstractmethod
    def build_components(self) -> None:
        """
        Méthode abstraite. Instancie concrètement le vectorizer et le classifieur,
        selon la configuration (ex. 'svm', 'random_forest', etc.).
        """
        pass

    def train(self) -> None:
        """
        Entraîne le classifieur sur les données vectorisées.
        Cette implémentation générique fonctionne pour tous les trainers cuML.
        """
        # Chargement des données

        data = cudf.read_csv(self.data_path)

        # Séparation des textes et des étiquettes
        # Supposons que la colonne de texte est la première colonne qui n'est pas la colonne cible
        text_column = [col for col in data.columns if col != self.target_column][0]
        texts = data[text_column]  # Extraire la série de texte
        labels = data[self.target_column].values

        # Vectorisation des textes
        X = self.vectorizer.fit_transform(texts)
        X_prepared = self._prepare_input_for_fit(X)
        # Entraînement du modèle
        self.classifier.fit(X_prepared, labels)

    def evaluate(self) -> dict:
        """
        Évalue le classifieur et calcule les métriques.
        Cette implémentation générique fonctionne pour tous les trainers cuML.
        """
        # Chargement des données (idéalement un jeu de test séparé)
        data = cudf.read_csv(self.data_path)

        # Séparation des textes et des étiquettes
        # Supposons que la colonne de texte est la première colonne qui n'est pas la colonne cible
        text_column = [col for col in data.columns if col != self.target_column][0]
        texts = data[text_column]  # Extraire la série de texte
        y_true = data[self.target_column].values

        # Vectorisation et prédiction
        X = self.vectorizer.transform(texts)
        X_prepared = self._prepare_input_for_predict(X)
        y_pred = self.classifier.predict(X_prepared)

        # Calcul et logging des métriques
        prefix = self.config.model.type.lower()
        metrics = self.metrics_calculator.calculate_and_log(
            y_true=y_true,
            y_pred=y_pred,
            prefix=prefix
        )

        # Afficher les résultats
        print(f"Métriques d'évaluation {prefix}: {metrics}")
        
        return metrics

    def _prepare_input_for_fit(self, X: Union[cp.ndarray,
                                              csr_matrix]) -> cp.ndarray:
        """
        Convertit, si nécessaire, la matrice en cupy.ndarray pour l'entraînement.

        :param X: Données d'entraînement (cupy.ndarray ou scipy.sparse.csr_matrix).
        :return: Données converties en cupy.ndarray, pour compatibilité cuML.
        """
        if isinstance(X, csr_matrix):
            return cp.asarray(X.toarray())
        return X  # c'est déjà cupy.ndarray

    def _prepare_input_for_predict(
            self, X: Union[cp.ndarray, csr_matrix]) -> cp.ndarray:
        """
        Convertit, si nécessaire, la matrice en cupy.ndarray pour la prédiction.

        :param X: Données de prédiction (cupy.ndarray ou scipy.sparse.csr_matrix).
        :return: Données converties en cupy.ndarray, pour compatibilité cuML.
        """
        if isinstance(X, csr_matrix):
            return cp.asarray(X.toarray())
        return X