# 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


# %% 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)",
                                     "Sex"]]
                                     
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",
                            "Sex": "pol"})

skup.dropna(inplace=True)

skup["pol"].unique()
skup.drop(skup[skup["pol"] == "."].index, inplace=True)

oznaka_preslikavanje_tb = {"FEMALE": 0, "MALE": 1}
skup["oznaka"] = skup["pol"].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 = skup_obučavanje.get(ob_cilj)

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 = skup_validacija.get(ob_cilj)


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

nm = Sequential()
nm.add(Input(shape=(ob_ulaz_kard,)))
nm.add(Dense(5, activation="sigmoid"))
nm.add(Dense(1, activation="sigmoid"))

nm.compile(loss="binary_crossentropy", 
           optimizer="adam",
           metrics=["binary_accuracy"])

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


# %% Validacija neuronske mreže

print("validacija")
print()

izlaz = nm.predict(skup_validacija_ulaz, verbose=0)
izlaz_oznaka = np.where(izlaz >= 0.5, 1, 0).ravel()
stvarno_oznaka = skup_validacija_cilj.values

tačnost = ((izlaz_oznaka == stvarno_oznaka).sum() / 
           izlaz_oznaka.shape[0]).round(4)

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

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

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

print("tačnost \n", tačnost)
print()

