import pandas as pd #biblioteka za rad sa podacima #u biblioteci sklearn su implementirane klase i funkcije za istrazivanje podataka from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn.model_selection import train_test_split import sklearn.metrics as met #modul metrics sadrzi f-je za evaluaciju modela za klasifikaciju import subprocess def calculate_metrics(part, true_values, predicted_values, class_names): """ part: opis skupa true_values: prave klase instanci predicted_values: dodeljene klase instanci class_names: imena klasa (za pravljenje tabela radi lepseg prikaza rezultata) """ print('Skup ', part) print('Matrica konfuzije') cnf_matrix = met.confusion_matrix(true_values, predicted_values) df_cnf_matrix = pd.DataFrame(cnf_matrix, index=class_names, columns=class_names) print(df_cnf_matrix) print('\n') accuracy = met.accuracy_score(true_values, predicted_values) print('Preciznost', accuracy) print('\n') accuracy = met.accuracy_score(true_values, predicted_values, normalize=False) print('Preciznost u broju instanci', accuracy) print('\n') class_report = met.classification_report(true_values, predicted_values) print('Izvestaj klasifikacije', class_report, sep='\n') #f-ja za pravljenje slike drveta odlucivanja def visualize_tree(tree, feature_names, class_names): """ tree: objekat klase Tree feature_names: imena atributa koji su korisceni pri pravljenju modela class_names: vrednosti u ciljnom atributu """ with open("dt.dot", "w") as f: #f-ja export_graphviz opisuje drvo odlucivanja u dot formatu export_graphviz(tree, out_file=f, feature_names=feature_names, class_names=class_names, filled=True, rounded=True) f.close() #na osnovu opisa drveta odlucivanja u dot formatu pravi se slika u png formatu subprocess.call("dot -Tpng dt.dot -o tree.png", shell=True) #ucitavanje podataka iz datoteke u csv formatu i #pravljenje tabele, tj. objekta klase DataFrame df = pd.read_csv("iris.csv") #deo sa upoznavanjem i pripremom podataka print('Prvih 5 instanci iz skupa', df.head(), sep='\n') print('\n') print('Opis podataka (deskriptivne statistike)', df.describe(include='all'), sep='\n') print('\n') #provera da li postoje nedostajuce vrednosti u skupu, jer ako #postoje moraju biti obradjene print('Postojanje nedostajuce vrednosti', df.isna().any().any()) print('\n') #posto je korelacija izmedju Petal_Width i Petal_Length 0.96, #jedan od ova dva atributa se moze izostaviti pri pravljenju modela print('Korelacije izmedju atributa', df.corr(), sep='\n') print('\n') features = df.columns[:4].tolist() #ako se eliminise jedan atribut zbog korelacije, npr. Petal_Length #features.remove('Petal_Length') # deo sa klasifikacijom #Posto fja train_test_split kao prvi parametar prima opis instanci (bez ciljnog atributa), #a kao drugi parametar listu sa klasama instanci koje su zadate kao prvi argument, #ucitani skup se prema tim potrebama deli na dva dela print('Atributi za pravljenje modela', features) print('\n') x=df[features] #opis instanci (skup sadrzi samo atribute koji se koriste za pravljenje modela) y=df["Species"] #skup sa ciljnim atributom """ f-ja train_test_split kao rezultat vraca x_train: instance u trening skupu (bez ciljnog atributa) x_test: instance u test skupu (bez ciljnog atributa) y_train: klase instanci u trening skupu y_test: klase instanci u test skupu """ x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=100, stratify=y) #pravljenje klasifikatora koriscenjem klase DecisionTreeClassifier (u slajdovima je detaljnije opisana) dt = DecisionTreeClassifier() #dt = DecisionTreeClassifier(criterion='entropy') #dt = DecisionTreeClassifier(max_depth=2) #dt = DecisionTreeClassifier(min_samples_split=20, max_depth=4) #dt = DecisionTreeClassifier(min_samples_split=20, max_depth=4, max_leaf_nodes=4) #dt = DecisionTreeClassifier(min_impurity_split=0.05) #pravljenje modela na osnovu trening skupa dt.fit(x_train, y_train) print('Klase', dt.classes_) print('Znacajnost atributa', pd.Series(dt.feature_importances_, index=features), sep='\n') # pravljenje skupa koji sadrzi oznaku instance i # verovatnocu pripadnosti svakoj od klasa x_proba = pd.DataFrame(dt.predict_proba(x_test), index= x_test.index, columns=['prob_' + x for x in dt.classes_]) #spajanje skupa sa podacima o instancama i skupa sa verovatnocama, #spajanje se vrsi po oznakama redova x_test_proba = pd.concat([x_test, x_proba], axis=1) print('Verovatnoca pripadnosti svakoj od klasa za prvih 10 instanci trening skupa') print(x_test_proba.head(10)) #graficki prikaz drveta visualize_tree(dt, features, dt.classes_) #primena modela na trening podatke y_pred = dt.predict(x_train) calculate_metrics('Trening ',y_train, y_pred, dt.classes_ ) #primena modela na test podatke y_pred = dt.predict(x_test) calculate_metrics('Test',y_test, y_pred, dt.classes_ )