Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
fab7c34909
92
Justyna.md
Normal file
92
Justyna.md
Normal file
@ -0,0 +1,92 @@
|
||||
# Drzewa decyzyjne, algorytm ID3
|
||||
|
||||
### autor Justyna Zarzycka
|
||||
|
||||
## Opis projektu
|
||||
Projekt implementuje tworzenie drzewa decyzyjnego wykorzystującego algorytm ID3, ktióre pomaga określić chęci do pracy agenta na podstawie warunków panujących na planszy.
|
||||
|
||||
### Tworzenie drzewa decyzyjnego
|
||||
|
||||
Funkcja budująca drzewo za pomocą algorymu ID3:
|
||||
|
||||
```py
|
||||
def ID3(data, original_data, attributes, target, parent_node_class=None):
|
||||
|
||||
if len(np.unique(data[target])) <= 1:
|
||||
return np.unique(data[target])[0]
|
||||
elif len(data) == 0:
|
||||
return np.unique(original_data[target])[
|
||||
np.argmax(np.unique(original_data[target], return_counts=True)[1])]
|
||||
elif len(attributes) == 0:
|
||||
return parent_node_class
|
||||
else:
|
||||
parent_node_class = np.unique(data[target])[
|
||||
np.argmax(np.unique(data[target], return_counts=True)[1])]
|
||||
|
||||
item_values = [info_gain(data, i, target) for i in
|
||||
attributes]
|
||||
|
||||
best_attribute_index = np.argmax(item_values)
|
||||
best_attribute = attributes[best_attribute_index]
|
||||
|
||||
tree = {best_attribute: {}}
|
||||
|
||||
attributes = [i for i in attributes if i != best_attribute]
|
||||
for value in np.unique(data[best_attribute]):
|
||||
sub_data = data.where(data[best_attribute] == value).dropna()
|
||||
subtree = ID3(sub_data, data, attributes, target, parent_node_class)
|
||||
tree[best_attribute][value] = subtree
|
||||
|
||||
return (tree)
|
||||
```
|
||||
Cechą charakterystyczną algorytmu jest wybór atrybutów dla których kolejno przeprowadzane są testy taki, aby końcowe drzewo było jak najprostsze i jak najefektywniejsze. Wybór atrybutów opiera się na liczeniu entropii, co pozwala obliczyć, wybór którego z atrybutów da największy przyrost informacji.
|
||||
|
||||
Obliczanie wartości przyrostu informacji:
|
||||
|
||||
Funkcja oblicza który atrybut najlepiej rozdziela zbiór danych (dzieli zbiór przykładów na jak najbardziej równe podzbiory).
|
||||
|
||||
```py
|
||||
def info_gain(data, split_attribute, target):
|
||||
|
||||
_entropy = entropy(data[target])
|
||||
vals, counts = np.unique(data[split_attribute], return_counts=True)
|
||||
weighted_entropy = np.sum(
|
||||
[(counts[i] / np.sum(counts)) * entropy(data.where(data[split_attribute] == vals[i]).dropna()[target])
|
||||
for i in range(len(vals))])
|
||||
information_gain = _entropy - weighted_entropy
|
||||
|
||||
return information_gain
|
||||
```
|
||||
|
||||
Entropia:
|
||||
|
||||
Entropia jest miarą ilości informacji - im mniejsza entropia, tym więcej informacji. W przypadku problemu klasyfikacji przykładów do dwóch odrębnych klas, wzór na entropię przedstawia się następująco:
|
||||
|
||||
Entropy(S) = - ∑ pᵢ * log₂(pᵢ) ; i = 1 to n
|
||||
gdzie:
|
||||
Z - źródło informacji
|
||||
p - prawdopodobieństwo wystąpienia przykładu pozytywnego w zbiorze trenującym
|
||||
(1-p) - prawdopodobieństwo wystąpienia przykładu negatywnego w zbiorze trenującym
|
||||
|
||||
```py
|
||||
def entropy(attribute):
|
||||
values, counts = np.unique(target_col, return_counts=True)
|
||||
entropy = np.sum(
|
||||
[(-counts[i] / np.sum(counts)) * np.log2(counts[i] / np.sum(counts)) for i in range(len(values))])
|
||||
return entropy
|
||||
```
|
||||
|
||||
### Zestaw uczący
|
||||
|
||||
Zestaw budujący drzewo to lista zawierająca 24 przykładów waruków panujących na polu. Atrybyty zapisane są w formacie ['pogoda', 'ile_chwastow', 'ile_burakow', 'czy_chce_pracowac']. Przykłady ze zbioru:
|
||||
|
||||
```py
|
||||
['slonecznie', 'duzo', 'bardzo_malo', 'srednio'],
|
||||
['deszcz', 'bardzo_duzo', 'malo', 'nie'],
|
||||
['grad', 'bardzo_duzo', 'bardzo_malo', 'nie'],
|
||||
['zachmurzenie', 'srednio', 'srednio', 'tak']
|
||||
```
|
||||
|
||||
### Implementacja w projekcie
|
||||
Podprojet uruchamiany jest za pomocą klawisza *F5*. Pobierane są inforamcje o warunkach panujących na polu, na podstawie których oceniana jest chęć do pracy.
|
||||
|
190
Justyna.py
190
Justyna.py
@ -1,3 +1,120 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from pprint import pprint
|
||||
import dataset
|
||||
import random
|
||||
|
||||
# obliczenie entropii dla wskazanej kolumny
|
||||
def entropy(attribute):
|
||||
values, counts = np.unique(attribute, return_counts=True)
|
||||
entropy = np.sum(
|
||||
[(-counts[i] / np.sum(counts)) * np.log2(counts[i] / np.sum(counts)) for i in range(len(values))])
|
||||
return entropy
|
||||
|
||||
#obliczanie wartości przyrostu informacji
|
||||
def info_gain(data, split_attribute, target):
|
||||
|
||||
# Wartość entropii zbioru
|
||||
_entropy = entropy(data[target])
|
||||
|
||||
# Wyodrębnienie poszczególnych podzbiorów
|
||||
vals, counts = np.unique(data[split_attribute], return_counts=True)
|
||||
|
||||
# Średnia ważona entropii każdego podzbioru
|
||||
weighted_entropy = np.sum(
|
||||
[(counts[i] / np.sum(counts)) * entropy(data.where(data[split_attribute] == vals[i]).dropna()[target])
|
||||
for i in range(len(vals))])
|
||||
|
||||
# Przyrost informacji
|
||||
information_gain = _entropy - weighted_entropy
|
||||
|
||||
return information_gain
|
||||
|
||||
|
||||
def ID3(data, original_data, attributes, target, parent_node_class=None):
|
||||
|
||||
|
||||
# Jeżeli wszystkie atrybuty są takie same, zwracamy liść z pierwszą napotkaną wartością
|
||||
|
||||
if len(np.unique(data[target])) <= 1:
|
||||
return np.unique(data[target])[0]
|
||||
|
||||
elif len(data) == 0:
|
||||
return np.unique(original_data[target])[
|
||||
np.argmax(np.unique(original_data[target], return_counts=True)[1])]
|
||||
|
||||
elif len(attributes) == 0:
|
||||
return parent_node_class
|
||||
|
||||
else:
|
||||
|
||||
# nadrzędna wartość
|
||||
parent_node_class = np.unique(data[target])[
|
||||
np.argmax(np.unique(data[target], return_counts=True)[1])]
|
||||
|
||||
# obliczenie przyrostu informacji dla każdego atrybutu
|
||||
item_values = [info_gain(data, i, target) for i in
|
||||
attributes]
|
||||
|
||||
# Wybór najlepszego atrybutu
|
||||
best_attribute_index = np.argmax(item_values)
|
||||
best_attribute = attributes[best_attribute_index]
|
||||
|
||||
# Struktura drzewa
|
||||
tree = {best_attribute: {}}
|
||||
|
||||
# Aktualizacja zbioru atrybutów
|
||||
attributes = [i for i in attributes if i != best_attribute]
|
||||
|
||||
# Budowa poddrzewa dla każdej wartości wybranego atrybutu
|
||||
for value in np.unique(data[best_attribute]):
|
||||
|
||||
sub_data = data.where(data[best_attribute] == value).dropna()
|
||||
subtree = ID3(sub_data, data, attributes, target, parent_node_class)
|
||||
|
||||
tree[best_attribute][value] = subtree
|
||||
|
||||
return (tree)
|
||||
|
||||
#tesownie drzewa
|
||||
def test(data, tree):
|
||||
queries = data.iloc[:, :-1].to_dict(orient="records")
|
||||
|
||||
predicted = pd.DataFrame(columns=["predicted"])
|
||||
|
||||
for i in range(len(data)):
|
||||
predicted.loc[i, "predicted"] = search(queries[i], tree, 'nie')
|
||||
print('Precyzja przewidywań: ', (np.sum(predicted["predicted"] == data['czy_chce_pracowac']) / len(data)) * 100, '%')
|
||||
|
||||
#dostowanie danych (lista na słownik) i wywolanie na nich funkcji serach
|
||||
def data_to_dict(data, tree):
|
||||
|
||||
queries = pd.DataFrame(data=data, columns=dataset.header)
|
||||
predicted = pd.DataFrame(columns=["predicted"])
|
||||
dict = queries.iloc[:, :-1].to_dict(orient="records")
|
||||
|
||||
for i in range(len(data)):
|
||||
predicted.loc[i, "predicted"] = search(dict[i], tree, 'nie')
|
||||
|
||||
predicted_list = predicted.values.tolist()
|
||||
return predicted_list[0][0]
|
||||
|
||||
#przeszukwianie drzewa
|
||||
def search(query, tree, default='nie'):
|
||||
|
||||
for key in list(query.keys()):
|
||||
if key in list(tree.keys()):
|
||||
try:
|
||||
result = tree[key][query[key]]
|
||||
except:
|
||||
return default
|
||||
result = tree[key][query[key]]
|
||||
if isinstance(result, dict):
|
||||
return search(query, result)
|
||||
|
||||
else:
|
||||
return result
|
||||
|
||||
class main():
|
||||
def __init__(self,traktor,field,ui,path):
|
||||
self.traktor = traktor
|
||||
@ -6,4 +123,75 @@ class main():
|
||||
self.path = path
|
||||
|
||||
def main(self):
|
||||
pass
|
||||
training_data = pd.DataFrame(data=dataset.training_data, columns=dataset.header)
|
||||
testing_data = pd.DataFrame(data=dataset.testing_data, columns=dataset.header)
|
||||
|
||||
# Utworzenie drzewa
|
||||
tree = ID3(training_data, training_data, training_data.columns[:-1], 'czy_chce_pracowac')
|
||||
pprint(tree)
|
||||
|
||||
# Testowanie drzewa
|
||||
print(test(testing_data, tree))
|
||||
|
||||
# Uzyskanie danych od agenta
|
||||
ocena_burakow = self.ocen_ile_burakow()
|
||||
ocena_chwastow = self.ocen_ile_chwastow()
|
||||
pogoda = self.pogoda()
|
||||
print('chwasty: ' + ocena_chwastow)
|
||||
print('buraki: ' + ocena_burakow)
|
||||
print('pogoda: ' + pogoda)
|
||||
data = [[pogoda, ocena_chwastow, ocena_burakow, '']]
|
||||
|
||||
#podjecie decyzji
|
||||
result = data_to_dict(data, tree)
|
||||
print('czy traktor chce pracowac: ' + result)
|
||||
|
||||
|
||||
def licz_chwasty_buraki(self):
|
||||
chwasty = 0
|
||||
buraki = 0
|
||||
|
||||
for i in self.field.field_matrix:
|
||||
for j in i:
|
||||
if(j==8):
|
||||
buraki = buraki + 1
|
||||
elif(j%2==1):
|
||||
chwasty = chwasty + 1
|
||||
return chwasty, buraki
|
||||
|
||||
def ocen_ile_burakow(self):
|
||||
chwasty, buraki = self.licz_chwasty_buraki()
|
||||
if buraki < 5:
|
||||
return 'bardzo_malo'
|
||||
elif buraki >= 5 and buraki<10:
|
||||
return 'malo'
|
||||
elif buraki >=10 and buraki<15:
|
||||
return 'srednio'
|
||||
elif buraki >=15 and buraki<20:
|
||||
return 'duzo'
|
||||
elif buraki >=20:
|
||||
return 'bardzo_duzo'
|
||||
|
||||
def ocen_ile_chwastow(self):
|
||||
chwasty, buraki = self.licz_chwasty_buraki()
|
||||
if chwasty < 40:
|
||||
return 'bardzo_malo'
|
||||
elif chwasty >= 40 and chwasty<42:
|
||||
return 'malo'
|
||||
elif chwasty >=42 and chwasty<45:
|
||||
return 'srednio'
|
||||
elif chwasty >=45 and chwasty<48:
|
||||
return 'duzo'
|
||||
elif chwasty >=48:
|
||||
return 'bardzo_duzo'
|
||||
|
||||
def pogoda(self):
|
||||
number = random.randrange(0, 4)
|
||||
if number==0:
|
||||
return 'slonecznie'
|
||||
elif number==1:
|
||||
return 'deszcz'
|
||||
elif number==2:
|
||||
return 'grad'
|
||||
elif number==3:
|
||||
return 'zachmurzenie'
|
11
Marcin.py
11
Marcin.py
@ -74,3 +74,14 @@ class main():
|
||||
return 3
|
||||
elif self.mode_value in [6]:
|
||||
return 10
|
||||
|
||||
def main_collective(self,poz):
|
||||
self.pole = self.ui.field_images[self.field.get_value(poz)]
|
||||
self.img = pygame.surfarray.array3d(self.pole)
|
||||
self.img = self.img.transpose([1, 0, 2])
|
||||
self.img = cv2.cvtColor(self.img, cv2.COLOR_RGB2BGR)
|
||||
self.reco = self.mode(self.recognition(self.img))
|
||||
if self.reco == 10:
|
||||
print("Nic nie trzeba robić")
|
||||
else:
|
||||
self.traktor.set_mode(self.reco)
|
15
collective.py
Normal file
15
collective.py
Normal file
@ -0,0 +1,15 @@
|
||||
class main():
|
||||
|
||||
def __init__(self,marcin, justyna, kamila, piotrek, traktor, pole, UI, path):
|
||||
self.marcin = marcin
|
||||
self.justyna = justyna
|
||||
self.kamila = kamila
|
||||
self.piotrek = piotrek
|
||||
self.traktor = traktor
|
||||
self.pole = pole
|
||||
self.UI = UI
|
||||
self.path = path
|
||||
|
||||
def main(self):
|
||||
# self.marcin.main_collective(pozycja) To podaje jakie jest pole jest na danym miejscu
|
||||
pass
|
39
dataset.py
Normal file
39
dataset.py
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
header = ['pogoda', 'ile_chwastow', 'ile_burakow', 'czy_chce_pracowac']
|
||||
|
||||
training_data = [
|
||||
['slonecznie', 'duzo', 'malo', 'tak'],
|
||||
['slonecznie', 'srednio', 'srdenio', 'tak'],
|
||||
['slonecznie', 'bardzo_duzo', 'malo', 'srednio'],
|
||||
['slonecznie', 'malo', 'bardzo_duzo', 'tak'],
|
||||
['slonecznie', 'duzo', 'bardzo_malo', 'srednio'],
|
||||
['slonecznie', 'malo', 'bardzo_malo', 'srednio'],
|
||||
['deszcz', 'bardzo_duzo', 'malo', 'nie'],
|
||||
['deszcz', 'srednio', 'srednio', 'srednio'],
|
||||
['deszcz', 'malo', 'bardzo_duzo', 'tak'],
|
||||
['deszcz', 'duzo', 'duzo', 'srednio'],
|
||||
['deszcz', 'malo', 'malo', 'tak'],
|
||||
['deszcz', 'srednio', 'bardzo_duzo', 'tak'],
|
||||
['grad', 'srednio', 'malo', 'nie'],
|
||||
['grad', 'bradzo_malo', 'bardzo_duzo', 'srednio'],
|
||||
['grad', 'duzo', 'srednio', 'nie'],
|
||||
['grad', 'malo', 'bardzo_malo', 'srednio'],
|
||||
['grad', 'bardzo_duzo', 'bardzo_malo', 'nie'],
|
||||
['grad', 'srednio', 'bardzo_malo', 'nie'],
|
||||
['zachmurzenie', 'srednio', 'srednio', 'tak'],
|
||||
['zachmurzenie', 'bardzo_duzo', 'duzo', 'nie'],
|
||||
['zachmurzenie', 'malo', 'srednio', 'tak'],
|
||||
['zachmurzenie', 'duzo', 'malo', 'srednio'],
|
||||
['zachmurzenie', 'malo', 'bardzo_malo', 'tak'],
|
||||
['zachmurzenie', 'malo', 'srednio', 'tak']
|
||||
]
|
||||
|
||||
testing_data = [
|
||||
['slonecznie', 'srednio', 'srednio', 'tak'],
|
||||
['deszcz', 'duzo', 'malo', 'nie'],
|
||||
['deszcz', 'duzo', 'duzo', 'srednio'],
|
||||
['grad', 'srednio', 'duzo', 'nie'],
|
||||
['zachmurzenie', 'bardzo_duzo', 'malo', 'nie'],
|
||||
['zachmurzenie', 'bardzo_duzo', 'malo', 'nie']
|
||||
]
|
||||
|
18
main.py
18
main.py
@ -1,5 +1,5 @@
|
||||
import pygame, sys
|
||||
import tractor, pathfinding, field, ui, Justyna, Kamila, Marcin, Piotrek, pathfinding_decision
|
||||
import tractor, pathfinding, field, ui, Justyna, Kamila, Marcin, Piotrek, pathfinding_decision, collective
|
||||
from pygame.locals import *
|
||||
|
||||
pole = field.field()
|
||||
@ -10,6 +10,7 @@ j = Justyna.main(traktor,pole,UI,path)
|
||||
k = Kamila.main(traktor,pole,UI,pathfinding_decision.pathfinding_dec())
|
||||
neuro = Marcin.main(traktor,pole,UI,path)
|
||||
p = Piotrek.main(traktor,pole,UI,path)
|
||||
c = collective.main(neuro,j,k,p,traktor,pole,UI,path)
|
||||
pygame.init()
|
||||
UI.update()
|
||||
UI.update()
|
||||
@ -41,12 +42,6 @@ while True:
|
||||
traktor.set_mode(3)
|
||||
if key[K_p]:
|
||||
path.pathfinding(traktor,pole,UI)
|
||||
if key[K_F9]:
|
||||
print(pole.if_value(traktor.get_modes_values()))
|
||||
if key[K_F10]:
|
||||
print(traktor.get_poz())
|
||||
if key[K_F11]:
|
||||
print(traktor.get_field_value())
|
||||
if key[K_F5]:
|
||||
#Dla projektu Justyny
|
||||
j.main()
|
||||
@ -59,6 +54,15 @@ while True:
|
||||
if key[K_F8]:
|
||||
# Dla projektu Piotrka
|
||||
p.main()
|
||||
if key[K_F9]:
|
||||
print(pole.if_value(traktor.get_modes_values()))
|
||||
if key[K_F10]:
|
||||
print(traktor.get_poz())
|
||||
if key[K_F11]:
|
||||
print(traktor.get_field_value())
|
||||
if key[K_12]:
|
||||
c.main()
|
||||
|
||||
UI.update()
|
||||
UI.update()
|
||||
|
||||
|
182
si.cfg
Normal file
182
si.cfg
Normal file
@ -0,0 +1,182 @@
|
||||
[net]
|
||||
# Testing
|
||||
batch=24
|
||||
subdivisions=8
|
||||
# Training
|
||||
# batch=64
|
||||
# subdivisions=2
|
||||
width=416
|
||||
height=416
|
||||
channels=3
|
||||
momentum=0.9
|
||||
decay=0.0005
|
||||
angle=0
|
||||
saturation = 1.5
|
||||
exposure = 1.5
|
||||
hue=.1
|
||||
|
||||
learning_rate=0.001
|
||||
burn_in=1000
|
||||
max_batches = 500200
|
||||
policy=steps
|
||||
steps=400000,450000
|
||||
scales=.1,.1
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=16
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=32
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=2
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[maxpool]
|
||||
size=2
|
||||
stride=1
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
###########
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=42
|
||||
activation=linear
|
||||
|
||||
|
||||
|
||||
[yolo]
|
||||
mask = 3,4,5
|
||||
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
||||
classes=9
|
||||
num=6
|
||||
jitter=.3
|
||||
ignore_thresh = .7
|
||||
truth_thresh = 1
|
||||
random=1
|
||||
|
||||
[route]
|
||||
layers = -4
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[upsample]
|
||||
stride=2
|
||||
|
||||
[route]
|
||||
layers = -1, 8
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=42
|
||||
activation=linear
|
||||
|
||||
[yolo]
|
||||
mask = 0,1,2
|
||||
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
|
||||
classes=9
|
||||
num=6
|
||||
jitter=.3
|
||||
ignore_thresh = .7
|
||||
truth_thresh = 1
|
||||
random=1
|
BIN
si_20000.weights
Normal file
BIN
si_20000.weights
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user