kdd-lab / LORE_sa

Code for LORE (stable and actionable)
3 stars 1 forks source link

dataset: costruttore #2

Closed mesosbrodleto closed 1 year ago

mesosbrodleto commented 1 year ago

[stiamo usando le issue anche internamente per lavorare meglio in asincrono]

Il costruttore del dataset dovrebbe richiedere in input anche tutte i parametri necessari per descrivere il dataset, e funzionali per gli step successivi del processo di LORE.

Alcuni dei parametri attuali sono invece eliminabili.


    def __init__(self,data: DataFrame):
        self.class_name = None #necessario
        self.df = data
        self.feature_names = None #necessario
        self.class_values = None #necessario
        self.numeric_columns = None #necessario
        self.real_feature_names = None #impostato poi da prepare_dataset
        self.features_map = None #impostato poi da prepare_dataset
        self.rdf = None #impostato poi da prepare_dataset
        self.filename = None #eliminato
LoSpino87 commented 1 year ago

Potremmo mantenere il metodo prepare_dataset() dandgli come argomenti tutti gli input funzionali necessari ai passi successivi, però incapsulando il tutto nella classe.

rinziv commented 1 year ago

Per la creazione automatica del descrittore, mi immagino una cosa del genere:

    def create_data_descriptor(self):
        """
        Analyzes the content of the data and automatically creates a dictionary with the description of the attributes
        of the dataset. For each attribute, the following information is provided, depending on the type of the attribute:
        - numeric: min, max, mean, std, median, 1st quartile, 3rd quartile
        - categorical: number of distinct values, probability of each value
        - ordinal: number of distinct values, probability of each value, as a sequence following the natural order of the values

        :return: a dictionary with the description of the dataset
        """

        data_descriptor = dict()
        data_descriptor["class_name"] = self.class_name
        data_descriptor["numeric_columns"] = self.get_numeric_columns()
        data_descriptor["categorical_columns"] = [c for c in self.df.columns if c not in self.get_numeric_columns()]
        data_descriptor["features"] = dict()
        for f in self.df.columns:
            if f == self.class_name:
                continue
            data_descriptor["features"][f] = dict()
            if f in data_descriptor["numeric_columns"]:
                data_descriptor["features"][f]["type"] = "numeric"
                data_descriptor["features"][f]["min"] = self.df[f].min()
                data_descriptor["features"][f]["max"] = self.df[f].max()
                data_descriptor["features"][f]["mean"] = self.df[f].mean()
                data_descriptor["features"][f]["std"] = self.df[f].std()
                data_descriptor["features"][f]["median"] = self.df[f].median()
                data_descriptor["features"][f]["q1"] = self.df[f].quantile(0.25)
                data_descriptor["features"][f]["q3"] = self.df[f].quantile(0.75)
            else:
                data_descriptor["features"][f]["type"] = "categorical"
                data_descriptor["features"][f]["distinct_values"] = self.df[f].nunique()
                data_descriptor["features"][f]["value_counts"] = self.df[f].value_counts()
                data_descriptor["features"][f]["value_counts_norm"] = self.df[f].value_counts(normalize=True)
                data_descriptor["features"][f]["value_counts_norm_cumsum"] = self.df[f].value_counts(normalize=True).cumsum()
                data_descriptor["features"][f]["value_counts_norm_cumsum_inv"] = self.df[f].value_counts(normalize=True).cumsum().apply(lambda x: 1-x)
        return data_descriptor

Forse molte più informazioni di quelle richieste.... Potremmo anche aggiungere una proprietà per il tipo di file

mesosbrodleto commented 1 year ago

eliminerei i vari "value_counts" dalle feature categoriche: i valori per ogni chiave sono dei dataframe o series, quindi poco maneggevoli per chi dovesse creare un suo personale data descriptor. Lo sostituirei con un semplice dizionerio {'value':count}, così da avere la distribuzione dei valori delle varie features