DSZI_2020_Projekt/polecanie_dań_Natalia_Plitta.md

123 lines
5.4 KiB
Markdown
Raw Normal View History

2020-05-24 18:06:58 +02:00
##### 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
2020-05-24 19:33:50 +02:00
2020-05-24 19:27:13 +02:00
## Realizacja projektu ##
2020-05-24 19:33:50 +02:00
Na początku dane są pobierane z pliku "Nowy.csv" gdzie zostały przygotowane 121 wiersze o kolumnach z kolejno podanymi nazwami. Następnie model zostal podzielony na cechy i etykietę ['number'], która oznacza polecane danie.
2020-05-24 19:30:30 +02:00
```python
2020-05-24 19:25:48 +02:00
col_names = ['age', 'sex', 'fat', 'fiber', 'spicy', 'number']
model_tree = pd.read_csv("Nowy.csv", header=None, names=col_names)
model_tree.head()
feature_cols = ['age', 'sex', 'fat', 'fiber', 'spicy']
X = model_tree[feature_cols]
y = model_tree.number
2020-05-24 19:30:30 +02:00
```
2020-05-24 19:33:50 +02:00
#### Dane: ####
2020-05-24 19:30:30 +02:00
Aby utworzyć model stworzyłam 121 wierszy z 6 kolejnych liczb oznaczających:
2020-05-24 19:25:48 +02:00
- wiek klienta (7 - 80);
- zawartość tłuszczu w daniu (0 - 16);
- zawartość błonnika w daniu (0 - 16);
- płeć osoby zamawiającej (0 - kobieta lub 1 - mężczyzna);
- ostrość dania (0 - 5);
- polecane danie o danym numerze:
1. zupa z soczewicy
2. frytki pieczone
3. makaron z sosem brokułowym
4. pikantne skrzydełka zasmażane
5. ostre zasmażane tofu
6. hiszpańska zapiekanka ziemniaczana
7. pieczone warzywa
Poszczególne liczby są oddzielone przecinkami, a wiersze znakiem nowej linii, plik z rozszerzeniem .csv.
2020-05-24 18:06:58 +02:00
2020-05-24 19:33:50 +02:00
#### Drzewa decyzyjne: ####
2020-05-24 18:06:58 +02:00
2020-05-24 19:25:48 +02:00
Następnie następuje podział danych na zestaw treningowy i testowy. Zestaw treningowy to 70% danych, testowy 30%. X to zestaw cech, Y zestaw wyników - tutaj etykieta "number".
2020-05-24 19:33:50 +02:00
```python
2020-05-24 19:25:48 +02:00
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=1)
2020-05-24 19:33:50 +02:00
```
2020-05-24 18:06:58 +02:00
2020-05-24 19:25:48 +02:00
Do stworzenia modelu drzew została wykorzystana funkcja **DecisionTreeClassifier.** Pierwsze drzewo przyjmuje jako kryterium indeks Gini (domyślny), drugie drzewo entropię.
2020-05-24 18:06:58 +02:00
```python
2020-05-24 19:25:48 +02:00
clf = DecisionTreeClassifier()
clf = DecisionTreeClassifier(criterion="entropy")
2020-05-24 18:06:58 +02:00
```
2020-05-24 19:25:48 +02:00
Do modelu drzewa zostały wczytane dane, dzięki funkcji **fit**.
2020-05-24 18:06:58 +02:00
```python
2020-05-24 19:25:48 +02:00
clf = clf.fit(X_train, y_train)
2020-05-24 18:06:58 +02:00
```
2020-05-24 19:25:48 +02:00
Generowane przewidywania są agregowane w zmiennej y_pred, dzięki funckji **predict**.
2020-05-24 18:06:58 +02:00
```python
2020-05-24 19:25:48 +02:00
y_pred = clf.predict(X_test)
2020-05-24 18:06:58 +02:00
```
2020-05-24 19:25:48 +02:00
Następnie wyświetlana jest akuratność dla modelu danych o wybranym kryterium, dzięki funkcji **accuracy_score**.
2020-05-24 18:06:58 +02:00
```python
2020-05-24 19:25:48 +02:00
print("Accuracy:", metrics.accuracy_score(y_test, y_pred))
2020-05-24 18:06:58 +02:00
```
2020-05-24 19:25:48 +02:00
Drzewo decyzyjne ma swoją reprezentację graficzną, która utworzona została dzięki bibliotece IPython, graphviz, StringIO.
2020-05-24 18:06:58 +02:00
```python
2020-05-24 19:25:48 +02:00
dot_data = StringIO()
export_graphviz(clf, out_file=dot_data,
filled=True, rounded=True,
special_characters=True, feature_names=feature_cols,
class_names=['1', '2', '3', '4', '5', '6', '7'])
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_png('polecanie_1.png')
Image(graph.create_png())
```
Na końcu model (z większym wskaźnikiem trafności) zostaje zapisany do pliku z rozszerzeniem sav.
```python
file_name = 'final_model.sav'
joblib.dump(clf, file_name)
2020-05-24 18:06:58 +02:00
```
2020-05-24 19:25:48 +02:00
<img src="https://git.wmi.amu.edu.pl/s444412/DSZI_2020_Projekt/raw/master/Restaurant/Natalia/polecanie_1.png" >
2020-05-24 18:06:58 +02:00
## 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.