def erreurs(taux_app, data, prof_max): erreurs_train = [] erreurs_test = [] x = [i for i in range(2, prof_max)] dataTrain, dataTest = partition(taux_app, data) train_x, train_y = x_y(dataTrain) test_x, test_y = x_y(dataTest) for i in range(2, prof_max): dt = DecisionTree() dt.max_depth = i dt.min_samples_split = 2 dt.fit(train_x, train_y) erreurs_train.append(1 - dt.score(train_x, train_y)) erreurs_test.append(1 - dt.score(test_x, test_y)) import matplotlib.pyplot as plt plt.figure() plt.plot(x, erreurs_train) plt.plot(x, erreurs_test) plt.ylabel('erreur en fonction de la profondeur, taux app : ' + str(taux_app)) plt.legend(['app', 'test'], loc='upper left') plt.savefig(str(taux_app) + "erreurs.png") plt.show()
def fit(self, X, y): self.tree = [] for _ in range(self.n_trees): tree = DecisionTree(min_samples_split=self.min_samples_split, max_depth=self.max_depth, n_features=self.n_feature) x_sample, y_sample = bootstrap_sample(X, y) tree.fit(x_sample, y_sample) self.trees.append(tree)
def predict(depth, x, y, x_test, y_test): dt = DecisionTree() dt.max_depth = depth # on fixe la taille de l ’ arbre a 5 dt.min_samples_split = 2 # nombre minimum d ’ exemples pour spliter un noeud dt.fit(x, y) dt.predict(x_test[:5, :]) score = dt.score(x_test, y_test) print(score) return (score)
def scoreTrainTest(f: float): assert (f > 0 and f <= 1) l = int(tot * f) scoresTrain = [] scoresTest = [] for depth in profondeurs: dt = DecisionTree(depth) dt.fit(datax[:l], datay[:l]) scoresTrain.append(dt.score(datax[:l], datay[:l])) scoresTest.append(dt.score(datax[l:], datay[l:])) return scoresTrain, scoresTest
def fit(self, datanum, ans): for _ in range(self.num_tree): x_train, _, y_train, _ = train_test_split(datanum, ans, test_size=1.0 - self.sample_data_rate) tree = DecisionTree(x_train, y_train, rand_features=self.sample_features) tree.fit() self.trees.append(tree)
def scoreTrain(): scores = [] for depth in profondeurs: dt = DecisionTree(depth) dt.fit(datax, datay) #dt.predict(datax [:5 ,:]) scores.append(dt.score(datax, datay)) # dessine l’arbre dans un fichier pdf si pydot est installe. #dt.to_pdf("/tmp/test_tree.pdf",fields) # sinon utiliser http :// www.webgraphviz.com/ #print(dt.to_dot(fields)) #ou dans la console #print(dt.print_tree(fields )) return scores
def scores_selon_prof(taux_app, data, prof_max): scores = [] x = [i for i in range(2, prof_max)] dataTrain, dataTest = partition(taux_app, data) train_x, train_y = x_y(dataTrain) test_x, test_y = x_y(dataTest) for i in range(2, prof_max): dt = DecisionTree() dt.max_depth = i dt.min_samples_split = 2 dt.fit(train_x, train_y) scores.append(dt.score(test_x, test_y)) import matplotlib.pyplot as plt plt.plot(x, scores) plt.ylabel('score en fonction de la profondeur, taux app : ' + str(taux_app)) plt.savefig(str(taux_app) + "scores.png") plt.show()
def fit(self, X, y): """Build multiple trees based on training data. Args: X (numpy array): sample in shape [n x d], where n is number of samples and d is number of features. y (numpy array): sample labels in shape [n]. """ n, d = X.shape for i in range(self.tree_num): # draws random subset of features features = np.random.choice(d, self.fc, replace=False) tree = DecisionTree(self.max_depth, self.min_improv, self.eval_func) samples = np.random.choice(n, n, replace=True) X_train = X[:, features][samples, ] y_train = y[samples] tree.fit(X_train, y_train) self.features[i] = features self.trees[i] = tree
def scoreCross(n=5): """fait la moyenne sur n tests taille test = tot/n""" assert (type(n) == int) scoresTrain = [] scoresTest = [] for depth in profondeurs: sTrain = 0 sTest = 0 for i in range(n): start = tot * i // n end = tot * (i + 1) // n dt = DecisionTree(depth) xtrain = np.vstack((datax[:start], datax[end:])) ytrain = np.hstack((datay[:start], datay[end:])) dt.fit(xtrain, ytrain) sTrain += dt.score(xtrain, ytrain) sTest += dt.score(datax[start:end], datay[start:end]) scoresTrain.append(sTrain / n) scoresTest.append(sTest / n) return scoresTrain, scoresTest
def partitionnement_test(datax,datay,rp,rdm,couleur): #rp la proportion qui sera dans l'apprentissage. #rdm un booléen qui détermine si on partitionne nos ensemble au hasard. dt = DecisionTree() dt.min_samples_split = 2 if rdm: rp = random.uniform(0,1) #inceap nos indices dans datax qui vont servir pour notre apprentissage, et indicet pour nos test. #On tire indiceap aléatoirement avec la proportion rp dans datax, et on effectue des tirages sans remise. indiceap = np.random.choice(np.arange(len(datax)), int(rp*len(datax)), replace = False) indicet = [] for i in range(0,len(datax)): if i not in indiceap: indicet.append(i) testy = np.zeros((len(indicet)), int) apprentissagey = np.zeros((len(indiceap)),int) testx = np.delete(datax,indiceap,axis=0) apprentissagex = np.delete(datax,indicet,axis=0) for i in range(0,len(indiceap)): apprentissagey[i] = datay[indiceap[i]] for i in range(0,len(indicet)): testy[i] = datay[indicet[i]] l_scoretest = [] l_scoreapprentissage = [] #On test différentes profondeurs d'arbres avec comme pas de 3 pour éviter un trop long temps de calcul. for i in range(2,20,3): dt.max_depth = i dt.fit(apprentissagex ,apprentissagey) dt.predict(apprentissagex[:5 ,:]) l_scoretest.append(1 - dt.score(testx,testy)) l_scoreapprentissage.append(1 - dt.score(apprentissagex,apprentissagey)) plt.plot(range(2,20,3),l_scoretest,couleur+'--',range(2,20,3),l_scoreapprentissage,couleur) plt.show()
def partitionnement_test(datax, datay, rp, rdm): #rp la proportion qui sera dans le test. dt = DecisionTree() dt.min_samples_split = 2 if rdm: rp = random.uniform(0, 1) indiceap = np.random.choice(np.arange(len(datax)), int(rp * len(datax)), replace=False) indicet = [] for i in range(0, len(datax)): if i not in indiceap: indicet.append(i) testy = np.zeros((len(indicet)), int) apprentissagey = np.zeros((len(indiceap)), int) testx = np.delete(datax, indiceap, axis=0) apprentissagex = np.delete(datax, indicet, axis=0) for i in range(0, len(indiceap)): apprentissagey[i] = datay[indiceap[i]] for i in range(0, len(indicet)): testy[i] = datay[indicet[i]] l_scoretest = [] l_scoreapprentissage = [] for i in range(2, 20, 3): dt.max_depth = i dt.fit(apprentissagex, apprentissagey) dt.predict(apprentissagex[:5, :]) l_scoretest.append(1 - dt.score(testx, testy)) l_scoreapprentissage.append(1 - dt.score(apprentissagex, apprentissagey)) plt.plot(range(2, 20, 3), l_scoretest, 'r--', range(2, 20, 3), l_scoreapprentissage, 'b--') plt.show() plt.close()
def validation_croisee(n, taux_app, data, prof_max): data_app, _ = partition(taux_app, data) erreurs_moy_app = [] borders = np.linspace(0, len(data_app), n + 1, dtype=int) for depth in range(1, prof_max): print(depth) erreurs_test = [] for i in range(n): data_test = data_app[borders[i]:borders[i + 1]] if len(data_app[0:borders[i]]) > 0: data_train = np.concatenate( (data_app[0:borders[i]], data_app[borders[i + 1]:len(data_app)])) else: data_train = data_app[borders[i + 1]:len(data_app)] train_x, train_y = x_y(data_train) test_x, test_y = x_y(data_test) dt = DecisionTree() dt.max_depth = depth dt.min_samples_split = 2 dt.fit(train_x, train_y) erreurs_test.append(1 - dt.score(test_x, test_y)) print(erreurs_moy_app) erreurs_moy_app.append((1 / n) * np.array(erreurs_test).sum()) x = [i for i in range(1, prof_max)] fig = plt.figure() plt.plot(x, erreurs_moy_app) plt.xlabel( 'Erreur moyenne en fonction de la prof avec VC avec taux app de : ' + str(taux_app)) plt.legend(['app'], loc='upper left') plt.savefig(str(taux_app) + "erreursVC.png") #plt.show() return
def apprentissage(datax, datay, prop): ax = datax[:int(np.floor(prop * len(datax)))] # donnee apprentissage ay = datay[:int(np.floor(prop * len(datax)))] tx = datax[int(np.floor(prop * len(datax))):] # donnee test ty = datay[int(np.floor(prop * len(datax))):] ascore = np.zeros(9) tscore = np.zeros(9) for d in range(1, 28, 3): print("apprentissage : prop = " + str(prop) + " depth = " + str(d)) dt = DecisionTree() dt.max_depth = d # on fixe la taille de l ’ arbre a 5 dt.min_samples_split = 2 # nombre minimum d ’ exemples pour spliter un noeud dt.fit(ax, ay) ascore[int(np.floor(d / 3))] = 1 - dt.score(ax, ay) tscore[int(np.floor(d / 3))] = 1 - dt.score(tx, ty) plt.plot(range(1, 28, 3), ascore) plt.plot(range(1, 28, 3), tscore) plt.legend(["Apprentissage", "Test"]) plt.title("Proportion : " + str(prop)) plt.show()
import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split from decisiontree import DecisionTree def accuracy(y_true, y_pred): accuracy = np.sum(y_true == y_pred) / len(y_true) return accuracy data = datasets.load_breast_cancer() X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234) clf = DecisionTree(max_depth=10) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) acc = accuracy(y_test, y_pred) print("Accuracy", acc)
np.around(max(igain), decimals=4)) # => 0.0607 #/////////////////////////////////////////////////////////////////////////////////////////////////// </prise en main IMDb> //// #///////////////////////////////////////////////////////////////////////////////////////////// <expériences préliminaires> //// # ··· L'objet DecisionTree est déjà implémenté dans le code source fourni. dt = DecisionTree() # Taille de l'arbre de décision. dt.max_depth = 5 # Nombre minimum d'exemples pour diviser un noeud. dt.min_samples_split = 2 # Apprentissage et prédiction. dt.fit(datax, datay) dt.predict(datax[:5, :]) print('Depth: {} - Score: {}'.format(dt.max_depth, dt.score(datax, datay))) # Dessiner l’arbre dans un fichier pdf si pydot est installé. # filename = 'imdb_tree_d{}_s{}.pdf'.format(dt.max_depth, dt.min_samples_split) # dt.to_pdf(filename, fields) # Si pydot n'est pas installé, utiliser http://www.webgraphviz.com/, # print(dt.to_dot(fields)) # ou dans la console, même si moyennement lisible print(dt.print_tree(fields)) #//////////////////////////////////////////////////////////////////////////////////////////// </expériences préliminaires> //// #//////////////////////////////////////////////////////////////////////////////////////////// <arbres et surapprentissage> ////
# Valeur de 0 : Le vecteur est homogène # Valeur de 1 : Le vecteur possède autant de 1 que de 0 # Le meilleur attribut pour la première partition est celui qui apporte plus plus d'informations, donc celui dont la différence d'entropie est la plus grande # Q 1.4 # PDF des graphes joints à ce fichier # On sépare beaucoup d'éléments avec les premières séparations et plus on descent, plus le nombre d'exemples devient petit # On filtre au fur et à mesure, c'est donc normal # Mettre True pour Quelques expériences préliminaires if True: dt = DecisionTree() dt.max_depth = 1 # on fixe la taille de l ’ arbre a 5 dt.min_samples_split = 2 # nombre minimum d ’ exemples pour spliter un noeud dt.fit(datax, datay) dt.predict(datax[:5, :]) print(dt.score(datax, datay)) # dessine l ’ arbre dans un fichier pdf si pydot est installe . dt.to_pdf("/tmp/test_tree.pdf", fields) # sinon utiliser http :// www . webgraphviz . com / # dt.to_dot(fields) # ou dans la console # print(dt.print_tree(fields)) # Q 1.5 # Profondeur 1 : 0.64 # Profondeur 3 : 0.72 # Profondeur 5 : 0.74
from decisiontree import DecisionTree import matplotlib.pyplot as plt def accuracy(y_true, y_pred): accuracy = np.sum(y_true == y_pred) / len(y_true) return accuracy data = datasets.load_breast_cancer() X = data.data y = data.target print(X.shape) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) accuracies = [] for depth in range(1, 31): tree = DecisionTree(max_depth=depth) tree.fit(X_train, y_train) y_pred = tree.predict(X_test) acc = accuracy(y_test, y_pred) accuracies.append(acc) print(f"Accuracy for depth {depth} : {acc:.2f}") plt.figure() plt.plot(range(1, 31), accuracies) plt.xlabel('Max Depth of Tree') plt.ylabel('Accuracy') plt.title('Performance of Decision Tree on Breast Cancer dataset') plt.savefig('dt_bc.png') plt.show()
foldsx = [] foldsy = [] for i in range(nb_folds): x = [] y = [] for j in range(i * size, (i + 1) * size): x.append(datax[j]) y.append(datay[j]) foldsx.append(np.array(x)) foldsy.append(np.array(y)) error_it = [] for i in range(nb_folds): testx = foldsx[i] testy = foldsy[i] tx = [] ty = [] for j in range(nb_folds): if (j != i): tx.append(foldsx[j]) ty.append(foldsy[j]) trainx = np.concatenate(tx, axis=0) trainy = np.concatenate(ty, axis=0) dt = DecisionTree() dt.max_depth = 4 dt.min_samples_split = 2 dt.fit(trainx, trainy) error_it.append(dt.score(testx, testy)) error_moy = sum(error_it) / nb_folds print(error_it) print(error_moy)
# On remarque qu'une valeur 0 de l'entropie correspond au cas où il n'y a pas des aspects aléatoires tandis qu'une # valeur 1 correspond bien au désordre le plus grand (lorsqu'on a une variable binaire et lorsqu'on prend le log # de base 2) # Alors, pour le gain d'information des valeurs plus hauts correspondent au cas où le désordre pour des valeurs # de l'attribut est plus grand alors que le désordre pour y est minimal. Et cela c'est ce qu'on cherche : un # attribut dont les valeurs sont les plus " équilibrées " mais qui produisent les étiquettes les plus " claires " sim_num = 5 depths = [5, 10, 15, 20, 25] scores = np.zeros(sim_num) split = 2 for sim in range(sim_num): dt = DecisionTree() dt.max_depth = depths[sim] # dt.min_samples_split = split # nombre minimum d ’ exemples pour spliter un noeud dt.fit(datax, datay) print(dt.score(datax, datay)) # dessine l ’ arbre dans un fichier pdf si pydot est installe . dt.to_pdf("test_tree_%d.pdf" % sim, fields) # sinon utiliser http :// www . webgraphviz . com / # dt.to_dot(fields) # ou dans la console # print(dt.print_tree(fields)) print('Score de classification : %f' % dt.score(datax, datay)) scores[sim] = dt.score(datax, datay) # Q 1.4 des arbres construits sont donnés dans les fichiers " test_tree_%d " où d se varie dans {0, ..., 4} ; # ces arbres correspondent aux profondeurs différentes indiquées au-dessus # On remarque qu'en fonction de profondeur on sépare de plus en plus exemples lorsque on l'augmente ; # Généralement, ce comportement semble normal car à chaque fois qu'on va plus loin dans un arbre, on sépare certains