From e618ecbf4213c317c4c1f6ab600e76443315d4a9 Mon Sep 17 00:00:00 2001 From: Marta Roszak Date: Sun, 10 May 2020 19:02:43 +0200 Subject: [PATCH] =?UTF-8?q?jednak=20teraz=20raport=20bo=20zapomnia=C5=82a,?= =?UTF-8?q?=20=C5=BCe=20by=C5=82=20w=20innym=20folderze?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- niestrawność_potraw_Marta_Roszak.md | 129 ++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 niestrawność_potraw_Marta_Roszak.md diff --git a/niestrawność_potraw_Marta_Roszak.md b/niestrawność_potraw_Marta_Roszak.md new file mode 100644 index 0000000..1ec0dba --- /dev/null +++ b/niestrawność_potraw_Marta_Roszak.md @@ -0,0 +1,129 @@ +##### Raport przygotowała: Marta Roszak + +##### Raportowany okres: 4 maja - 10 maja 2020 + +##### Niniejszy raport poświęcony jest przekazaniu informacji na temat stanu mini-projektu indywidualnego w ramach projektu grupowego realizowanego na przedmiot Sztuczna Inteligencja w roku akademickim 2019/2020. + +Tematem realizowanego projektu indywidualnego jest stworzenie sztucznej inteligencji rozpoznającej z podanych parametrów czy danie jest ciężkostrawne czy nie. Do tego celu wykorzystane zostało drzewo decyzyjne oraz biblioteki: + +- scikit - learn +- pydotplus +- joblib +- IPython +- pandas + +## Uczenie modelu ## + +#### Dane wejściowe: #### + +Do utworzenia modelu przygotowałam zestaw danych składający się z 60 krotek, każda składająca się z 6 liczb oznaczających odpowiednio: + +- wiek osoby zamawiającej danie (z przedziału 10 do 60); +- zawartość tłuszczu w daniu (z przedziału 0 do 16); +- zawartość błonnika w daniu (z przedziału 0 do 16); +- płeć osoby zamawiającej (0 - mężczyzna lub 1 - kobieta); +- wskazanie czy danie jest ostre czy nie (0 - nieostre lub 1 - ostre); +- wskazanie czy danie jest ciężkostrawne czy nie (0 - nie lub 1 - tak); + +Liczby oddzielone są przecinkami i zapisane w pliku z rozszerzeniem .csv. + +#### Proces uczenia: #### + +Na początku dane są importowane do programu: + +```python +def dataImport(): + dataset = pd.read_csv('learnData4.csv', sep=',', header=None) + return dataset +``` + +Następnie dane są dzielone odpowiednio na zestaw cech (*X*) i zestaw klas - "wyników" (*Y*). Zbiory te są jeszcze, przy pomocy funkcji **train_test_split** (z biblioteki scikit - learn) dodatkowo dzielone na zestawy do uczenia i zestawy do testowania (*x_train*, *x_test*, *y_train*, *y_test*): + +```python +def splitDataSet(dataset): + X = dataset.values[:, 0:5] + Y = dataset.values[:, 5] + x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=100) + return X, Y, x_train, x_test, y_train, y_test +``` + +Zbiór danych testowych składa się z 0.3 krotek zestawu początkowego. + +Korzystając z funkcji **DecisionTreeClassifier** utworzony zostaje model w postaci drzewa, do którego następnie zostają załadowane uprzednio przygotowane zbiory danych: + +```python +model = tree.DecisionTreeClassifier() +model2 = tree.DecisionTreeClassifier(criterion="entropy") + +model.fit(x_train, y_train) +model2.fit(x_train, y_train) +``` + +Funkcja **DecisionTreeClassifier** domyślnie wykorzystuje indeks Gini jako kryterium podziału. Ja jednakże, wygenerowałam dodatkowo model, gdzie jako kryterium podziału została przyjęta entropia. + +Następnie modele zostają poddane testowi i obliczony zostaje wskaźnik trafności wygenerowanych, na zbiorze testowym, wyników: + +```python +pred = model.predict(x_test) +pred2 = model2.predict(x_test) + +acc = accuracy_score(y_test, pred) * 100 +acc2 = accuracy_score(y_test, pred2) * 100 + +print("akuratnosc dla modelu Gini: " + str(acc)) # aprox. 77.78% +print("akuratnosc dla modelu Entropy: " + str(acc2)) # aprox. 83.33% +``` + +#### Operacje na wygenerowanym modelu: #### + +W tym przypadku, model z entropią daje nam większą trafność. Zatem to on zostanie wykorzystany w głównym programie. Model drzewa zostaje zapisany w pliku .sav: + +```python +filename = 'finalized_model.sav' +joblib.dump(model2, filename) +``` + +Dodatkowo zostaje wygenerowane (przy pomocy biblioteki Graphviz i IPython) graficzne przedstawienie drzewa i zapisane w pliku .png: + +```python +dot_data2 = tree.export_graphviz(model2, out_file=None, feature_names=["age", "fat", "fiber", "sex", "spicy"], class_names=["easty to digest", "hard to digest"], filled=True, rounded=True, special_characters=True) + +graph2 pydotplus.graph_from_dot_data(dot_data2) +Image(graph2.create_png()) +graph2.write_png("digest_entropy.png") +``` + + + +## Integracja z projektem ## + +Po uruchomieniu programu i wybraniu na ekranie głównym opcji *Ciężkostrawność dań*, uruchomiona zostaje funkcja *Evaluate()*, która ładuje z pliku model drzewa. Zainicjowany zostaje również przykładowy stan restauracji (dodanie kilku klientów, przypisanie im stołów i talerzy). Wywoływany jest też przykładowy ruch kelnera, który podchodzi do kilku stolików i pomaga w ocenie strawności dania, przy pomocy funkcji *predictDigest()*: + +```python +def predictDigest(dish, client, model): + data = [] + data.append(client.age) + data.append(dish.fatContent) + data.append(dish.fiberContent) + data.append(client.sex) + data.append(dish.spicy) + prediction = model.predict([data]) + if prediction == 1: + messagebox.showinfo("opinia", "Z tym może być ciężko. " + str(data)) + return prediction + else: + messagebox.showinfo("opinia", "Z tym nie będzie tak źle! " + str(data)) + return prediction +``` + +Funkcja jako parametry przyjmuje obiekty danie, klient i załadowany model. Parametry potrzebne modelowi do wyznaczenia wyniku pobierane są z odpowiednich obiektów i jako tablica przekazywane do funkcji *predict()*. Następnie, w zależności od otrzymanego wyniku wyświetlany jest odpowiedni komunikat i dane jakie podlegały ocenie. + +Pola *fatContent*, *fiberContent*, *spicy* klasy *Dish* w momencie tworzenia instancji klasy są ustawiane na losowo wygenerowaną liczbę z odpowiednich przedziałów: + +```python +self.fatContent = random.randint(0, 16) +self.fiberContent = random.randint(0, 16) +self.spicy = random.randint(0, 1) +``` + +Po zakończeniu trasy wyświetlany jest stosowny komunikat, a aplikacja zostaje wyłączona. \ No newline at end of file