# Univerzitet u Novom Sadu, Fakultet tehničkih nauka, Novi Sad, Srbija
# Studijski program OAS Informacioni inženjering
# Predmet Metode i tehnike nauke o podacima

# Pomoćni sadržaj

# Korišćeni podaci
#
# Skup podataka "Structural size measurements and isotopic signatures
# of foraging among adult male and female Adélie penguins (Pygoscelis
# adeliae) nesting along the Palmer Archipelago near Palmer Station,
# 2007-2009"
# - Internet sajt EDI Data Portal
# - podaci o pingvinima vrste Pygoscelis adeliae s Palmerovog arhipelaga
#   - autor podataka: stanica Palmer Antarktik LTER, Kristen Gorman 
#     (Univerzitet Sajmon Frejzer, Vankuver, Kanada)
#   - vreme nastanka podataka: od 2007. do 2009.
#   - format podataka: CSV
#
# Internet strana:
# https://portal.edirepository.org/nis/mapbrowse?packageid=knb-lter-pal.219.5
#
# Skup podataka "Structural size measurements and isotopic signatures
# of foraging among adult male and female gentoo penguins (Pygoscelis
# papua) nesting along the Palmer Archipelago near Palmer Station,
# 2007-2009"
# - Internet sajt EDI Data Portal
# - podaci o pingvinima vrste Pygoscelis papua s Palmerovog arhipelaga
#   - autor podataka: stanica Palmer Antarktik LTER, Kristen Gorman 
#     (Univerzitet Sajmon Frejzer, Vankuver, Kanada)
#   - vreme nastanka podataka: od 2007. do 2009.
#   - format podataka: CSV
#
# Internet strana:
# https://portal.edirepository.org/nis/mapbrowse?scope=knb-lter-pal&
# identifier=220&revision=7
#
# Skup podataka "Structural size measurements and isotopic signatures
# of foraging among adult male and female Chinstrap penguins (Pygoscelis
# antarcticus) nesting along the Palmer Archipelago near Palmer Station,
# 2007-2009"
# - Internet sajt EDI Data Portal
# - podaci o pingvinima vrste Pygoscelis antarcticus s Palmerovog arhipelaga
#   - autor podataka: stanica Palmer Antarktik LTER, Kristen Gorman 
#     (Univerzitet Sajmon Frejzer, Vankuver, Kanada)
#   - vreme nastanka podataka: od 2007. do 2009.
#   - format podataka: CSV
#
# Internet strana:
# https://portal.edirepository.org/nis/mapbrowse?scope=knb-lter-pal&
# identifier=221&revision=8
#


# %% Biblioteke

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Input
from keras.layers import Dense
from keras.utils import to_categorical


# %% Generator vrednosti

gpsv = np.random.default_rng(59)


# %% Učitavanje i uređivanje podataka

podaci_adelie = pd.read_csv("table_219.csv")
podaci_papua = pd.read_csv("table_220.csv")
podaci_antarcticus = pd.read_csv("table_221.csv")

skup = pd.concat([podaci_adelie, podaci_papua, podaci_antarcticus], 
                 ignore_index=True)[["Species", 
                                     "Culmen Length (mm)", 
                                     "Culmen Depth (mm)", 
                                     "Flipper Length (mm)", 
                                     "Body Mass (g)"]]
                                     
skup = skup.rename(columns={"Species": "vrsta", 
                            "Culmen Length (mm)": "kljun_dužina", 
                            "Culmen Depth (mm)": "kljun_dubina", 
                            "Flipper Length (mm)": "peraje_dužina", 
                            "Body Mass (g)": "telo_težina"})

skup.dropna(inplace=True)

oznaka_preslikavanje_tb = {"Adelie Penguin (Pygoscelis adeliae)": 0, 
                           "Gentoo penguin (Pygoscelis papua)": 1, 
                           "Chinstrap penguin (Pygoscelis antarctica)": 2}

oznaka_preslikavanje_bt = {0: "Adelie Penguin (Pygoscelis adeliae)", 
                           1: "Gentoo penguin (Pygoscelis papua)", 
                           2: "Chinstrap penguin (Pygoscelis antarctica)"}

skup["oznaka"] = skup["vrsta"].apply(lambda x: oznaka_preslikavanje_tb[x])

skup.shape
skup.dtypes


# %% Pripremanje podataka za postupke obučavanja i validacije neuronske mreže

ob_ulaz = ["kljun_dužina", "kljun_dubina", "peraje_dužina", "telo_težina"]
ob_ulaz_kard = len(ob_ulaz)
ob_cilj = "oznaka"
ob_cilj_jedinst_kard = skup[ob_cilj].nunique()

skup_obučavanje = skup.sample(frac=0.8, random_state=gpsv.bit_generator)
skup_obučavanje_ulaz = skup_obučavanje.get(ob_ulaz)
skup_obučavanje_ulaz = (skup_obučavanje_ulaz - 
                        skup_obučavanje_ulaz.min()) / (
                            skup_obučavanje_ulaz.max() - 
                            skup_obučavanje_ulaz.min())
skup_obučavanje_cilj = to_categorical(skup_obučavanje.get(ob_cilj), 
                                      ob_cilj_jedinst_kard)

skup_validacija = skup.drop(index=skup_obučavanje.index)
skup_validacija_ulaz = skup_validacija.get(ob_ulaz)
skup_validacija_ulaz = (skup_validacija_ulaz - 
                        skup_validacija_ulaz.min()) / (
                            skup_validacija_ulaz.max() - 
                            skup_validacija_ulaz.min())
skup_validacija_cilj = to_categorical(skup_validacija.get(ob_cilj), 
                                      ob_cilj_jedinst_kard)


# %% Formiranje i obučavanje neuronske mreže

nm = Sequential()
nm.add(Input(shape=(ob_ulaz_kard,)))
nm.add(Dense(10, activation="tanh"))
nm.add(Dense(ob_cilj_jedinst_kard, activation="softmax"))

nm.compile(loss="categorical_crossentropy", 
           optimizer="adam",
           metrics=["categorical_accuracy"])

nm.fit(skup_obučavanje_ulaz, skup_obučavanje_cilj, epochs=70)
print()


# %% Validacija neuronske mreže

print("validacija")
nm.evaluate(skup_validacija_ulaz, skup_validacija_cilj, verbose=2)
print()

izlaz = nm.predict(skup_validacija_ulaz, verbose=0)
izlaz_oznaka = np.argmax(izlaz, axis=1)
stvarno_oznaka = np.argmax(skup_validacija_cilj, axis=1)

print("izlaz \n", izlaz)
print()

print("izlaz kao oznake \n", izlaz_oznaka)
print()

print("očekivane oznake \n", stvarno_oznaka)
print()

print("pogrešne procene ")
for stvarno, procenjeno in zip(stvarno_oznaka, izlaz_oznaka):
    if stvarno != procenjeno:
        print("\t izlaz '{}' \n\t\t očekivano '{}'".format(
            oznaka_preslikavanje_bt[procenjeno],
            oznaka_preslikavanje_bt[stvarno]))

