diff --git a/RaportSzymonParafiński.md b/RaportSzymonParafiński.md index 2e65efe..e488445 100644 --- a/RaportSzymonParafiński.md +++ b/RaportSzymonParafiński.md @@ -1 +1,187 @@ -a \ No newline at end of file +# Podprojekt indywidualny - Szymon Parafiński +--- +W folderze Sklearn znajduje się wykorzystana baza, wygenerowane drzewo oraz reszta plików związana z podprojektem. + +## Wykorzystana metoda uczenia + +Do realizacji podprojektu wykorzystano drzewa decyzyjne do decydowania, co należy zrobić po najechaniu na konkretne pole. +Drzewo decyduje na jakim etapie jest roślina analizując poszczególne stany danego pola: +- Dopiero co zasiana (kiełek) + - 0: "Nie_podejmuj_działania" +- Roślinka kiełkująca (młoda) + - 1: "Zastosuj_nawóz" +- Roślina starzejąca się, bez środka ochrony + - 2: "Zastosuj_środek" +- Roślinka dojrzałam gotowa do zbioru + - 4: "Zbierz" +- Roślina zepsuta, nie nadaje się do użytku + - 5: "Roślina_już_zgniła-zbierz_i_wyrzuć". + + Do implementacji drzew decyzyjnych w Pythonie wykorzystane zostały biblioteki + **sklearn** , **pandas**,**sys** oraz **pickle**. + +## Uczenie modelu + +#### loadLearningBase(): [python] +Metoda **loadLearningBase** rozpoczyna od utworzenia zbioru uczącego na podstawie tabeli zawierającej informacje wszystkich możliwych stanach roślinki. + +* *col_names* -> zawiera nagłówki poszczególnych kolumn +* *feature_cols* -> zawiera nagłówki z kolumnami w których znajdują się dane do analizy +``` + col_names = ['Warzywo', 'Nawoz', 'Srodek', 'Stan', 'Dzialanie'] + base = pd.read_csv("Database.csv", header=None, names=col_names) + feature_cols = ['Warzywo', 'Nawoz', 'Srodek', 'Stan'] + """ print dataset""" + # print(base.head()) +``` + Tutaj dzielimy podane kolumny na dwa typy zmiennych: +* zmienne docelowe ---> y +* i zmienne funkcyjne ---> X + +Aby móc sprawdzić wydajność modelu, dzielę zestaw danych na zestaw szkoleniowy i zestaw testowy ---> za pomocą funkcji train_test_split (). + +``` + X = base[feature_cols] # Features + y = base.Dzialanie # Target variable + + # Split dataset into training set and test set + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, + random_state=1) # 70% training and 30% test +``` +Wywołanie funkcji odpowiedzialnej za wygenerowanie drzewa. +``` + data = generateDecisionTree(X_train, X_test, y_train, y_test) +``` +Dodatkowe elementy pozwalające na wizualizację stworzonego drzewa decyzyjnego poprzez wygenerowanie drzewa zależności if/else lub najpierw do pliku .dot, który następnie poddany odpowiedniej 'obróbce' utworzy obraz. +``` + """generate data for image""" + # tree.export_graphviz(data, out_file='treeData.dot', filled=True, rounded=True, special_characters=True, + # feature_names=feature_cols) + + """Printing if_styled tree to console""" + # tree_to_code(data, feature_cols) + + return data +``` +--- +#### generateDecisionTree(): [python] +Metoda **generateDecisionTree** generuje drzewo decyzyjne na podstawie dostarczonej bazy danych. + +Do zmiennej *clf* zapisujemy drzewo decyzyjne z biblioteki **sklearn** utworzone za pomocą metody **DecisionTreeClassifier** z parametrem **criterion** ustawionym na **"entropy"**, który pozwala na uzyskiwanie informacji. +Na drzewie wywołujemy metodę **fit**, która dopasowuje do drzewa zbiór uczący zadany w tablicach **X_train** i **y_train**. +Po dopasowaniu danych możemy przewidzieć stan nowych przykładów, co robimy wywołując na drzewie metodę **predict** z parametrami, które zawierają informację o stanie danego pola. +``` +def generateDecisionTree(X_train, X_test, y_train, y_test): + # Create Decision Tree classifer object + clf = DecisionTreeClassifier(criterion="entropy") + + # Train Decision Tree Classifer + clf = clf.fit(X_train, y_train) +``` +Aby ocenić dokładność naszego modelu przewidujemy odpowiedzi dla naszego zestawu testowego, aby móc go porównać z zestawem y_test i otrzymać dokładność wygenerowanego modelu. +``` + # Predict the response for test dataset + y_pred = clf.predict(X_test) + + """Model Accuracy, how often is the classifier correct """ + # print("Accuracy:", metrics.accuracy_score(y_test, y_pred)) +``` +--- +#### main(): [python] +Metoda main wywołuje pozostałe metody oraz zapisuje wygenerowany model do pliku .sav aby nie było trzeba ponownie generować drzewa, tylko wczytać już te wygenerowane. +``` +generated = loadLearningBase() + + # Save generated tree + filename = 'decisionTree.sav' + pickle.dump(generated, open(filename, 'wb')) +``` + +## Implementacja w projekcie całościowym + +Klasa wywoływana w **C++** nazywa się *injectCode*. +Działanie polega na tym że, funkcja **stanPola** sprawdza jakie wartości ma dane pole i generuje odpowiednie polecenie do wykonania. +#### stanPola(): [C++] + +``` +void stanPola(int x, int y) { + //[x][x][0] = 0 - brak chemii + //[x][x][0] = 1 - tylko nawóz + //[x][x][0] = 2 - tylko środek + //[x][x][0] = 3 - środek i nawóz + //[x][x][1] - wartość wzrostu rośliny + + if (stan[x][y][0] == 0) + polecenie.append("0 0 "); + if (stan[x][y][0] == 1) + polecenie.append("1 0 "); + if (stan[x][y][0] == 2) + polecenie.append("0 1 "); + if (stan[x][y][0] == 3) + polecenie.append("1 1 "); + int w = (stan[x][y][1]); + std::string s = std::to_string(w); + polecenie.append(s); +} +``` + +Następnie funckja **decisionTree** wykonuje wygenerowane zapytanie. +#### decisionTree(): [C++] + +``` +void decisionTree(string polecenie) { + + std::string str = polecenie; + const char* c = str.c_str(); + system(c); +} +``` +#### injectCode(): [python] + +``` +import pickle +import sys + + +def prediction(warzywo, nawoz ,srodek, stan_wzrostu): + filename = 'decisionTree.sav' + tree = pickle.load(open(filename, 'rb')) + val = (tree.predict([[warzywo, nawoz, srodek, stan_wzrostu]])) + print(decision(val)) + +def decision(prediction): + if prediction == 0: + return "Nie_podejmuj_dzialania" + elif prediction == 1: + return "Zastosuj_nawoz" + elif prediction == 2: + return "Zastosuj_srodek" + elif prediction == 4: + return "Zbierz" + elif prediction == 5: + return "Roslina_juz_zgnila__zbierz_i_wyrzuc" + + + +if __name__ == '__main__': + # Map command line arguments to function arguments. + prediction(*sys.argv[1:]) +``` +Generowane polecenie wygląda w ten sposób: +``` +python injectCode.py a b c d +``` +Gdzie: +* a -> rodzaj warzywa + * 1: "burak" +* b -> czy roślina była nawożona + * 0: "nie" + * 1: "tak" +* c -> czy na roślinie był stosowany środek ochronny + * 0: "nie" + * 1: "tak" +* d -> stan wzrostu w jakim znajduje się roślina + * [1,20) - kiełek, + * [20,45) - młoda roślina, + * [45,85) - dojrzała, + * [80,100] - starzejąca się. \ No newline at end of file