-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprogram.py
More file actions
142 lines (101 loc) · 4.87 KB
/
program.py
File metadata and controls
142 lines (101 loc) · 4.87 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""
@author Alicia TCHEMO
@date 2025-03-20
Apprentissage Machine - M1 INFO DCI - Université Paris-Cité
Identification du noeud parent d'un arbre de décision selon du principe de minimisation de l'entropie
"""
import pandas as pd
import numpy as np
from math import log2
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier, export_text
import matplotlib.pyplot as plt
from scipy.stats import entropy
def entropy_calcul(probabilites: list) -> float:
"""
Calcule l'entropie selon des probabilités données, tel que l'entropie
E(X) = − ∑ pi x log2(pi)
:param probabilites: list(float) Liste de propabilités
:return: L'entropie calculé
"""
return -sum(p * log2(p) for p in probabilites if p > 0)
def findparentnode(file: str, raw: bool = True) -> str:
"""
Trouve le noeud parent d'un fichier donné.
:param file: Nom du fichier
:param raw: Indique si le chemin doit être retourné sous forme brute
:return: Nœud parent de l'arbre de décision déduit grace au fichier
"""
df = pd.read_csv(file, sep=' ')
classification = df.columns[-1]
eaps = []
if df[classification].dtype != 'int64':
# Numérisation de la colonne classification
d = {elem: index for index, elem in enumerate(pd.unique(df[classification]))}
df[classification] = df[classification].map(d)
# Boucle for sur toutes les colonnes (sauf celle de la classification)
for i in range(df.shape[1] - 1):
eap = []
colonne = df.columns[i]
# Numérisation de la colonne si nécessaire
if df[colonne].dtype != 'int64':
d = {elem: index for index, elem in enumerate(pd.unique(df[colonne]))}
df[colonne] = df[colonne].map(d)
df_colonne = df[[colonne, classification]]
denominateur = df[colonne].value_counts().sum() # N+P
df_count_classification = df_colonne.groupby(colonne).value_counts() # Ré-organisation de la table
for j in range(len(df[colonne].value_counts())):
numerateur = df_count_classification.loc[j].sum()
probabilites = list( float(elem / numerateur) for elem in df_count_classification.loc[j].tolist() )
entropie = None
if raw:
entropie = entropy_calcul(probabilites)
else:
entropie = entropy(probabilites)
eap.append(entropie * numerateur / denominateur)
eaps.append( (colonne, float(sum(eap))) )
# Résultat final
parentnode = sorted(eaps, key=lambda x: x[1])
print(f"Racine de l'arbre de décision {'choisit par le programme' if raw else 'sélectionné à l\'aide de `scipy`'} : {parentnode[0]}")
def decisiontree(file: str, plot: bool = False) -> None:
"""
Construit un arbre de décision à partir d'un fichier de données et l'affiche sous forme graphique ou textuelle.
:param file: Nom du fichier
:param plot: Si True, affiche l'arbre avec `matplotlib` ; sinon, affiche l'arbre sous forme textuelle.
"""
df = pd.read_csv(file, sep=' ')
# Numérisation de la colonne si nécessaire
for colonne in df.columns:
if df[colonne].dtype != 'int64':
d = {elem: index for index, elem in enumerate(pd.unique(df[colonne]))}
df[colonne] = df[colonne].map(d)
train = df.iloc[:]
# On sérpare la variables du résulats de la classification
features = df.columns[:-1]
classification = df.columns[-1]
X = train[features]
y = train[classification]
# On entraine le model pour la création de l'arbre de décision selon le principe de minimisation de l'entropie
dtree = DecisionTreeClassifier(criterion='entropy')
dtree = dtree.fit(X, y)
# Affichage de l'arbre créé
if plot:
plt.figure(figsize=(10,6))
tree.plot_tree(dtree, feature_names=features, filled=True, rounded=True, fontsize=10)
plt.show()
else:
tree_text = export_text(dtree, feature_names=list(X.columns))
print(f"Arbre de décision choisit par la librairie `sklearn` : \n{tree_text}")
# --- main --------------------------------------------------------------------
import argparse
if __name__ == "__main__":
# Gestion des parametres de l'invite de commande
parser = argparse.ArgumentParser(description="Gestion des paramètres")
parser.add_argument('--file', nargs='?', help="Fichier CSV en entrée", default='example.csv')
parser.add_argument('--plot', help="Affichage de l'arbre de décision avec `matplotlib`", default='no')
args = parser.parse_args()
file = args.file
display_tree = True if args.plot == 'yes' else False
findparentnode(file)
findparentnode(file, raw=False)
decisiontree(file, plot=display_tree)