La Digitalizzazione dei Musei nel Lazio, solo il 62% ha un sito web

L’altro giorno su HackerNews se si cercavano le notizie relative all’Italia, oltre ai nostri problemi con la manovra di bilancio, c’era un articolo del NYTimes sul più antico ritrovamento preistorico in Italia, conservato presso il Museo di Preistoria della Sapienza (Non sapevo dell’esistenza di questo museo se non fosse stato per Giorgia).

Partendo dalla lettura di questo articolo ho voluto investigare gli open data relativi ai musei del Lazio.

Dati che potete consultare liberamente in forma tabulare sul sito della Regione(qui il link).

I dati sono legati al censimento nazionale dei musei d’Italia voluto dal Ministero dei Beni e Attività Culturali, Istat e Regioni aderenti, il censimento riguarda il periodo che intercorre il 2011-2014, ma il dataset è stato creato solo il 26 Dicembre 2016.

Photo by Dario Veronesi on Unsplash

Nel Lazio ci sono almeno 357 Musei, se volessimo visitarne 1 al giorno non basterebbe 1 anno, anche perché non tutti hanno un sito web, quindi sarebbe necessaria  una attenta pianificazione.

Già.

Nel 2018 chi lo avrebbe mai detto.

Questa informazione è racchiusa in una colonna del dataset che contiene proprio l’url di ogni sito museale.

Su 357 solo 222 musei nel Lazio hanno un sito web, il 62% del totale.

Inoltre di questi non è possibile sapere quanti siano mobile-friendly (realmente) e quanti abbiano una sezione in lingua inglese.

Se cercate il Museo Archeologico Nazionale di Formia sarete indirizzati ad una sezione del sito del Ministero per i Beni e le Attività Culturali e selezionando la lingua inglese vi comparirà questo:

Il nulla.

Ovviamente anche il Museo della Sapienza, che conserva il reperto citato dal New York Times, è sprovvisto di una sezione in lingua inglese (o se dovesse esserci non è di facile individuazione), qui il link al sito del museo.

E’ un peccato, un vero peccato, visto che c’è sempre qualcuno pronto ad affermare che la nostra vocazione è il turismo, la cultura e la creatività.

Diagnosi del dataset:

  • Dovrebbe essere aggiornato
  • Sarebbe utile integrare queste informazioni con
    • Il numero di ingressi
    • Il prezzo del biglietto intero
    • Le entrate per l’anno di riferimento (comprensive degli affitti dei bar/gadget ecc…)
    • Se il museo accetta o meno prenotazioni on-line
    • Il numero di lingue del sito e delle audio-guide(se presenti) all’interno del museo

Di seguito come sempre viene allegato il codice Python utilizzato per la pulizia e visualizzazione dei dati 🙂

Grazie per aver letto l’articolo! 

Se ti è piaciuto o lo ritieni utile per informare degli amici su questo problema condividilo liberamente, se c’è qualche errore o miglioramento scrivimi pure 🙂

Un abbraccio

Andrea

 

In [1]:
#Importiamo i moduli necessari
#per il lavoro di visualizzazione
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
In [2]:
path_csv='elencomusei20142.csv'
museum_csv=pd.read_csv(path_csv)
print(museum_csv.info())
print(museum_csv.columns)
print(museum_csv['Q1.11_SA_SITO WEB_MUSEO_ISTITUTO'].head(3))
#Dopo aver visualizzato le info del dataframe
#possiamo identificare le colonne di interesse
#per la nostra analisi
webcolumn='Q1.11_SA_SITO WEB_MUSEO_ISTITUTO'
museum_name='Q1.1_SA_DENOMINAZIONE_MUSEO_ISTITUTO'
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 357 entries, 0 to 356
Data columns (total 19 columns):
Comune                                        357 non-null object
Provincia                                     357 non-null object
Statale ƒ?? Non statale                       357 non-null object
OMR                                           161 non-null object
Sistema museale territoriale                  48 non-null object
Sistema museale urbano                        33 non-null object
Sistema museale tematico                      82 non-null object
Casa museo                                    12 non-null object
Q1.1_SA_DENOMINAZIONE_MUSEO_ISTITUTO          357 non-null object
Q1.2_SA_INDIRIZZO_MUSEO_ISTITUTO              353 non-null object
Q1.3_SA_LOCALITA_MUSEO_ISTITUTO               321 non-null object
Q1.4_SA_UBICAZIONE/EDIFICIO_MUSEO_ISTITUTO    344 non-null object
Cap                                           356 non-null float64
Q1.8_SA_TELEFONO_MUSEO_ISTITUTO               352 non-null object
Q1.9_SA_FAX_MUSEO_ISTITUTO                    328 non-null object
Q1.10_SA_EMAIL_MUSEO_ISTITUTO                 349 non-null object
Q1.11_SA_SITO WEB_MUSEO_ISTITUTO              344 non-null object
latitudine                                    357 non-null float64
longitudine                                   357 non-null float64
dtypes: float64(3), object(16)
memory usage: 53.1+ KB
None
Index(['Comune', 'Provincia', 'Statale ƒ?? Non statale', 'OMR',
       'Sistema museale territoriale', 'Sistema museale urbano',
       'Sistema museale tematico', 'Casa museo',
       'Q1.1_SA_DENOMINAZIONE_MUSEO_ISTITUTO',
       'Q1.2_SA_INDIRIZZO_MUSEO_ISTITUTO', 'Q1.3_SA_LOCALITA_MUSEO_ISTITUTO',
       'Q1.4_SA_UBICAZIONE/EDIFICIO_MUSEO_ISTITUTO', 'Cap',
       'Q1.8_SA_TELEFONO_MUSEO_ISTITUTO', 'Q1.9_SA_FAX_MUSEO_ISTITUTO',
       'Q1.10_SA_EMAIL_MUSEO_ISTITUTO', 'Q1.11_SA_SITO WEB_MUSEO_ISTITUTO',
       'latitudine', 'longitudine'],
      dtype='object')
0       www.simulabo.it
1    www.ecomuseocrt.it
2                     -
Name: Q1.11_SA_SITO WEB_MUSEO_ISTITUTO, dtype: object
In [3]:
#Dobbiamo rimuovere gli spazi vuoti ed il carattere '-'
#Così successivamente
#Possiamo rimuovere 
#tutte le righe con una cella vuota all'interno 
#della colonna contenente la lista dei siti web
museum_csv[webcolumn]=museum_csv[webcolumn].str.strip('-')
museum_csv[webcolumn]=museum_csv[webcolumn].str.strip('')
In [4]:
#Esploriamo le prime 10 righe 
#della colonna con i siti web
#per capire come è fatta
print(museum_csv[webcolumn][:10])
0                                      www.simulabo.it
1                                   www.ecomuseocrt.it
2                                                     
3                     www.comlogpro.esercito.difesa.it
4                   www.sviluppoeconomico.gov.it/museo
5               htpp://www.archeoroma.beniculturali.it
6                              www.museicapitolini.org
7                                                     
8                            www.museocriminologico.it
9    www.sangiovannideifiorentini.net/index.php/museo/
Name: Q1.11_SA_SITO WEB_MUSEO_ISTITUTO, dtype: object
In [5]:
#Sostituiamo gli spazi vuoti con Nan
#In questo modo sarà possibile "droppare" queste righe
museum_csv[webcolumn]=museum_csv[webcolumn].replace('', np.nan)
print(museum_csv.info())
museum_csv_dn=museum_csv.dropna(subset=[webcolumn])
print(museum_csv_dn.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 357 entries, 0 to 356
Data columns (total 19 columns):
Comune                                        357 non-null object
Provincia                                     357 non-null object
Statale ƒ?? Non statale                       357 non-null object
OMR                                           161 non-null object
Sistema museale territoriale                  48 non-null object
Sistema museale urbano                        33 non-null object
Sistema museale tematico                      82 non-null object
Casa museo                                    12 non-null object
Q1.1_SA_DENOMINAZIONE_MUSEO_ISTITUTO          357 non-null object
Q1.2_SA_INDIRIZZO_MUSEO_ISTITUTO              353 non-null object
Q1.3_SA_LOCALITA_MUSEO_ISTITUTO               321 non-null object
Q1.4_SA_UBICAZIONE/EDIFICIO_MUSEO_ISTITUTO    344 non-null object
Cap                                           356 non-null float64
Q1.8_SA_TELEFONO_MUSEO_ISTITUTO               352 non-null object
Q1.9_SA_FAX_MUSEO_ISTITUTO                    328 non-null object
Q1.10_SA_EMAIL_MUSEO_ISTITUTO                 349 non-null object
Q1.11_SA_SITO WEB_MUSEO_ISTITUTO              222 non-null object
latitudine                                    357 non-null float64
longitudine                                   357 non-null float64
dtypes: float64(3), object(16)
memory usage: 53.1+ KB
None
<class 'pandas.core.frame.DataFrame'>
Int64Index: 222 entries, 0 to 355
Data columns (total 19 columns):
Comune                                        222 non-null object
Provincia                                     222 non-null object
Statale ƒ?? Non statale                       222 non-null object
OMR                                           102 non-null object
Sistema museale territoriale                  29 non-null object
Sistema museale urbano                        28 non-null object
Sistema museale tematico                      42 non-null object
Casa museo                                    7 non-null object
Q1.1_SA_DENOMINAZIONE_MUSEO_ISTITUTO          222 non-null object
Q1.2_SA_INDIRIZZO_MUSEO_ISTITUTO              220 non-null object
Q1.3_SA_LOCALITA_MUSEO_ISTITUTO               194 non-null object
Q1.4_SA_UBICAZIONE/EDIFICIO_MUSEO_ISTITUTO    214 non-null object
Cap                                           221 non-null float64
Q1.8_SA_TELEFONO_MUSEO_ISTITUTO               219 non-null object
Q1.9_SA_FAX_MUSEO_ISTITUTO                    204 non-null object
Q1.10_SA_EMAIL_MUSEO_ISTITUTO                 217 non-null object
Q1.11_SA_SITO WEB_MUSEO_ISTITUTO              222 non-null object
latitudine                                    222 non-null float64
longitudine                                   222 non-null float64
dtypes: float64(3), object(16)
memory usage: 34.7+ KB
None
In [6]:
#Adesso possiamo conoscere
#Quanti musei hanno un sito web
#e quanti sono sprovvisti
l_web_site=len(museum_csv_dn[webcolumn])
l_all=len(museum_csv[webcolumn])
l_without=l_all-l_web_site
print('Museum with a website',l_web_site)
print('Museum without a website',l_without)
print('Total museum',l_all)
print("Museums With a WebSite",round(l_web_site/l_all*100),'%')
print("Museums Without a WebSite",round(l_without/l_all*100),'%')
Museum with a website 222
Museum without a website 135
Total museum 357
Museums With a WebSite 62 %
Museums Without a WebSite 38 %
In [7]:
#Creiamo una "mask" 
#per filtare il dataframe
#e salvare una lista csv
#con tutti i musei senza sito web
mask=(museum_csv[webcolumn].isna())
save=museum_csv[mask].to_csv('muslazionositoweb.csv')
In [8]:
#In questa sezione rappresentiamo 
#con un bar plot i musei in valore assoluto
n=3
x_variable=np.arange(1,n+1)
y_variable=[l_without,l_web_site,l_all]
color=['red','Crimson','DarkBlue']
fig, ax=plt.subplots()
for i in range(n):
    plt.bar(x_variable[i],y_variable[i], color=color[i])
fig.suptitle('Musei nel Lazio e Digitalizzazione (Agg. Dati 2016)', fontsize=18)

#Qui definiamo il font degli assi e le etichette 
plt.xticks(np.arange(1,n+1), ('Musei Senza Sito Web', 'Musei Con Sito Web',"Totale Musei"), rotation=55)
plt.yticks(np.arange(0, max(y_variable)+100, 200))

plt.tick_params(axis='both', which='major', labelsize=20)
for i, v in enumerate(y_variable):
    ax.text(i+0.9, v+10 , str(v), color='Blue', fontsize=12, fontweight='bold')
#Questa sezione è per aggiungere una filigrana al plot
plt.text(2, 10, 'Elaborazione Dati: Ing. Andrea Ciufo. Fonte: Regione Lazio Open Data',
         fontsize=11, color='gray',
         ha='center', va='bottom', alpha=0.9)
  
plt.show()
In [9]:
#In questa sezione rappresentiamo 
#con un bar plot i musei in valore %
m=2
x_variable=np.arange(1,m+1)
y_variable=[round(l_without/l_all,2),round(l_web_site/l_all,2)]
color=['red','DarkBlue']
fig, ax=plt.subplots()
for i in range(m):
    plt.bar(x_variable[i],y_variable[i], color=color[i])
fig.suptitle('Musei nel Lazio e Digitalizzazione (Agg. Dati 2016)', fontsize=18)


#Qui definiamo il font degli assi e le etichette 
plt.xticks(np.arange(1,m+1), ('Musei Senza Sito Web', 'Musei Con Sito Web'), rotation=55)
plt.yticks(np.arange(0,2))
plt.tick_params(axis='both', which='major', labelsize=20)
for i, v in enumerate(y_variable):
    ax.text(i+0.9, v+0.01 , str(v)+'%', color='Blue', fontsize=12, fontweight='bold')
    
#Questa sezione è per aggiungere una filigrana al plot    
plt.text(1.5,0.05, 'Elaborazione Dati: Ing. Andrea Ciufo. Fonte: Regione Lazio Open Data',
         fontsize=11, color='gray',
         ha='center', va='top', alpha=0.9)
  
plt.show()
Annunci

Lascia un commento

Archiviato in riflessioni, Tecnologia

Nove principi per valutare le stime e i sondaggi basati sulle intenzioni, con bibliografia e 35 anni di studi citati

Mentre stavo realizzando un piccolo modello predittivo e cercavo delle conferme teoriche su determinate ipotesi ho scoperto un libro estremamente valido e con una ricca bibliografia. “Principles Of Forecasting: A Handbook for Researchers and Practitioners” curato da J. Scott Armstrong, della Wharton School.

Il manuale affronta tutti i modelli decisionali da quelli basati sul giudizio(Esperti, Sondaggi) a quelli statistici basati su modelli Econometrici, Multivariati ed applicazioni delle reti neurali.

Sono oltre 600 pagine dense di contenuti ed ogni capitolo è curato da un professore diverso.

Photo by Markus Spiske on Unsplash

Questo post è una sintesi di uno dei capitoli che ho letto e che mi ha fatto riflettere. Riflessioni nate dall’assiduo utilizzo e lettura di indagini/ricerche sull’indice di gradimento dei clienti/utilizzatori, ad esempio quest’anno ne abbiamo  realizzato  uno con Mosiello (un alumno di InnovAction Lab) per valutare e migliorare il BBQ Annuale di InnovAction Lab.

Il capitolo “Methods For Forecasting From Intentions Data” è stato realizzato da Vicki G. Morwitz, della New York University. 

Andando per gradi è necessario  definire il termine “Intenzioni” per avere un linguaggio comune.

Esistono tante definizioni, ma per l’obiettivo di questo post e in coerenza con il libro utilizzerò la seguente:

Le Intenzioni sono una misura. Nello specifico rappresentano il grado di possibilità degli individui di realizzare dei piani, obiettivi o aspettative nel futuro. Spesso le intenzioni sono utilizzate per stimare cosa le persone faranno nel futuro.

Morwitz ha sviluppato nove principi sui quali basare le decisioni basandosi sulle informazioni acquisite sulle intenzioni dei consumatori.

Morwitz evidenzia inoltre che anche nel rispetto dei nove principi è sempre necessario essere estremamente cauti quando si effettuano delle stime sui dati intenzionali.

I nove principi sviluppati dall’autore rispondono alle seguenti domande:

  1. Come dovrebbero essere misurate le intenzioni?
  2. Le intenzioni come dovrebbero essere utilizzate per stimare e predire i comportamenti?
  3. Come si devono adeguare ed adattare le intenzioni quando si deve stimare un comportamento?
  4. Quando le intenzioni e preferenze dichiarate devono essere utilizzate per stimare e predire un comportamento?
  5. Perché può capitare che le intenzioni siano delle misure incoerenti con l’effettivo comportamento?”

 

  1. Come dovrebbero essere misurate le intenzioni?

    • Utilizzando una scala di probabilità  invece di altre possibili classificazioni (Primo Principio)
    • E’ necessario spiegare agli intervistati di essere estremamente coerenti con quelle che sono le loro effettive caratteristiche personali e di rispondere al sondaggio in funzione di quello che si vorrebbe (il classico esempio è l’intenzione ad avere una Ferrari e l’effettiva possibilità economica di acquistarla) (Secondo Principio)
  2. Le intenzioni come dovrebbero essere utilizzate per stimare e predire i comportamenti?

    1. Se possibile, le “Intenzioni” misurate non andrebbero utilizzate così come collezionate, ma andrebbero sottoposte ad un processo di rettifica. Ad esempio se le intenzioni sono valutate utilizzando una scala di probabilità un metodo semplice di stima della percentuale di persone che acquisterebbero può essere definito come la probabilità media di acquisto tra gli intervistati.  (Terzo Principio) In generale alcune ricerche hanno rilevato che la probabilità di acquisto per beni durabili è spesso sottostimata rispetto al numero di acquisti effettivi * Gli studi di  Bird and Ehrenber hanno evidenziato un fenomeno inverso per i beni non durevi: la sovrastima nell’intenzione. **
  3. Come si devono adeguare ed adattare le intenzioni quando si deve stimare un comportamento?

    1. Si possono utilizzare i dati dei sondaggi passati e con quei risultati  adeguare i dati intenzionali oggetto dello studio recente(Quarto Principio)
      1. Comportamento Effettivo(t)=Valore medio delle Intenzioni (t-1) + Bias(t-1,t)
      2. Bias(t-1,t)=Comportamento Effettivo(t) -Valore medio delle Intenzioni (t-1)
      3. Comportamento Effettivo (t+1)= Valore medio delle Intenzioni(t) + Bias(t-1,t)
        • (t -1) è il tempo in cui è stato effettuato il precedente sondaggio
        • (t) è il tempo in cui è stato somministrato l’attuale sondaggio sul quale si prenderanno delle decisioni o si effettueranno delle analisi di previsione, è inoltre il tempo in cui si rileva l’effettivo comportamento rispetto alle intenzioni espresse al tempo (t-1)
        • (t+1) è il tempo in cui si realizzeranno i comportamenti espressi attraverso le intenzioni al tempo (t)
        • Il Bias, l’errore, commesso/presente al tempo (t-1) è funzione del comportamento effettivo al tempo t
    2. Attraverso una fase di segmentazione e classificazione degli intervistati prima di adeguare/adattare le intenzioni  (Quinto Principio)
      • Morwitz e Schmittlein hanno analizzato nel dettaglio il punto precedente, dividendo gli intervistati in chi era intenzionato ad acquistare e chi non era intenzionato
      • Gli autori dai loro studi hanno appurato che segmentando gli intervistati attraverso dei metodi nei quali venivano identificate le variabili dipendendi (Criterion) ed indipendenti (Predictor) si  determinava un errore minore nelle stime rispetto a quelle effettuate per valori aggregati. Nel caso specifico hanno analizzato in diverse famiglie la propensione ad acquistare un’auto in un test ed in un altro test un PC. La segmentazione degli intenzionati e non intenzionati è stata molto sofisticata (lo studio è del 1992) e non si sono accontentati di un solo metodo, ma ne hanno valutati diversi, alcuni molto noti a tutti gli appassionati di DataScience a Analytics:
        1. Segmentazione per reddito
        2. Clusterizzazione K-Means su dati demografici e variabili legate all’uso del prodotto
        3. Analisi discriminante  dove l’acquisto era stato predetto sulla base di alcune demografiche e variabili di utilizzo del prodotto
        4. CART (Classification And Regression Trees), la predizione dell’acquisto era funzione di  informazioni demografiche, variabili di utilizzo del prodotto ed altre variabili indipendenti
      • Citando il paper presente nel capitolo del libro: “The main empirical finding is that more accurate sales forecasts appear to be obtained by applying statistical segmentation methods that distinguish between dependent and independent variables (e.g., CART, discriminanatn analysis) than by applying simpler directc clustering  approaches( e.g., a priori segmentation or K-means clustering)“****
        • Le variabili indipendenti (Predictors) identificate nello studio di Morwitz e Schmittlein

           

    3. Utilizzare le misure sulle intenzioni per definire i confini/limiti della probabilità di acquisto(Sesto Principio).
      • Quando è necessario valutare lo scenario migliore o peggiore gli autori evidenziano che è possibile utilizzare i valori estremi delle intenzioni misurate dai sondaggi
  4. Quando le intenzioni e preferenze dichiarate devono essere utilizzate per stimare e predire un comportamento?

    1. Secondo gli studi di Armstrong ci sono sei condizioni tali per cui è possibile che le intenzioni dichiarate siano coerenti con l’effettivo comportamento(Settimo Principio)***
      1. “Il comportamento previsto è importante
      2. Le risposte sono state rilasciate da chi prenderà la decisione
      3. L’intervistato ha un piano
      4. L’intervistato descrive con precisione il piano (al contrario dell’intervistato che afferma che “E’ riservato non posso dirtelo”,  racconta il piano in modo confuso o il piano non è coerente con le attitudini di chi lo sta raccontando)
      5. L’intervistato può rispettare e realizzare il piano
      6. Nuove informazioni aggiuntive non sono in grado di modificare il piano nell’orizzonte di previsione”***
  5. Perché può capitare che le intenzioni siano delle misure incoerenti con l’effettivo comportamento?

    • Misurare le intenzioni modifica i comportamenti. Morwitz, Johnson e Schmittlein in uno studio hanno selezionato due campioni che avrebbero dovuto acquistare un’auto. Di un campione è stata misurata la propensione all’acquisto, del secondo no. Il risultato è stato che il gruppo in cui le intenzioni (positive all’acquisto) sono state misurate aveva una tendenza maggiore ad acquistare una macchina. La spiegazione è sul piano cognitivo, perchè nel momento del sondaggio nell’intervistato si innesca un processo che Goleman nel suo libro “Intelligenza Emotiva” (estremamente consigliato per tutti lo trovate a questo link) chiamerebbe “metacognizione”(Ottavo Principio)
    • Spesso l’uomo è affetto da alcune distorsioni percettive quando deve ricordare il momento del suo ultimo acquisto(Nono Principio). Se questo bias/distorsione è presente nei songaggi si possono determinare delle stime e predizioni distorte, è importante identificarlo per associare un grado di incertezza alle predizioni. Il nono ed ultimo principio è frutto degli studi di Kalwani e Silk.

Ho trovato questi principi estremamente utili, interessanti, alcuni di rapida applicazione in particolare i primi, altri invece più complessi e da approfondire.

Voi?

Se ti è piaciuto o lo trovi utile ricondividilo liberamente o clicca “Mi Piace”, con pochi click si può fare tanto, se pensi meriti delle correzioni, typo, o si possa migliorare scrivimi pure. 🙂

Grazie per aver letto l’articolo!

Andrea

*(Juster 1966 “Consumer buying intentions and purchase probability: An experiment in survey design”, McNeil 1974, “Federal programs to measure consumer purchase expectaions”)

**(Bird, Ehrenberg 1966 “Intentions-to-buy and claimed brand usage”)

***(Armstrong, Long-Range Forecasting , pag 83)

****(Vicki G. Morwitz and David Schmittlein,Nov., 1992, “Using Segmentation to Improve Sales Forecasts Based on Purchase Intent: Which “Intenders” Actually Buy?”)

*****(Silk Urban, “Pre-Test-Market Evaluation of New Packaged Goods: A Model and Measurement
Methodology”,Journal of Marketing Research, Vol. 15, No. 2. (May, 1978), pp. 171-191.)

 

Lascia un commento

Archiviato in riflessioni, Scritti sparsi, Startup

Quali sono i farmaci più venduti in Italia? Quelli per i quali è prevista la pubblicità

I Farmaci più venduti in Italia sono i farmaci per i quali è prevista la pubblicità.

I Farmaci senza obbligo di ricetta sul sito del Ministero della Salute sono divisi in OCT e SOP:

  • Senza Obbligo di Prescrizione
  • Overt The Counter o farmaci da banco o farmaci di automedicazione per i quali è prevista la
    pubblicità

Dati alla mano del Ministero della Salute se si puliscono un po’ è possibile realizzare un grafico  dove in blu ho rappresentati i SOP ed in Rosso gli OTC.

Ad essere rigorosi si deve parlare di “distribuzione” dei farmaci perchè questo è il titolo riportato sulla descrizione del dataset, ma questo valore è strettamente correlato con la vendita.

Aggregando le due categorie e sommando per categoria le “Quantità confezioni fornite alle farmacie ed agli esercizi commerciali” si  ottiene che, nel primo semestre 2016*:

Sono 30,3 Milioni le confezioni di farmaci OTC distribuite contro i 12,6 Milioni di confezioni SOP

Mi scuso se non ho formattato adeguatamente l’asse del y, è espresso come potenza di 10^7 (quindi 3*10^7= 30Milioni)

 

Sulla base di questi risultati mi sento di scrivere tre affermazioni:

  • I medicinali equivalenti sono poco utilizzati, nonostante l’obbligo del farmacista nel momento dell’acquisto di evidenziare la possibilità di questa scelta
  • Potrebbe esserci un consumo eccessivo di medicinali con ricadute sulla salute legato alla pubblicità e non ad un confronto corretto con il proprio medico di base, ma non sono un medico questa è un valutazione che va oltre le mie competenze
  • E’ importante per permettere una analisi più corretta che vengano pubblicati
    • I Dati più recenti relativi al 2017 e 2018
    • I dati relativi ai farmaci equivalenti per valutare eventuali correlazioni e confronti, anche se non sono tra i 50 più venduti

Per onestà intellettuale ho scritto al Ministero, sia per chiedere un aggiornamento del dataset sia per avere informazioni sui farmaci equivalenti, se dovesse esserci una risposta vi aggiornerò.

 

Di seguito trovate invece tutto il lavoro svolto in Python per la selezione, analisi e visualizzazione dei dati a partire dal dataset originale.

In particolare successivamente all’aggregazione tramite metodo groupby in pandas del dataframe ho aggiunto una colonna che avesse come label la “Modalità e Prescrizione” del farmaco.

Questa colonna è stata aggiunta attraverso  una unione (merge) con un dataframe contenente solo la lista unica dei Farmaci e la  “Modalità di Prescrizone” che avevo estratto dal dataframe originario.

Grazie per aver letto l’articolo!

Se ti è piaciuto o lo trovi utile ricondividilo, se pensi meriti delle correzioni scrivimi pure 🙂

Un abbraccio 

Andrea

In [1]:
# Import pandas
import pandas as pd

import numpy as np
# Import plotting modules
import matplotlib.pyplot as plt

import re
file_name='C_17_dataset_15_download_itemDownload_0_upFile.csv'
csv=pd.read_csv(file_name,sep=';',encoding="ISO-8859-1",skiprows=1)
csv.info()
#Visualizzo il titolo dei farmaci
#Questo è necessario per il successivo
#processo di pulizia e aggregazione 
csv_mod=csv.dropna().copy()
csv_mod['Farmaco']=None
#Un prodotto Rinazina aveva ** ad inizio stringa perchè il ministero doveva confermare il dato
#per comodità ho rimosso ** 
csv_mod['Denominazione della confezione']=csv_mod['Denominazione della confezione'].str.replace('*','')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 52 entries, 0 to 51
Data columns (total 6 columns):
N°                                                                        51 non-null object
Codice Autorizzazione all'Immissione in Commercio
(AIC)                   50 non-null float64
Denominazione della confezione                                            50 non-null object
Fascia PTN                                                                50 non-null object
Modalità
Prescrizione                                                     50 non-null object
Quantità confezioni fornite alle farmacie ed agli esercizi commerciali    50 non-null object
dtypes: float64(1), object(5)
memory usage: 2.5+ KB
In [2]:
#Aggiungiamo la colonna Farmaco al nostro DataFrame
csv_mod['Farmaco']=None
def primaparola(colonna_di_testo):
    
    pattern=r'\W*(\w[^,. !?"]*)'
    return re.match(pattern,colonna_di_testo).group()


estratto=csv_mod['Denominazione della confezione'].apply(primaparola)
#Aggiungo la colonna Farmaco al mio dataframe per la successiva aggregazione
csv_mod['Farmaco']=estratto
csv_mod['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali']=pd.to_numeric(csv_mod['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'].str.replace('.',''))
In [3]:
#In questa sezione realiziamo un dataframe 
#Contenente le categorie uniche di Farmaco
#Per fare questo
#Rimuoviamo i duplicati
selezione= csv_mod.drop_duplicates(subset=['Farmaco']).copy()
#Selezioniamo solo le colonne di interesse che andranno 
#a costituire il nostro
#dataframe
selezione=selezione[['Modalità\nPrescrizione','Farmaco']]
In [4]:
#Iniziamo il nostro lavoro di Aggregazione 
#e visualizzazione in ordine 
#Decrescente per numero di confezioni 
#fornite alle farmacie
grouped=csv_mod.groupby(by='Farmaco').sum()
grouped=grouped.sort_values(by='Quantità confezioni fornite alle farmacie ed agli esercizi commerciali',ascending=False)
print("Grouped Prima del reset dell'index")
print(grouped.head(2))
#Il reset dell'index serve per avere il farmaco come colonna e non come index
grouped=grouped.reset_index()
print("Grouped Dopo il reset dell' index")
print(grouped.head(2))

#Effettuiamo l'unione tra i due dataframe
#L'unione è fatta sfruttando la colonna Farmaco
df_farma=grouped.merge(selezione,on='Farmaco')
print(df_farma.head(3))
print(grouped.info())
#tu hai dei farmaci con lo stessa label in una colonna ma una diversa in un'altra come fare a conoscere se questa affermazione è vera?
#Puoi crare un dizionario che associ ->tachipirina a sop e rinazina a otc
#print(csv_mod.info())
Grouped Prima del reset dell'index
               Codice Autorizzazione all'Immissione in Commercio\n(AIC)  \
Farmaco                                                                   
TACHIPIRINA                                           89215558.0          
ENTEROGERMINA                                         39138155.0          

               Quantità confezioni fornite alle farmacie ed agli esercizi commerciali  
Farmaco                                                                                
TACHIPIRINA                                              8309360                       
ENTEROGERMINA                                            3834716                       
Grouped Dopo il reset dell' index
         Farmaco  Codice Autorizzazione all'Immissione in Commercio\n(AIC)  \
0    TACHIPIRINA                                         89215558.0          
1  ENTEROGERMINA                                         39138155.0          

   Quantità confezioni fornite alle farmacie ed agli esercizi commerciali  
0                                            8309360                       
1                                            3834716                       
         Farmaco  Codice Autorizzazione all'Immissione in Commercio\n(AIC)  \
0    TACHIPIRINA                                         89215558.0          
1  ENTEROGERMINA                                         39138155.0          
2       VOLTAREN                                        138192273.0          

   Quantità confezioni fornite alle farmacie ed agli esercizi commerciali  \
0                                            8309360                        
1                                            3834716                        
2                                            2940672                        

  Modalità\nPrescrizione  
0                    SOP  
1                    OTC  
2                    OTC  
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 32 entries, 0 to 31
Data columns (total 3 columns):
Farmaco                                                                   32 non-null object
Codice Autorizzazione all'Immissione in Commercio
(AIC)                   32 non-null float64
Quantità confezioni fornite alle farmacie ed agli esercizi commerciali    32 non-null int64
dtypes: float64(1), int64(1), object(1)
memory usage: 848.0+ bytes
None
In [6]:
##### Ora che abbiamo aggiunto la colonna che definisce 
#quali farmaci sono SOP e quali OTC possiamo 
#realizzare il nostro scatter plot con colori differenti
df_farma=df_farma.sort_values(by='Quantità confezioni fornite alle farmacie ed agli esercizi commerciali',ascending=False)
label=df_farma['Farmaco']
ln=np.arange(0,len(df_farma))
#Creaiamo due dataframe uno per OTC ed uno per i SOP
df_otc=df_farma[df_farma['Modalità\nPrescrizione']=='OTC']
df_sop=df_farma[df_farma['Modalità\nPrescrizione']=='SOP']
#L'index sarà  necessario per la corretta 
#disposizione sull'asse delle x delle corrispoondenti y
index_otc=df_otc.index

index_sop=df_sop.index

otc_plot=plt.scatter(index_otc,df_otc['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'], color='red')
sop_plot=plt.scatter(index_sop,df_sop['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'], color='blue')
plt.ylabel('# di confezioni distribuite')
plt.xticks(ln,(label) ,rotation=90)
plt.title('Medicinali senza obbligo di prescrizione più distribuiti primo semestre 2016 alle farmacie aperte al pubblico ed agli esercizi commerciali')

plt.text(10, 4, 'Elaborazioni Ing. Andrea Ciufo',
         fontsize=15, color='gray',
         ha='center', va='top', alpha=0.5)
plt.legend((sop_plot,otc_plot),('SOP= Senza Obbligo di Prescrizione','OTC= Over The Counter o farmaci da banco o farmaci di automedicazione per i quali è prevista la pubblicità'),loc='upper right')
plt.rcParams["figure.figsize"] = (15,4)
plt.show()
In [11]:
#In questa sezione invece Aggreghiamo
#Tutti i Farmaci SOP e tutti i farmaci OTC 
#Per visualizzarli attraverso un Bar Plot
#Per motivi di tempo non sono riuscito a migliorare 
#L'asse delle Y dove i valori sono espressi 
#In termini di x*e7


sum_otc=df_otc.groupby(by='Modalità\nPrescrizione').sum()
sum_sop=df_sop.groupby(by='Modalità\nPrescrizione').sum()
print(sum_otc['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'])
print(sum_sop['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'])
sum_df_y=[sum_otc['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'].values, sum_sop['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'].values]
sum_df_x=['OTC','SOP']

sum_df = pd.DataFrame({'Modalità Prescrizione':sum_df_x, 'Quantità confezioni fornite alle farmacie ed agli esercizi commerciali':sum_df_y})

ind=np.arange(len(sum_df_y))

plt.bar(ind,sum_df['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'], width=0.2)
plt.rcParams["figure.figsize"] = (7,3)
plt.title('Medicinali senza obbligo di prescrizione più distribuiti primo semestre 2016')

plt.ylabel('# di confezioni distribuite')
plt.xticks(ind,(sum_df_x) ,rotation=90)


plt.text(0.5, 0.5, 'Elaborazioni Ing. Andrea Ciufo',
         fontsize=15, color='gray',
         ha='center', va='top', alpha=0.5)

plt.show()
Modalità\nPrescrizione
OTC    30361800
Name: Quantità confezioni fornite alle farmacie ed agli esercizi commerciali, dtype: int64
Modalità\nPrescrizione
SOP    12599616
Name: Quantità confezioni fornite alle farmacie ed agli esercizi commerciali, dtype: int64

*il dataset più recente disponibile al 25 Ottobre 2018 sul sito del Ministero

Lascia un commento

Archiviato in Notizie e politica, riflessioni

I Farmaci Più Distribuiti In Italia

“Lo sai che la Tachiprina 500
Se ne prendi due diventa mille
Si vede che hai provato qualcosina parlano
Parlano le tue pupille
E adesso che mi prendi per la mano vacci piano
Che se mi stringi così”

-Calcutta

Il Ministero della Salute ha un set di open data sui farmaci più distribuiti, così questa mattina ho deciso di studiarlo (trovate qui il dataset)

Anticipo che dal punto di vista metodologico ho aggregato tutti i farmaci che avessero lo stessa parola iniziale.

Ad esempio la Tachipirina è stata aggregata in un’unica variabile sia che fosse da 500, sia da 1000, per via orale e supposte.

Per motivi di tempo ho potuto indagare quali di questi farmaci fossero anche sponsorizzati in TV. C’è una variabile categorica “Modalità” che può assumere o il valore “SOP”(Senza Obbligo di Ricetta”) o OTC (Over The Counter) farmaci da banco o di automedicazione per i quali è prevista pubblicità.

Nel prossimo post approfondirò la relazione tra il consumo di farmaci e la loro sponsorizzazione in TV.

I primi 5 farmaci con il più alto tasso di distribuzione in Italia nel primo semestre 2016 sono stati la Tachipirina(8+Mil di confezioni), l’Enterogermina(3+Mil di confezioni), il Voltaren, la Rinazina e l’Aspirina.

Sempre per chiarezza metodologica “Glicerolo“, sono le supposte Carlo Erba.

I farmaci più venduti in Italia

80% del tempo è stato impiegato per la pulizia del dataset.

Nello specifico ho dovuto saltare le prime righe perché si presentavano come vedete in foto.

Inoltre la tabulazione non era codificata secondo ‘utf-8’ ma ho dovuto utilizzare la “ISO-8859-1” ed al posto della virgola il separatore utilizzato era ‘;

I valori numerici dei quantitativi distribuiti erano nel seguente formato “1.000.000” è stato necessario rimuovere con una funzione il punto per poter convertire la stringa in numero.

A questo link trovate una domanda di stack overflow che mi ha aiutato nel leggere con padas il csv perchè non avevo capito subito che c’era un problema nella lettura e codifica del file, questa (link) invece per l’estrazione della prima parola quando ci sono dei caratteri speciali iniziali.

 

Grazie per aver letto l’articolo!

Se ti è piaciuto ricondividilo, se pensi meriti delle correzioni scrivimi pure 🙂

Un abbraccio

Andrea

 

In [1]:
# Import pandas
import pandas as pd

import numpy as np
# Import plotting modules
import matplotlib.pyplot as plt

import re
file_name='C_17_dataset_15_download_itemDownload_0_upFile.csv'
csv=pd.read_csv(file_name,sep=';',encoding="ISO-8859-1",skiprows=1)
csv.info()
#Visualizzo il titolo dei farmaci
#Questo è necessario per il successivo
#processo di pulizia e aggregazione 
print(csv['Denominazione della confezione'])
csv_mod=csv.dropna().copy()
csv_mod['Farmaco']=None
#Un prodotto Rinazina aveva ** ad inizio stringa perchè il ministero doveva confermare il dato
#per comodità ho rimosso ** 
csv_mod['Denominazione della confezione']=csv_mod['Denominazione della confezione'].str.replace('*','')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 52 entries, 0 to 51
Data columns (total 6 columns):
N°                                                                        51 non-null object
Codice Autorizzazione all'Immissione in Commercio
(AIC)                   50 non-null float64
Denominazione della confezione                                            50 non-null object
Fascia PTN                                                                50 non-null object
Modalità
Prescrizione                                                     50 non-null object
Quantità confezioni fornite alle farmacie ed agli esercizi commerciali    50 non-null object
dtypes: float64(1), object(5)
memory usage: 2.5+ KB
0            TACHIPIRINA "500 MG COMPRESSE"20 COMPRESSE
1      TACHIPIRINA "120 MG/5 ML SCIROPPO"FLACONE 120 ML
2     ENTEROGERMINA "2 MILIARDI/5 ML  SOSPENSIONE OR...
3     RINAZINA "100 MG/100 ML SPRAY NASALE, SOLUZION...
4           TACHIPIRINA "500 MG COMPRESSE" 30 COMPRESSE
5     **RINAZINA ANTIALLERGICA "1 MG/ML SPRAY NASALE...
6                  OKITASK "40 MG GRANULATO" 10 BUSTINE
7     DAFLON "500 MG COMPRESSE RIVESTITE CON FILM" 3...
8     ENTEROGERMINA "4 MILIARDI / 5 ML SOSPENSIONE O...
9     MOMENT "200 MG COMPRESSE RIVESTITE"  12 COMPRESSE
10    GLICEROLO CARLO ERBA "ADULTI 6,75 G SOLUZIONE ...
11    ENTEROGERMINA "2 MILIARDI/5 ML  SOSPENSIONE OR...
12    FLUIBRON "15 MG/2 ML SOLUZIONE DA NEBULIZZARE"...
13            VOLTAREN EMULGEL " 1 % GEL " TUBO DA 60 G
14    PURSENNID "12 MG COMPRESSE RIVESTITE" 30 COMPR...
15    GLICEROLO CARLO ERBA "ADULTI 2250 MG SUPPOSTE ...
16    TACHIPIRINA "BAMBINI 250 MG SUPPOSTE" 10 SUPPOSTE
17             VOLTAREN EMULGEL " 2 % GEL" TUBO DA 60 G
18    ASPIRINA "400 MG COMPRESSE EFFERVESCENTI CON V...
19     MAALOX "PLUS COMPRESSE MASTICABILI" 30 COMPRESSE
20    PROCTOLYN "0,1 MG/G + 10 MG/G CREMA RETTALE" T...
21     GYNO-CANESTEN "2% CREMA VAGINALE" 1 TUBO DA 30 G
22       BIOCHETASI "GRANULATO EFFERVESCENTE"20 BUSTINE
23              IMODIUM "2 MG CAPSULE RIGIDE" 8 CAPSULE
24    VIVIN C "330 MG + 200 MG COMPRESSE EFFERVESCEN...
25                 OKITASK "40 MG GRANULATO" 20 BUSTINE
26    ASPIRINA "400 MG COMPRESSE EFFERVESCENTI CON V...
27    VEROLAX "6,75 G ADULTI SOLUZIONE RETTALE" 6 CO...
28    TACHIPIRINA "500 MG GRANULATO EFFERVESCENTE"20...
29    ASPIRINA DOLORE E INFIAMMAZIONE "500 MG COMPRE...
30                     CANESTEN "1% CREMA" TUBO DA 30 G
31    MAALOX "400 MG + 400 MG COMPRESSE MASTICABILI"...
32    VICKS SINEX "ALOE 0,05% SOLUZIONE DA NEBULIZZA...
33                               ESSAVEN "1% + 0,8% GEL
34              VOLTAREN EMULGEL "1% GEL" TUBO DA 120 G
35       TANTUM VERDE "0,15% COLLUTORIO" FLACONE 240 ML
36    NUROFEN FEBBRE E DOLORE "BAMBINI 100 MG/5 ML S...
37    REACTINE "5 MG + 120 MG COMPRESSE A RILASCIO P...
38    MOMENDOL "220 MG COMPRESSE RIVESTITECON FILM" ...
39    BUSCOPAN "10 MG COMPRESSE RIVESTITE" 30 COMPRE...
40          LASONIL ANTIDOLORE "10% GEL" 1 TUBO DA 50 G
41    LORMETAZEPAM MYLAN GENERICS " 2,5 MG/ ML GOCCE...
42    ARVENUM "500 MG COMPRESSE RIVESTITE CON FILM" ...
43    CLISMA LAX "SOLUZIONE RETTALE" 1 FLACONE DA 13...
44    MOMENT " 200 MG COMPRESSE RIVESTITE " 36 COMPR...
45    BISOLVON "4 MG/5 ML SCIROPPO GUSTO CIOCCOLATO ...
46            VOLTAREN EMULGEL " 2 % GEL" TUBO DA 100 G
47    FROBEN GOLA "0,25% SPRAY PER MUCOSA ORALE" FLA...
48    TACHIPIRINA "ADULTI 1000 MG SUPPOSTE" 10 SUPPOSTE
49    TACHIPIRINA "BAMBINI 500 MG SUPPOSTE" 10 SUPPOSTE
50                                                  NaN
51                                                  NaN
Name: Denominazione della confezione, dtype: object
In [2]:
#Aggiungiamo la colonna Farmaco al nostro DataFrame
csv_mod['Farmaco']=None
def primaparola(colonna_di_testo):
    
    pattern=r'\W*(\w[^,. !?"]*)'
    return re.match(pattern,colonna_di_testo).group()

print(type(csv_mod['Denominazione della confezione']))

estratto=csv_mod['Denominazione della confezione'].apply(primaparola)
csv_mod['Farmaco']=estratto
csv_mod['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali']=pd.to_numeric(csv_mod['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'].str.replace('.',''))

grouped=csv_mod.groupby(by='Farmaco').sum()

print(csv_mod.info())
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 50 entries, 0 to 49
Data columns (total 7 columns):
N°                                                                        50 non-null object
Codice Autorizzazione all'Immissione in Commercio
(AIC)                   50 non-null float64
Denominazione della confezione                                            50 non-null object
Fascia PTN                                                                50 non-null object
Modalità
Prescrizione                                                     50 non-null object
Quantità confezioni fornite alle farmacie ed agli esercizi commerciali    50 non-null int64
Farmaco                                                                   50 non-null object
dtypes: float64(1), int64(1), object(5)
memory usage: 3.1+ KB
None
In [3]:
df_farmaco=grouped['Quantità confezioni fornite alle farmacie ed agli esercizi commerciali'].sort_values(ascending=False)
ln=np.arange(0,len(df_farmaco))
label=df_farmaco.index
In [6]:
label=df_farmaco.index
#Rappresentiamo in nostri dati attraverso uno scatter plot
plt.scatter(ln,df_farmaco)
plt.title('Medicinali senza obbligo di prescrizione più venduti primo semestre 2016 alle farmacie aperte al pubblico ed agli esercizi commerciali')

plt.ylabel('# di confezioni vendute')
plt.xticks(ln,(label) ,rotation=90)
plt.text(10, 4, 'Elaborazioni Ing. Andrea Ciufo',
         fontsize=15, color='gray',
         ha='center', va='top', alpha=0.5)
plt.rcParams["figure.figsize"] = (15,4)
plt.show()

 

I farmaci più venduti in Italia

Lascia un commento

Archiviato in riflessioni, Salute e Benessere

A/B Test spiegato al Nerd che vuole rimorchiare su Tinder

Ti sei appena comprato l’ultimo profumo, l’addome non è proprio scolpito, la barba è perfetta, ma l’unico match che sei riuscito ad ottenere su Tinder è con il profilo finto della Mucca Carolina iscritta dal tuo amico Marco anche noto come “Il Capraro”.

Inizi a riflettere che forse c’è un problema.

Questa strategia del rimorchio non sta funzionando, evidentemente.

Decidi di affidarti al tuo amico, il mago della conquista, il re del rimorchio dai tempi di MySpace e Netlog, per gli amici “Er Trivella”.

Dopo una veloce chiacchierata ed un paio di birre, Er Trivella, decide di aiutarti, ma solo se sei disposto a pagargli da bere in caso di successo.

Subito si accorge che la tua selezione di foto profilo a petto nudo con la mutanda “Uomo” comprata in pacchi da 10 al mercato non può andar bene, così come deve essere aggiornata l’altra tutta sfocata e con il volto devastato dagli shoot di Ibiza 2k12.

“Terapia d’urto” queste le parole di “Er Trivella” in un momento di grande sconforto e compassione nei tuoi confronti.

Shopping selvaggio tra Piazza Italia e OVS, foto con la reflex in modalità automatico fatte dall’amica fotografa e frasi random di Fabio Volo.

Subito dopo l’aggiornamento del profilo iniziano i match e stenti a crederci.

Tu però non vuoi offrire da bere, pensi sia tutto frutto del caso, che “Er Trivella “ sia stato fortunato.

Con le vecchie foto profilo -> 100 tentativi ->1 match

Con le nuove foto profilo ->100 tentativi -> 10 Match

Guardi Er Trivella e con un po’ di sfacciataggine dici

“Guarda secondo me è solo un caso, con le nuove foto di profilo è stata solo fortuna, l’ipotesi che sia cambiato qualcosa è falsa”

Er Trivella ti guarda negli occhi, non gli pare vero, lui vuole che gli paghi da bere e con calma risponde:

“Ok allora facciamo così se è vero che è stata solo fortuna non cambia nulla tra la situazione prima e la situazione successiva.

Noi abbiamo 200 tentativi in totale giusto?”

Tu:”Si”

Er Trivella:”Facciamo delle simulazioni.

Prendiamo 200 foglietti scriviamo sopra questi il nome della tipa e se hai avuto successo o meno.

1 se hai avuto successo e 0 se non è andata bene”.

Alla strana richiesta realizzi questi 200 foglietti.

Er Trivella:”Ora per un bel po’ di volte mischiamo i 200 foglietti, associamo i primi 100 alla vecchia condizione (Test A) e gli ultimi 100 a quella nuova (Test B).

Una volta fatto calcoliamo la differenza tra i casi di successo tra il nuovo caso B’ ed il nuovo caso A’, chiameremo questo valore “Delta Rimorchio”.

Ti ricordi nel caso originale questa differenza era di 0.09?” (10/100-1/100)

“Una volta calcolato il “Delta Rimorchio” la seconda volta, rimischiamo i foglietti e ripetiamo l’operazione un certo numero di volte (un numero di volte n, con n molto grande).

Ora se quello che hai detto ha senso le volte in cui rimischiando i foglietti il delta rimorchio è uguale o maggiore al delta rimorchio iniziale dovrà essere abbastanza frequente, essendo questa differenza un caso”

Tu:”Certo, ha senso”

Er Trivella: “Potremmo valutare la cosa dividendo il numero di volte in cui “Delta rimorchio è maggiore o al più uguale” per il numero di volte che abbiamo rimischiato i foglietti” (questo valore sarà il nostro p-value dei dati).

Er Trivella:”Più questo rapporto sarà grande e più le tue ipotesi saranno corrette, ma più questo valore è piccolo e più probabile che la tua ipotesi sia falsa.”

Tu:”Quanto piccolo?”

Er Trivella:”Se voglio rifiutare la tua ipotesi con il 95% di confidenza questo dovrà essere più piccolo di 0.05.”

 

Tu ed Er Trivella scoprite che:

  • Il numero di volte che mischiando i foglietti hai ottenuto risultati migliori è stata solo 1 su 100 il p-value è 0.01
  • l’ipotesi che fosse tutta fortuna è falsa
  • tocca pagare da bere

Gli A/B test sono estremamente frequenti soprattutto nel Digital Marketing, ma non sempre la loro valutazione è facile, questo articolo con lo script allegato è solo una simpatica introduzione, molte ipotesi sono state semplificate, per una rigorosa trattazione consiglio sempre il Ross “Introduzione alla Probabilità ed alla Statistica per Ingegneri e Scienziati”.

Inoltre bisogna sempre valutare il costo della sperimentazione, il miglioramento che si ottiene dal test A o dal test B non solo deve essere statisticamente significativo, ma anche economicamente significativo.

Per Economicamente Significativo intendo che il costo della sperimentazione è giustificato dal guadagno che il miglioramento genera, un punto estremamente difficile e non sempre rispettato.

Grazie per aver letto l’articolo!

Se ti piace ri-condividilo 🙂

Un abbraccione

Andrea

 

ps Devo formattare meglio il codice è sempre un po’ un trauma per me districarmi tra il notebook jupyter e il codice html, inizierò anche a pubblicare questi script sul mio profilo GitHub 🙂

 

In [4]:
import numpy as np

import pandas as pd

 

In [5]:
#Rappresentiamo attraverso due array di 1 e 0 i nostri due scenari di analisi

old_pic=np.array([True] * 1 + [False] * 99)

new_pic=np.array([True] * 10 + [False] * 90)

 

 

In [6]:
#Definiamo la statistica oggetto di analisi come 

#la differenza i successi con le nuove foto e i successi con le vecchie

#in rapporto al numero di tentativi effettuati

def frac_abs_success(a,b):



afrac = np.sum(a) /len(a)

bfrac= np.sum(b) /len(b)

ababs=abs(afrac-bfrac)

return ababs

def permutation_sample(data1, data2,func):

"""Generiamo una permutazione definiti due data set."""

 

# Concateniamo i datasets: data

data = np.concatenate((data1,data2))

 

# Definiamo l'array delle permutazioni permuted_data

permuted_data = np.random.permutation(data)

 

#  Dividiamo in due insiemi A' B' l'array delle permtazioni: perm_sample_1, perm_sample_2

perm_sample_1 = permuted_data[:len(data1)]

perm_sample_2 = permuted_data[len(data1):]

delta_rim=func(perm_sample_1,perm_sample_2)

 

return delta_rim

 

In [7]:
#Realizziamo n permutazioni dei nostri due insiemi A* B*

n=1000

#per ogni permutazione calcoliamo il valore della statistica di analisi

#la differenza tra il secondo ed il primo insieme

def draw_rep_stat(data,data2, func, size):

"""Draw bootstrap replicates."""

 

# Initialize array of replicates: bs_replicates

stat_replicates = np.empty(size)

 

# Generate replicates

for i in range(size):

stat_replicates[i] = permutation_sample(data,data2,func)

 

return stat_replicates

 

In [16]:
test_set=draw_rep_stat(old_pic, new_pic,frac_abs_success,n)

 

print(len(test_set))

#Calcoliamo il p-value dei dati 

#n è il numero di permutazioni che realizziamo 

p = np.sum(test_set >= frac_abs_success(old_pic,new_pic)) / len(test_set)

print('p-value =', p)

 

 

 

1000

p-value = 0.01

 

Lascia un commento

Archiviato in Ingegneria, riflessioni, Tecnologia

Come Diventare DataScientist da Autodidatta

-Dottore mio figlio vuole diventare DataScientist secondo lei è grave?

-Gravissimo signora, mi dispiace per lei, ma io l’avevo avvertita. Purtroppo la medicina non ha risposte a queste malattie. Si prepari, si prepari, suo figlio andrà all’IKEA o per risparmiare tempo comprerà delle lavagne su Amazon(https://amzn.to/2NpOImd), ne abbiamo già visti di casi del genere.

Le ha già parlato entusiasta di MonteCarlo (https://it.wikipedia.org/wiki/Metodo_Monte_Carlo)?

-Si.

-Allora è più grave di quanto pensassi.

 

Ieri o l’altro ieri mi aveva scritto Davide Sicignani , sempre un fratello del gruppo InnLab, di Terracina (quindi dietro casa), ma che ho conosciuto solo a Londra.

Da sinistra Ugo, Davide, Gabriele ed Io in un tipico pranzo della Domenica Londinese

Davide mi chiedeva un consiglio per un suo amico Biologo che vuole avvicinarsi a Python e DataScience.

In particolare mi contattava perché ho cominciato da Zero e da Autodidatta.

Non essendo la prima persona che mi ha contattato per questo motivo, anche Stefano (sempre InnLab) qualche mese fa, ho deciso di scriverci due righe.

E’ opportuno distinguere tre domini di conoscenza che rientrano a mio avviso sotto il grande cappello del DataScientist, ma lo farò in un altro post:

  • Data Engineering (Informatica)
  • Data Modeling (Probabilità e Statistica- Ricerca Operativa)
  • Business Intelligence (Capacità Analitica)

Quello che racconterò è un po’ la sintesi del mio percorso e delle risorse utilizzate.

Indubbiamente la strada migliore per essere DataScientist è la stessa che caratterizza il settore medico:

La perfetta sinergia tra Pratica, Studio e degli ottimi Mentor.

Cosa ho capito fino ad oggi:

  1. Non esistono corsi che in un mese o in una settimana ti permettono di diventare DataScientist, se dicono il contrario è una balla
  2. Non è possibile diventare DataScientist solo attraverso la pratica
  3. Non è possibile diventare DataScientist solo attraverso i libri
  4. E’ estremamente bello
  5. E’ estremamente faticoso
  6. Esistono molte persone del mestiere disposte ad aiutarti (gratis)
  7. Per iniziare a capirci qualcosa serve almeno un anno di allenamento
  8. L’anno di allenamento necessario non ti esime dal provare a trovare lavoro anche se non hai abbastanza esperienza, quello che sai fare ed hai imparato fallo valutare anche agli altri. Rischi di rimandare il tuo ingresso nel settore spaventato di non essere all’altezza

 

Ahi quanto a dir qual era è cosa dura

esta selva selvaggia e aspra e forte

che nel pensier rinova la paura!

–Dante Alighieri, Inferno, I Canto

 

Quindi quali sono le risorse da scegliere per intraprendere questo percorso?

Ecco le mie:

DataCamp.com

Ad Agosto 2017 ho iniziato a studiare su DataCamp.com ho seguito tutto il percorso per diventare DataScientist.

Consigliatissimo.

Il costo per un anno di accesso a tutti i corsi è di 130/180$ adesso non ricordo precisamente.

Ottimo investimento, corsi semplici, ma efficaci.

Questi corsi servono per una prima infarinatura sul Machine Learning e Python.

L’app mobile permette di allenarsi anche sul bus o in metro su concetti basilari.

Contro, non è assolutamente sufficiente per lavorare, sono necessarie altre risorse a supporto.

 

Python for Data Analysis: Data Wrangling with Pandas, Numpy, and IPython

Il link al libro *-> https://amzn.to/2NrqLuJ

E’ il libro scritto da Wes McKinney, l’autore della libreria Pandas, una delle più usate in Python per la manipolazione e pulizia dei dati.

Il libro me lo aveva regalato Marchetti quando ho cominciato questo percorso ed è stato una grande risorsa, perché gradualmente spiega tutto quello che è necessario sapere per la pulizia e manipolazione dei dati.

Ho impiegato un anno per studiarlo tutto e altri sei mesi servirebbero per ripassarlo ed allenarsi su tutti i concetti che vengono illustrati.

Il libro va letto, studiato, con il pc ed il notebook jupyter aperti.

In questo modo è possibile riprodurre in tempi brevi tutti i consigli ed esempi riportati nel testo.

Se non si mettono in pratica gli esempi riportati, anche modificandoli a piacere, il libro perde gran parte della sua efficacia.

 

Pratica

Questa parte è F-O-N-D-A-M-E-N-T-A-L-E

Ho avuto modo di fare pratica attraverso progetti di consulenza, progetti pro-bono, data set pubblici, durante gli step tecnici di alcuni colloqui di lavoro e lavorando su freelancer.com.

Il tempo viene dedicato in buona parte alla pulizia e manipolazione dei dati, è frustrante, ma è sempre così. 

Solo col tempo ed esperienza si diventa veloce in questa parte del lavoro.

Esistono tantissimi data set pubblici anche italiani dove acquisire dati e iniziare ad effettuare un po’ di Data  Visualization, inferenze e creare qualche modello di Machine Learning

Eccone alcuni:

 

C’è anche Kaggle

Kaggle è una piattaforma e comunity specifica per DataScientist.

Li sono presenti tantissimi dataset sui quali esercitarsi.

Avere un buon punteggio su Kaggle, partecipare alle competizioni è un’ottima strada per farsi notare da eventuali recruiter e poter dimostrare le proprie competenze

PostgreSQL

La conoscenza di SQL è la seconda skill più richiesta dopo Python negli annunci di lavoro.

Questo sulla base  delle job description analizzate (+100) per il lavoro di DataScientist a Londra

Un’ottima piattaforma gratuita per allenarsi è https://pgexercises.com/

Postgresql era uno dei DBMS più frequenti negli annunci, ne esistono anche altri, non sentitevi vincolati nella scelta.

 

Mentor

Un mentor tecnico è una risorsa chiave per vari motivi:

  • Ti sprona a fare di più
  • Può aiutarti in momenti di difficoltà a sciogliere subito eventuali nodi (ovviamente dopo che hai sbattuto la testa per almeno due giorni sul problema)
  • Rende umano un percorso fatto di numeri e righe di codice

Podcast

Esistono podcast di vario tipo sia su SoundCloud che su Spotify, ascoltarli permette nei tempi morti di essere aggiornati su tecnologie e trend del mercato.

Ingrediente Segreto

L’ingrediente segreto è uno ed uno solo: la passione

Se non vi emozionate davanti ad un bel grafico, se non vi incuriosisce la possibilità di pianificare e predire l’andamento delle vendite o valutare l’andamento delle azioni, se non impazzite all’idea di una nottata passata ad analizzare i processi esponenziali che potrebbero rappresentare la rottura di alcuni componenti elettronici, non iniziate questo percorso.

 

E’ la passione che muove tutto, le altre risorse sono secondarie.

Iniziate.

Fate.

Fate.

Fate.

Grazie per aver letto l’articolo!

Un abbraccio

Andrea

 

ps se ci sono errori di battitura o di grammatica scrivimi pure 🙂

*Con i link di affiliazione di Amazon potete aiutarmi a coprire le spese per il blog vi ringrazio in anticipo

 

3 commenti

Archiviato in Hobby, Ingegneria

Open Data e Immigrazione se l’Italia fosse come la Nuova Zelanda

Questo post non dovrebbe essere sull’Immigrazione Neozelandese (in realtà il rilascio di Visti), il Viminale e gli Open Data, avevo promesso a Davide, un alumno di InnovAction Lab, che avrei discusso dell’importanza di non avere l’app di Facebook sul cellulare per evitare distrazioni e restare focalizzati.

In sintesi se andate su questo sito statistico della Nuova Zelanda (dove hanno girato il Signore degli Anelli), con estrema facilità potete scaricare tutti i dati sui Visti rilasciati dal 2001 ad oggi.

Basta andare nella sezione Turismo-International Travel e Migration ecc.. http://archive.stats.govt.nz/infoshare/

Volete fare lo stesso lavoro con un data base italiano?

http://www.interno.gov.it/it/servizi/banche-dati-ed-elenchi

Almeno per me è stato un inferno e non sono riuscito a trovare qualcosa di strutturato, intuitivo e usabile(in termini di usabilità).

In questo modo non è possibile condurre  nessuna discussione seria e costruttiva in merito alla questione Immigrazione.

Così ho scritto all’Agenzia per l’Italia Digitale, ma ancora nulla.

 

 

Nel mentre, per motivi di lavoro ho condotto una sintetica ricerca sui Visti rilasciati in Nuova Zelanda dal 2001 al 2016.

Il codice verrà pubblicato su www.lovabledata.com nei prossimi giorni nel formato di Jupyter Notebook.

 

E questi sono i valori:

Total      %
Visitor    367368  30.62
Residence  295935  24.67
Student    274149  22.85
Work       247818  20.66
Other       14478   1.21


Oltre a queste informazioni è anche possibile valutare da dove provengono le richieste approvate:
Sum and % of Visa by Region
                              Total      %
North-East Asia              109569  40.03
Southern and Central Asia     74583  27.25
South-East Asia               38487  14.06
North-West Europe             14367   5.25
Oceania and Antarctica        12330   4.50
Africa and the Middle East    11583   4.23
The Americas                   9150   3.34
Southern and Eastern Europe    3678   1.34

E valutare sommariamente applicando una media mobile qual è il trend di provenienza degli immigrati regolari dalle realtà più significative.

Sarebbe interessante poter fare le stesse analisi con i dati italiani (che ci sono ma non si sa dove siano nascosti).

Un abbraccio

Andrea

Guardiamo alle religioni come alle mille foglie di un albero, ci sembrano tutte differenti, ma tutte riconducono a uno stesso tronco.
(Mahatma Gandhi)

 

 

ps ci sono più persone nel Lazio(5,8 Milioni) che in Nuova Zelanda  (4,6 Milioni)

 

pps Si scrive “New Zealand” e non “New Zeland” correggerò i grafici 😀

Lascia un commento

Archiviato in Notizie e politica, riflessioni