Implementere data science løsninger#

Når vi snakker om implementasjon i data science, så kan det bety flere forskjellige ting. Her er en (ikke fullstendig) liste av muligheter:

  • Vi har fått noe innsikt fra data og bruker denne innsikten til å utføre en handling. Data science prosessen slutter her. Vi har for eksempel funnet ut at en ny medisin fungerer bedre enn det som ble brukt før. Vi implementerer dette ved å endre anbefalingene slik at fremtidige pasienter kan få den nye medisinen. Dette er veldig bra å få til, men det trenger vi ikke å snakke mer om.

  • Vi har lagd en modell fra data og bruker den til å predikere noe. Vi lager for eksempel en nettside som bruker modellen for å forslå kundene produkter de ville likt. Det er det vi kommer til å fokusere på.

  • Vi har lagd en modell, bruker den til å predikere noe og oppdaterer den når nye data blir tilgjengelig. Vi lager for eksempel en nettside som bruker modellen for å forslå kundene produkter de ville likt. Når de kjøper eller ikke kjøper genererer det nye data og vi bruker de til å oppdatere modellen vår. Dette krever metoder fra programmvareutvikling som vi ikke snakker om i dette faget.

Her gir vi bare en kort og forenklet innføring i trinnene som vanligvis inngår. I virkeligheten inngår mange flere steg som nettsteddesign, sikkerhet (autentisering, data beskyttelse), oppskalering (til å håndtere mange forespørsler parallelt), monitoring og vedlikehold (overvåke modellens ytelse over tid for å fange opp avvik eller degraderinger i prediksjonsnøyaktigheten og om nødvendig oppdatere modell), osv.

Et minimalt eksempel som kun inneholder de mest relevante stegene er tilgjengelig i huspris_app.

Lagre modeller#

For å lagre modeller kan vi bruke pickle modulen. Vi bruker

pickle.dump(model, open('model.pkl', 'wb'))

for å lagre modellen og

model = pickle.load(open('model.pkl', 'rb'))

for å laste inn modellen.

Enkel nettside med skjema#

Her snakker vi ikke om hvordan å lage en nettside, men kun om hvordan å lage et skjema på en nettside. Det finnes flere muligheter, men her bruker vi HTML Forms. Det er en enkel måte å bruke html til å la brukere fylle ut skjemaer som sendes til en server for behandling. Et eksempel som bruker HTML forms er index.html under templates i huspris_app.

Vi bruker HTML <form> elementet for å lage et HTML skjema. Vanligvis bruker vi den med to argumenter action og method. Action brukes for å sende data videre til en spesifik python-metode. Metoden brukes for å spesifisere http-metoden som skal brukes. Vi skal alltid bruke «post»-metoden.

Det finnes mange forskjellige typer innput som HTML Forms kan ta inn, mest brukt er kanskje tekst <input type="text">, numerisk <input type="number">, dato <input type="date"> og tid <input type="time">. Vi kan også lage rullegardinmeny ved hjelp av <select> -elementer. I så fall bør man sette en <label> først, med samme verdi for xxx i <label for="xxx"> og <select id="xxx">. Elementene i <option> definerer hva slags muligheter som kan velges.

Vi bruker knapper submit og reset for å sende inn data og for å nullstille skjemaet.

Interaksjon mellom python og nettside (Restful API)#

For å kunne endre innholdet av en nettside basert på nye data med python bruker vi flask. Her lager vi en python-fil app.py. Vi begynner alltid ved å importere pakkene flask og waitress.

from flask import Flask, request, render_template
from waitress import serve

Så lager vi en instanse av klassen Flask med variablen __name__ som forteller flask hvor applikasjonen er lagret.

app = Flask(__name__)

Vi bruker så route() for å fortelle flask hvilken url som skal føre til at en funksjonen blir brukt. Her lager vi for eksempel en funksjon som bare gjengir index.html-filen i mappen templates.

@app.route('/')
def home():
    return render_template('./index.html')

Vi kan også lage flere funksjoner som blir brukt når data blir sendt inn. I så fall må vi spesifisere http-metoden som skal brukes i tillegg til en ny url. Vi bruker request.form for å finne hva som er lagret i skjemaet. For å bli vant med det, så anbefales å skrive det ut.

Vi kan så gjengi den samme eller en annen html-fil. Vi kan også legge til tekst som kommer på denne siden.

@app.route('/predict', methods=['POST'])
def predict():
    # get data
    features = dict(request.form)  
    print(features)
    
    # render with new prediction_text
    return render_template(
        './index.html',
        prediction_text='Predicted price ...')

I så fall må det stå {{prediction_text}} i html-filen som plassholder for det som vi angir i python-koden. Denne koden bare gir tilbake «Predicted price …», så for å faktisk lage en prediksjon må vi ha noe kode mellom der features blir lest inn og der vi avslutter funksjonen. Her kommer kode for å sjekke at innput gir mening, forberedelse av data for modellen, imputering av data og prediksjon.

Vi avslutter vår app.py ved å faktisk servere appen. Her bruker vi argumentene host for å spesifisere navn eller ip addressen. I kurset bruker vi kun '0.0.0.0' som gjør at nettsiden kun kjøres lokalt. I tillegg angir vi en TCP port. Det kan være at dere må endre den for å ungå problemer med brannmuren.

if __name__ == '__main__':
    serve(app, host='0.0.0.0', port=8080)

Så kan vi kjøre nettsiden ved å kjøre

python app.py

i en shell og gå til http://localhost:8080/ i en nettleser. Hvis vi har skrevet ut noe med print, så dukker dette opp i shell. For et enkelt eksempel se simpleapp.py og for et komplett eksempel se app.py i huspris_app.