commit_natalia2
This commit is contained in:
parent
260ce4fe62
commit
3c8c663597
@ -5,7 +5,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/Restaurant/Marta/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/Restaurant/Marta/venv" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.7 (projekt_sztuczna)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestRunnerService">
|
<component name="TestRunnerService">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (projekt_sztuczna)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
@ -25,7 +25,7 @@ def main():
|
|||||||
X = model_tree[feature_cols]
|
X = model_tree[feature_cols]
|
||||||
#separacja danych etykieta
|
#separacja danych etykieta
|
||||||
y = model_tree.number
|
y = model_tree.number
|
||||||
# Target variable
|
|
||||||
|
|
||||||
#podział danych na zestaw treningowy i testowy; 70% trening 30% test
|
#podział danych na zestaw treningowy i testowy; 70% trening 30% test
|
||||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
|
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
|
||||||
|
@ -437,6 +437,41 @@ def predictDigest(dish, client, model):
|
|||||||
messagebox.showinfo("opinia", "Z tym nie będzie tak źle! " + str(data))
|
messagebox.showinfo("opinia", "Z tym nie będzie tak źle! " + str(data))
|
||||||
return prediction
|
return prediction
|
||||||
|
|
||||||
|
def ShowImg(file):
|
||||||
|
zdjęcie = Image.open(file)
|
||||||
|
zdjęcie.show()
|
||||||
|
|
||||||
|
def show_predict(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:
|
||||||
|
ShowImg("Natalia/danie1.png")
|
||||||
|
return prediction
|
||||||
|
elif prediction == 2:
|
||||||
|
ShowImg("Natalia/danie2.png")
|
||||||
|
return prediction
|
||||||
|
elif prediction == 3:
|
||||||
|
ShowImg("Natalia/danie3.png")
|
||||||
|
return prediction
|
||||||
|
elif prediction == 4:
|
||||||
|
ShowImg("Natalia/danie4.png")
|
||||||
|
return prediction
|
||||||
|
elif prediction == 5:
|
||||||
|
ShowImg("Natalia/danie5.png")
|
||||||
|
return prediction
|
||||||
|
elif prediction == 6:
|
||||||
|
ShowImg("Natalia/danie6.png")
|
||||||
|
return prediction
|
||||||
|
else:
|
||||||
|
ShowImg("Natalia/danie7.png")
|
||||||
|
return prediction
|
||||||
|
|
||||||
|
|
||||||
def evaluate(b):
|
def evaluate(b):
|
||||||
@ -564,6 +599,43 @@ def payment(c):
|
|||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def Tree_natalia(d):
|
||||||
|
if d == 1:
|
||||||
|
loaded_model = joblib.load('Natalia/final_model.sav')
|
||||||
|
messagebox.showinfo("Zaczynamy!", "Zaczynamy!")
|
||||||
|
|
||||||
|
prefer1 = Dish("prefer1", 40, 20, 15)
|
||||||
|
prefer2 = Dish("prefer2", 25, 10, 10)
|
||||||
|
prefer3 = Dish("prefer3", 55, 25, 28)
|
||||||
|
|
||||||
|
plate1 = Plate(prefer1, "Natalia/danie1.png")
|
||||||
|
plate2 = Plate(prefer2, "Natalia/danie2.png")
|
||||||
|
plate3 = Plate(prefer3, "Natalia/danie3.png")
|
||||||
|
|
||||||
|
client1 = Client(25, 1, 45, 1)
|
||||||
|
client2 = Client(41, 0, 22, 4)
|
||||||
|
client3 = Client(10, 0, 32, 8)
|
||||||
|
|
||||||
|
client1.takePlateAndEat(plate1)
|
||||||
|
client2.takePlateAndEat(plate2)
|
||||||
|
client3.takePlateAndEat(plate3)
|
||||||
|
|
||||||
|
bot.goByAStar((tables[1].pos[0] + 1, tables[1].pos[1]))
|
||||||
|
opinion = show_predict(prefer1, client1, loaded_model)
|
||||||
|
|
||||||
|
bot.goByAStar((tables[3].pos[0] + 1, tables[3].pos[1]))
|
||||||
|
opinion = show_predict(prefer2, client2, loaded_model)
|
||||||
|
|
||||||
|
bot.goByAStar((tables[5].pos[0] + 1, tables[5].pos[1]))
|
||||||
|
opinion = show_predict(prefer3, client3, loaded_model)
|
||||||
|
|
||||||
|
messagebox.showinfo("Informacja końcowa", "Zakończono trasę.")
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
exit()
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
def text_objects(text, font):
|
def text_objects(text, font):
|
||||||
textSurface = font.render(text, True, black)
|
textSurface = font.render(text, True, black)
|
||||||
return textSurface, textSurface.get_rect()
|
return textSurface, textSurface.get_rect()
|
||||||
@ -741,7 +813,7 @@ def main():
|
|||||||
button("Rozpoznawanie talerzy", 0, width + 1, 150, 48, light_beige, white, classify)
|
button("Rozpoznawanie talerzy", 0, width + 1, 150, 48, light_beige, white, classify)
|
||||||
button("Ciężkostrawność dań", 150, width + 1, 150, 48, light_beige, white, evaluate)
|
button("Ciężkostrawność dań", 150, width + 1, 150, 48, light_beige, white, evaluate)
|
||||||
button("Rozpoznawanie banknotów", 300, width + 1, 150, 48, light_beige, white, payment)
|
button("Rozpoznawanie banknotów", 300, width + 1, 150, 48, light_beige, white, payment)
|
||||||
button("Polecanie dań", 450, width + 1, 150, 48, light_beige, white) #Natalia tu dopisz swoją funkcję :)
|
button("Polecanie dań", 450, width + 1, 150, 48, light_beige, white, Tree_natalia)
|
||||||
redrawWindow(window)
|
redrawWindow(window)
|
||||||
|
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
|
131
polecanie_dań_Natalia_Plitta.md
Normal file
131
polecanie_dań_Natalia_Plitta.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
##### Raport przygotowała: Natalia Plitta
|
||||||
|
|
||||||
|
##### Raportowany okres: 11 maja - 25 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, która na podstawie podanych parametrów poleca jedno z siedmiu dań. Wykorzystane zostały poniższe biblioteki:
|
||||||
|
|
||||||
|
- scikit - learn
|
||||||
|
- joblib
|
||||||
|
- IPython
|
||||||
|
- pandas
|
||||||
|
- pydotplus
|
||||||
|
- StringIO
|
||||||
|
##Realizacja projektu ##
|
||||||
|
|
||||||
|
#### 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")
|
||||||
|
```
|
||||||
|
|
||||||
|
<img src="https://git.wmi.amu.edu.pl/s444412/DSZI_2020_Projekt/raw/master/Restaurant/Marta/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.
|
Loading…
Reference in New Issue
Block a user