Skip to content

Commit

Permalink
Merge pull request #7 from torave/hanne
Browse files Browse the repository at this point in the history
Hanne - predetic
  • Loading branch information
torave authored and GitHub Enterprise committed Apr 8, 2025
2 parents fc2dcbe + ad9ec94 commit f41226c
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 13 deletions.
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Da begynte vi å lete etter API-er, først på Metrologisk Institutt:
- Vanskelig å kunne hente data fra ønsket sted, stasjonsbasert
- [Locationforecast](https://api.met.no/weatherapi/locationforecast/2.0/documentation)
- Enkel å finne data fra ønsket sted, men bare en forecast, så finner ikke historiske data
- [Vaer og klima](https://www.met.no/vaer-og-klima/klima-siste-150-ar)
- Mye historisk data, men hadde kun for regioner og ikke for byer slik vi ønsket

Ettersom ingen av de fra MET funket etter vårt ønske, søkte vi videre på nettet, og kom over:
- [OpenWeatherMap API](https://openweathermap.org/)
Expand Down Expand Up @@ -95,4 +97,73 @@ Pandas-syntaks kan være noe kompleks og da kan man for eksempel med sqldf, bruk
##### Uregelmessigheter i dataene
Uregelmessigheter vi kan forvente å møte på er blant annet manglende verdier. For å håndtere disse kan vi bruke metoder som for eksempel fillna(), som fyller manglende verdier med en standardverdi. Eller så kan vi bruke dropna(), som fjerner radene med manglende verdi. Vi kan også møte på ufullstendige datoer eller datoer i ukjent format. Da kan vi bruke pd.to_datetime() for å sikre at datoene blir riktig konvertert til datetime format. 

Vi kan også møte ekstremverdier, som vi kan fjerne ved å sjekke om de er "uteliggere" ved å ligge mer enn tre standardavvik i fra gjennomsnittet. Da kan vi bruke verdien før med fillna('obj.ffill()') eller bruke interpolate linear metoden for å få den mest "smoothe" overgangen mellom manglende verdier. Da den "gjetter" seg frem til manglende verdier.
Vi kan også møte ekstremverdier, som vi kan fjerne ved å sjekke om de er "uteliggere" ved å ligge mer enn tre standardavvik i fra gjennomsnittet. Da kan vi bruke verdien før med fillna('obj.ffill()') eller bruke interpolate linear metoden for å få den mest "smoothe" overgangen mellom manglende verdier. Da den "gjetter" seg frem til manglende verdier.


#### Oppgave 4 - Dataanalyse

#### Numpy og Pandas til beregninger
For eksempel i notebook_statistic_data har vi brukt Pandas til å beregne gjennomsnittstemperaturen for å få oversikt over den typiske temperaturen i den perioden. Så har vi temp.median også som gir den midterste verdien og er viktig for når det er skjevheter i dataene. For eksempel hvis det er dager med ekstremt høy eller ekstremt lav temperatur vil medianen hjelpe oss med å gi en mer riktig representativ temperatur. Disse statistiske målene hjelper med å få innsikt i datasettet. Gjennomsnittet gir en generell indikasjon på temperaturen, medianen beskytter mot ekstreme verdier, og standardavviket forteller oss om variasjonen i dataene.

#### Kan du gi et eksempel på hvordan du vil implementere en enkel statistisk analyse for å undersøke sammenhengen mellom to variabler i datasettet?


#### Håndtering av skjevheter
Vi har møtt på noen skjevheter som for eksempel at temperaturen har vært urealistisk i perioder, for å rydde opp i dette har vi sjekket uteliggere, altså sjekket om verdiene ligger mer enn 3 standardavvik fra gjennomsnittet. Om standardavviket er høyere enn 3 byttet ut disse verdiene med mer realistisk verdi basert på de andre verdiene.

#### Visualiseringer av funnene våre
Vi har laget mange grafer som viser både temperatur, nedbør i både regn og snø, og vindmålinger for å visuelt formidle funnene våre. Disse grafene kan du finne i våre notebooks.


#### Oppgave 5 - Visualisering

#### Hvilke spesifikke typer visualiseringer planlegger du å lage for å representere eksempelvis endringer i luftkvalitet og temperaturdata, og hvorfor valgte du disse?
Vi har laget visualiseringer for temperatur og andre værforhold både for dagens dato, alle timene i en dag og sted brukeren selv velger, en kort periode og sted som brukeren selv velger og årlig for et sted brukeren selv velger. Det årlige dataene er basert på alle tidligere år sammenlagt. Vi valgte akkurat disse fordi det gir brukeren flere muligheter å sjekke ulike perioder og steder. Vi valgte nedbør, vind og temperatur fordi det er de værforholdene vi mener er mest interessante å vite. I notebook_current_data som viser data fra dagen idag har vi ikke tatt en graf men heller en kolonne med informasjon. Her har vi i tillegg til værdataene lagt til solnedgang og soloppgang fordi vi tenker at det kan være noe brukeren synes er relevant når spør om dagens data.


#### Hvordan kan Matplotlib og Seaborn brukes til å forbedre forståelsen av de analyserte dataene, og hvilke funksjoner i disse bibliotekene vil være mest nyttige?



#### Hvordan vil du håndtere og visualisere manglende data i grafene dine for å sikre at de fortsatt er informative?
Da vil vi at den manglende dataen blir byttet ut med data som er hentet fra tidspunktene rundt slik den manglende dataen får en verdi som passer med de andre. Vi har også for eksempel laget søylediagram som viser manglende data for feks. snø og regn ettersom det ikke alltid snør og regner også videre laget et nytt diagram hvor de manglende dataene for snø og regn er byttet med 0.

#### Kan du beskrive prosessen for å lage interaktive visualiseringer med Widgets, Plotly eller Bokeh, og hvilke fordeler dette kan gi i forhold til statiske visualiseringer?


#### Hvordan vil du evaluere effektiviteten av visualiseringene dine i å formidle de viktigste funnene fra dataanalysen til et bredere publikum?
Vi mener effektiviteten i visualiseringene våre er svært god fordi grafene og søylediagramene er lett lesbare og vi har kodet ut kolonner vi ikke mener har data med viktig informasjon. Grafene har også fargekoder og kombinasjoner for de ulike værforholdene noe som gir en god visuell oversikt.


#### Opggave 6 - Prediktiv analyse

#### Lag minst tre forskjellige typer visualiseringer (f.eks. linjediagrammer, søylediagrammer og scatterplots) for å representere endringer i eksempelvis luftkvalitet og temperaturdata over tid. Forklar valget av visualiseringstype for hver graf.
Vi har laget linjediagrammer, søylediagrammer og scatterplots. Alle tre typer kan man finne i notebook_one_day_data.ipynb, i notebook_one_week.ipynb kan man finne søylediagram og linjediagram. I notebook_statistic_data.ipynb kan man finne linjediagram og søylediagram.
Linjediagram ble brukt i de fleste notebooks fordi det passer godt til å vise utvikling over tid, spesielt for temperaturen. Søylediagram ble brukt fordi det gjør det enkelt å visuelt se hvor mye feks. regn eller snø det var i den perioden. Scatterplots ble brukt for å visuelt vise hvor mye temperaturen hver time er over eller under gjennomsnittet for dagens temperatur.


#### Implementer visualiseringer ved hjelp av Matplotlib og Seaborn. Inkluder tilpassede akser, titler, og fargepaletter for å forbedre lesbarheten og estetikk.


#### Demonstrer hvordan manglende data håndteres i visualiseringene. Lag en graf som viser hvordan manglende verdier påvirker datatrender, og diskuter hvordan dette kan påvirke tolkningen av dataene.


#### Skriv en kort evaluering av de utviklede visualiseringene. Diskuter hvilke visualiseringer som var mest effektive for å formidle informasjon, og hvorfor. Reflekter over tilbakemeldinger fra medstudenter eller veileder.


#### Oppgave 7 - Refleksjonsnotat
Det jeg har lært om datainnsamling, databehandling og dataanalyse, visualisering gjennom dette prosjektet er at det krever en del arbeid og kan være frustrerende, men når man får det til så er det en utrolig mestringsfølelse og en veldig oversiktlig og informativ representasjon av datainnsamlingene. Visualiseringen av dataen var mest givende fordi vi fikk tydelig se at databehandlingen og datarenskingen ga resultater og et fint layout.

Jeg har hatt noe koding med Pythons-bibliotekene Pandas, NumPy og Matplotlib fra emne TDT4111 forrige semester. Men gjennom dette emne og denne oppgaven har jeg blitt tryggere på alle tre, spesielt Pandas. Jeg har også blitt kjent med et nytt bibliotek, Scikit-learn og fått nye ferdigheter til hvordan å bruke dette til å gjøre lineær regresjon.

Når vi først skulle komme i gang med prosjektet møtte vi på en del hindringer og komplikasjoner ved GitHub og API. Jeg hadde laget mappen min for prosjektet i OneDrive mappen min og begynt å jobbe der og da når jeg skulle commite og pulle og slikt så gikk ikke dette og jeg fikk flere feilmeldinger. Fikk feilmeldinger om API og at mappen var feil, vi fikk laget en ny API og fikk fortsatt feilmelding. Etter litt frem og tilbake så prøvde vi å flytte mappen fra OneDrive til direkte på datamaskinen og da løste det seg. Ellers har det noen ganger dukket opp feilmeldinger når jeg har manglet biblioteker eller de har trengt å oppdatere seg, men disse små hindrene løste vi fort.

Jeg synes samarbeidet i gruppen har gått bra. Når jeg har møtt på hinder har hun vært veldig flink til å hjelpe meg og løse de sammen med meg. Vi har møttes jevnt og jobbet litt sammen og fordelt oppgaver mellom oss som skal jobbes med frem til vi møtes igjen. Ettersom jeg hadde noen vanskeligheter med GitHub iblant har vi løst det med at jeg har sendt arbeidet mitt til henne på mail og hun har lagt det inn i GitHub.

Kvaliteten på dataene våre mener jeg er gode ettersom vi har en API som man trenger å lage bruker for (gratis) og har utrolig mye data for mange mange år og mange steder. Jeg mener dette styrker troverdigheten og legitimiteten til dataene våre. Vi har fått laget mange diagrammer og mange Jupyter Notebooks som gjør at brukeren kan velge fra forskjellige perioder og steder de ønsker informasjon om værforhold fra. Grafene er lett lesbare og har realistisk data noe jeg mener styrker kvaliteten på dataene våre. Ettersom dataene fra API-en vår er i kelvin og ikke celsius har det noen steder vært litt komplikasjoner med riktig temperatur, noe som gjerne svekker kvaliteten litt.

For videre forskning kunne vi utviklet kodene våre til å gi brukeren valget om å velge byer utenfor Norge. Vi har i dette prosjektet begrenset til Norge, så å ha muligheten til å sjekke byer i hele verden ville vært et bra og naturlig steg videre i forskningen.

Det jeg mener er noen av de viktigste læringspunktene er at jeg har fått blitt bedre kjent med biblioteker og fått god øving på å programmere og jobbe i gruppe. Med store datamengder av været kan man sammenligne værforhold i dag og mange år tilbake og se på forskjellene. Da kan man prøve å se det i miljøaspekt og det kunne også vært interessante forhold å se på videre. Våre værdata i sammenheng med miljø og klima utviklingen gjennom årene. Andre viktige læringspunkter jeg har fått bedre forståelse for er iteratorer og list-comprehensions, enhetstesting, kunne håndtere data lagring, feil og filbehandlinger.

Jeg tror at å ha erfaringene jeg har lært om Pythons generelt, VS-Code, Jupyter Notebooks vil komme godt med i arbeidslivet dersom man finner en jobb innenfor programmerings område. Samtidig som de grunnleggende programmeringsferdighetene vil komme godt med, vil det at vi har jobbet mye med statistikk og grafer gjøre at vi har en bedre forståelse av de områdene noe som man vil trenge videre i studie og i en eventuell jobb. Det at vi har jobbet i grupper har også en positiv påvirkning ved at vi lærer og samarbeidet og kommunisere med andre.
156 changes: 144 additions & 12 deletions notebooks/notebook_one_day_data.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
"### Viser temperaturen\n",
"Regner ut gjennomsnittst-temperatur ved hjelp av innebygde funksjoner. Finner også høyeste og laveste målte temperatur.\n",
"\n",
"Plotter temperaturen ved hjelp av matplotlib."
"Plotter gjennomsnittstemperaturen og temperaturen per time for dagen valgt, ved hjelp av matplotlib."
]
},
{
Expand All @@ -220,36 +220,43 @@
"print(\"Highest temperature:\", max_temp)\n",
"print(\"Lowest temperature:\", min_temp)\n",
"\n",
"# Set the x_axis to the index, which means the time\n",
"\n",
"# Set the x_axis to the index, which represents the time\n",
"x_axis = df.index\n",
"\n",
"# Choose the width and height of the plot\n",
"plt.figure(figsize=(12, 6))\n",
"\n",
"# Plotting temperatur\n",
"plt.plot(x_axis, temp, color='tab:red', label='Temperatur')\n",
"# Scatter plot for each temperature reading\n",
"plt.scatter(x_axis, temp, color='tab:green', label='Temperaturmålinger', alpha=0.6)\n",
"\n",
"# Get the current axsis, and store it as ax\n",
"# Add a horizontal line for the mean temperature\n",
"plt.axhline(y=temp_mean, color='green', linestyle='--', label=f'Gj.snitt {temp_mean}°C')\n",
"\n",
"# Get the current axis and store it as ax\n",
"ax = plt.gca()\n",
"\n",
"# Customize the x-axis to show ticks for each hour\n",
"ax.xaxis.set_major_locator(mdates.HourLocator(interval=1)) # Tick marks for every hour\n",
"ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # Format as \"Day Month Hour:Minute\"\n",
"ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # Format as \"Hour:Minute\"\n",
"\n",
"# Rotate x-axis labels for better readability\n",
"plt.xticks(rotation=45)\n",
"\n",
"# Adjust layout\n",
"plt.tight_layout()\n",
"\n",
"# Add title for the plot, with city_name and start to end date\n",
"# Add title for the plot\n",
"plt.title(f'Temperatur {city_name}, ({date})')\n",
"\n",
"# Shows a grid\n",
"# Show grid\n",
"plt.grid()\n",
"\n",
"# Show the label-description\n",
"plt.legend(loc = 'upper right')\n",
"# Show legend\n",
"plt.legend(loc='upper right')\n",
"\n",
"# Show the plot\n",
"plt.show()"
"plt.show()\n"
]
},
{
Expand Down Expand Up @@ -563,6 +570,131 @@
"# Show the plot\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lineær regresjons og prediktiv analyse\n",
"\n",
"lager en lineær regresjon og bruker den til å finne temperaturer vi kan forvente å få samme tid, neste år.\n",
"Bruker scikit-learn biblioteket, sklearn.linear_model, LinearRegression for å få til dette"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.linear_model import LinearRegression\n",
"\n",
"#Hours of the day (0 to 23) and temperatures\n",
"data = {\n",
" 'Hour': np.arange(24), # 24 hours of the day\n",
" 'Temperature': temp # get the temperatures\n",
"}\n",
"\n",
"# Create a DataFrame\n",
"df = pd.DataFrame(data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### klargjøre data til regresjonsmodellen"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Reshape the data (features should be 2D for sklearn)\n",
"X = df['Hour'].values.reshape(-1, 1) # Hours of the day (x-axis)\n",
"y = df['Temperature'].values # Temperatures (y-axis)\n",
"\n",
"# Create and train the regression model\n",
"model = LinearRegression()\n",
"model.fit(X, y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### trene modellen og predikerte fremtidig data\n",
"\n",
"trene modellen og lager en graf som viser den originale dataen fra årets dag brukeren har skrevet inn og regresjons modellen\n",
"\n",
"bruker den trente modellen til å lage predikasjoner for temperaturen samme dag, neste år"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from matplotlib.dates import DateFormatter\n",
"\n",
"y = np.array(df['Temperature'].values)\n",
"\n",
"x_axis = df.index\n",
"\n",
"plt.figure(figsize=(12, 6))\n",
"\n",
"# Plot the original data\n",
"plt.scatter(x_axis, y, color='green', label='Original data', alpha=0.6)\n",
"\n",
"predicted_temperatures = model.predict(X)\n",
"\n",
"# Plot the regression line\n",
"plt.plot(x_axis, predicted_temperatures, color='red', label='Prediktiv temperatur')\n",
"\n",
"#title for the axis\n",
"plt.xlabel('Datetime')\n",
"plt.ylabel('Temperature (°C)')\n",
"\n",
"#ax = plt.gca()\n",
"\n",
"# Customize the x-axis to show ticks for each hour\n",
"plt.xticks(rotation=45)\n",
"plt.gca().xaxis.set_major_formatter(DateFormatter('%H:%M'))\n",
"\n",
"plt.tight_layout()\n",
"\n",
"#Title for the plot\n",
"plt.title(f'Temperature {city_name}')\n",
"\n",
"plt.grid(axis = 'x')\n",
"\n",
"plt.legend(loc='upper right')\n",
"\n",
"plt.show()\n",
"\n",
"# Display the predicted temperatures\n",
"print(f'predicted temperatures: {predicted_temperatures}')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand All @@ -581,7 +713,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.5"
"version": "3.9.6"
}
},
"nbformat": 4,
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/test_nordic_cityname.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import unittest

from src.my_package.util import replace_nordic

#test one city for every letter "æøå" to see that they all work
class TestReplaceNordic(unittest.TestCase):
def test_replace_nordic(self):
self.assertEqual(replace_nordic("Bærum"), "Baerum")
self.assertEqual(replace_nordic("Bø"), "Bo")
self.assertEqual(replace_nordic("Snåsa"), "Snaasa")

if __name__ == "__main__":
unittest.main()

0 comments on commit f41226c

Please sign in to comment.