Commit d9f69c57 authored by Federico Mestrone's avatar Federico Mestrone
Browse files

Query in Datalab should not SELECT all fields

parent 2740bd6f
%% Cell type:markdown id: tags:
<h1>Analisi di dati con BigQuery</h1>
In questa demo e nella successiva svilupperemo un modello di machine learning per predirre la richiesta di taxi in New York, utilizzando dei dati pubblici messi a disposizione del governo della città e dalle stazioni metereologiche statunitensi. Questi dati sono riportati in tabelle di BigQuery cui chiunque può avere accesso.
Abbiamo tre obiettivi principali in questa demo
1) imparare a utilizzare BigQuery, scrivere query SQL sofisticate, capire come le query che scriviamo hanno impatto sui costi
2) fare un po' di pratica con Datalab, stabilire quando e per cosa si possa utilizzare, imparare i comandi per creare e gestire le istanze
3) farsi un'idea del processo di analisi prelimare dei dati per stabilire le correlazioni da approfondire con il Machine Learning
Non si può diventare esperti di ML in cinque minuti, ma speriamo di darvi una buona introduzione e stimolarvi a volerne sapere di più!
%% Cell type:code id: tags:
``` python
# importiamo le librerie necessarie per utilizzare BigQuery in Python e per la manipolazione avanzata dei dati in Python
import google.datalab.bigquery as bq
import pandas as pd # Pandas (strutture dati avanzate per l'analisi)
import numpy as np # NumPy (libreria per calcoli scientifici)
import shutil # operazioni su file e gruppi di file
```
%% Cell type:code id: tags:
``` python
%bq tables describe --name bigquery-public-data.new_york.tlc_yellow_trips_2015
# vediamo la struttura della tabella che utilizzeremo nel resto del notebook
```
%% Cell type:markdown id: tags:
<h2> Analisi della richiesta di taxi per giorno </h2>
Ora usiamo SQL in BigQuery per ottenere la domanda totale di taxi ogni giorno dell'anno nel 2015. Cominciamo con l'estrazione del giorno dell'anno dalla data di inizio di ogni viaggio.
%% Cell type:code id: tags:
``` python
%bq query
# la funzione EXTRACT tira fuori parti specifiche di una data dal valore passato come parametro
# in questo caso noi prendiamo solo il giorno dell'anno
SELECT
EXTRACT (DAYOFYEAR from pickup_datetime) AS daynumber # minimizzare i costi restituendo solo i valori che servono
FROM `bigquery-public-data.new_york.tlc_yellow_trips_2015`
LIMIT 15 # limitare il numero di risultati non diminuisce il costo della query
```
%% Cell type:markdown id: tags:
Ora che abbiamo l'elenco dei giorni, calcoliamo il totale di viaggi in taxi effettuati ogni giorno.
Utilizzeremo una query con nome in Datalab, che ci consente di passare il valore di uno o più parametri e di riutilizzare la query più volte.
Nel nostro caso la query prenderà l'anno come input e calcola il totale di viaggi per ogni giorno di quell'anno.
%% Cell type:code id: tags:
``` python
%bq query -n taxiquery
# l'opzione -n crea una query con nome utilizzabile in Python come funzione
WITH trips AS ( # WITH trips : crea una view temporanea utilizzabile in questo comando
SELECT EXTRACT (DAYOFYEAR from pickup_datetime) AS daynumber
FROM `bigquery-public-data.new_york.tlc_yellow_trips_*` # tabella partizionata per anno
where _TABLE_SUFFIX = @YEAR # variabile speciale utlizzata con tabelle partizionate
)
SELECT daynumber, COUNT(1) AS numtrips FROM trips # utilizza la view creata prima
GROUP BY daynumber ORDER BY daynumber
```
%% Cell type:code id: tags:
``` python
# prepara il parametro YEAR per la query con nome
query_parameters = [
{
'name': 'YEAR',
'parameterType': {'type': 'STRING'},
'parameterValue': {'value': 2015}
}
]
# invoca la query con nome e transforma il risultato in un dataframe di Pandas
trips = taxiquery.execute(query_params=query_parameters).result().to_dataframe()
# mostra solo i primi 15 risultati del dataframe
trips[:15]
```
%% Cell type:markdown id: tags:
<h2> Dati sul tempo </h2>
Abbiamo il sospetto che il tempo possa influenzare l'utilizzo dei taxi. Magari in un giorno di pioggia o quando fa particolarmente freddo le persone che normalmente andrebbero a piedi preferiscono prendere un taxi...
Con BigQuery possiamo unire e combinare le informazioni da qualunque fonte che il prodotto sia in grado di leggere e a cui - ovviamente - abbiamo accesso, inlcusi dati federati o in altri progetti.
%% Cell type:code id: tags:
``` python
%bq tables describe --name bigquery-public-data.noaa_gsod.stations
# vediamo la struttura della tabella che contiene l'elenco delle stazioni metereologiche
```
%% Cell type:code id: tags:
``` python
%bq tables describe --name bigquery-public-data.noaa_gsod.gsod2015
# e la struttura della tabella con i dati metereologici di ciascuna stazione
```
%% Cell type:code id: tags:
``` python
%bq query
# Prendiamo i dati di tutte le stazioni metereologiche di New York nella zone dell'aeroporto di La Guardia
SELECT * FROM `bigquery-public-data.noaa_gsod.stations`
SELECT usaf FROM `bigquery-public-data.noaa_gsod.stations` # limita i campi restituiti per ridurre la quantità di dati processati
WHERE state = 'NY' AND wban != '99999' AND name LIKE '%LA GUARDIA%' # troviamo la stazione che ci serve poi limitiamo le query successive per minimizzare i costi
```
%% Cell type:markdown id: tags:
Ora che abbiamo trovato la stazione metereologica di La Guardia, andiamo a raccogliere la temperature minima e massima e la quantità di pioggia per i vari giorni dell'anno.
%% Cell type:code id: tags:
``` python
%bq query -n wxquery
# -n per una query con nome
SELECT EXTRACT (DAYOFYEAR FROM CAST(CONCAT(@YEAR,'-',mo,'-',da) AS TIMESTAMP)) AS daynumber, # calcola il giorno dell'anno
EXTRACT (DAYOFWEEK FROM CAST(CONCAT(@YEAR,'-',mo,'-',da) AS TIMESTAMP)) AS dayofweek, # calcola il giorno della settimana
`min` AS mintemp, `max` AS maxtemp, IF(prcp=99.99,0,prcp) AS rain # backtick per chiarezza (min e max sono anche nomi di funzioni)
FROM `bigquery-public-data.noaa_gsod.gsod*` # tabella partizionata con wildcard - il backtick è obbligatorio qui!
WHERE stn='725030' AND _TABLE_SUFFIX = @YEAR # variabile speciale per il suffisso (_TABLE_SUFFIX) e parametro della query con nome (@YEAR)
ORDER BY daynumber DESC
```
%% Cell type:code id: tags:
``` python
# prepara il parametro YEAR per la query con nome
query_parameters = [
{
'name': 'YEAR',
'parameterType': {'type': 'STRING'},
'parameterValue': {'value': 2015}
}
]
# invoca la query con nome e transforma il risultato in un dataframe di Pandas
weather = wxquery.execute(query_params=query_parameters).result().to_dataframe()
# mostra solo i primi 15 risultati del dataframe
weather[:15]
```
%% Cell type:markdown id: tags:
<h2> Unire i dati </h2>
Con Pandas possiamo prendere le due dataframe create in precedenza e unirle, utilizzando il giorno dell'anno come punto di unione. Il concetto è simile a quello di una JOIN in SQL.
%% Cell type:code id: tags:
``` python
# metti insieme le informazioni sul tempo con quelle sui viaggi in taxi, utilizzando il giorno dell'anno come collante
data = pd.merge(weather, trips, on='daynumber')
# mostra i primi 15 risultati
data[:15]
```
%% Cell type:markdown id: tags:
Ora che abbiamo messo insieme i dati metereologici con quelli sui viaggi in taxi, vediamo se troviamo delle correlazioni evidenti che meritino di essere approfondite e che possono aiutarci a creare un modello di previsione per la domanda di taxi in determinati giorni.
Cominciamo col disegnare un grafico di viaggi in relazione alla temperatura massima...
Pandas ha una funzione "plot" che fa esattamente quello che ci serve adesso.
%% Cell type:code id: tags:
``` python
j = data.plot(kind='scatter', x='maxtemp', y='numtrips')
```
%% Cell type:markdown id: tags:
Anche se il grafico ha molta dispersione e non si possono raggiungere conclusioni definitive, possiamo comunque notare una certa tendenza, quindi decidiamo di utilizzare le informazioni metereologiche come correlatore per determinare il numero di viaggi in taxi in una giornata.
Proviamo a vedere se c'è una relazione tra numero di viaggi e giorno della settimana.
%% Cell type:code id: tags:
``` python
j = data.plot(kind='scatter', x='dayofweek', y='numtrips')
```
%% Cell type:markdown id: tags:
Sembra che qui ci sia un pattern più chiaro. La gente usa i taxi di più verso la fine della settimana. Potrebbe avere a che fare con il turismo, o con il desiderio di essere più comodi man mano che la stanchezza della settimana lavorativa si fa sentire... ma possiamo dire che sicuramente venerdì, sabato e domenica il numero di viaggi in taxi è maggiore.
Proviamo ancora una cosa! Fissiamo il giorno della settimana, e vediamo se tolto quel fattore, notiamo delle correlazioni più chiare tra temperatura e viaggi in taxi...
%% Cell type:code id: tags:
``` python
j = data[data['dayofweek'] == 7].plot(kind='scatter', x='maxtemp', y='numtrips')
```
%% Cell type:markdown id: tags:
Il un grafico è ancora non molto definitivo, ma parrebbe esserci una più stretta relazione vista così. Decidiamo pertanto di utilizzare anche il giorno della settimana come correlatore per determinare il numero di viaggi in taxi in una giornata.
%% Cell type:markdown id: tags:
Tenete a mente queste due decisioni che abbiamo preso in questa demo, perché ne riparleremo nella prossima!
%% Cell type:markdown id: tags:
<em>Copyright 2019 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License</em>
%% Cell type:code id: tags:
``` python
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment