AS
Python
Parametric correlation analysis: Pearson R coefficient
Il coefficiente di correlazione R di Pearson fornisce una misura del grado di correlazione fra variabili numeriche, continue ed in relazione lineare.
Il valore di R è compreso fra -1 e 1. Un valore prossimo a 1 significa una forte relazione; un valore prossimo a -1 significa una forte relazione inversa; un valore vicino a 0 indica che le variabili non sono linearmente correlate.
Si deve aver chiaro che correlazione non implica causalità.
Per implementare un esempio, ci collegheremo ai dati del portale Open Data della Regione Lomardia.
In particolare, considerato il parco veicoli circolante, cercheremo di mettere in relazione le emissioni di CO2 nell'aria con altri parametri.
Gli insight che ne risulteranno non saranno certo sorprendenti, ma questo vuole solo essere una dimostrazione di come affrontare con Python l'analisi in oggetto.
Codice
import pandas as pd
url = "https://www.dati.lombardia.it/resource/mb9s-97xn.csv"
#Parco Veicoli Circolanti Regione Lombardia a Ottobre 2018
df = pd.read_csv(url)
#subst = df[["portata", "cilindrata", "kw", "dt_prima_immatricolazione", "peso_complessivo", "emissioni_co2"]]
subst = df.loc[:, ("portata", "cilindrata", "kw", "dt_prima_immatricolazione", "peso_complessivo", "emissioni_co2")]
#creo un subset
subst.info()
subst.head()
#info DataFrame e anteprima
Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   portata                    994 non-null    float64
 1   cilindrata                 1000 non-null   object 
 2   kw                         985 non-null    float64
 3   dt_prima_immatricolazione  994 non-null    float64
 4   peso_complessivo           994 non-null    float64
 5   emissioni_co2              997 non-null    float64
dtypes: float64(5), object(1)
memory usage: 47.0+ KB
				
portata cilindrata kw dt_prima_immatricolazione peso_complessivo emissioni_co2
0 1000.0 NaN 1989.0 1300.0 0.0
1 70.0 00125 13.0 1991.0 245.0 0.0
2 350.0 01995 119.0 1991.0 1680.0 0.0
3 96.0 00101 6.0 1997.0 265.0 0.0
4 70.0 00647 42.0 1994.0 360.0 0.0
Codice
#clean data
subst["cilindrata"] = pd.to_numeric(subst["cilindrata"], errors="coerce")
#convert to float
subst = subst[subst["emissioni_co2"]>0]
#considero solo se il dato delle emissioni รจ disponibile
subst.dropna(how="any", axis=0, inplace=True)
# axis 0=Drop rows 1=Drop columns
# how any=any NA values are present all=allvalues are NA
# inplace makes the changes in data frame itself if True
subst.reset_index(inplace=True, drop=True)
subst.info()
subst.head()
Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 485 entries, 0 to 484
Data columns (total 6 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   portata                    485 non-null    float64
 1   cilindrata                 485 non-null    float64
 2   kw                         485 non-null    float64
 3   dt_prima_immatricolazione  485 non-null    float64
 4   peso_complessivo           485 non-null    float64
 5   emissioni_co2              485 non-null    float64
dtypes: float64(6)
memory usage: 22.9 KB
				
portata cilindrata kw dt_prima_immatricolazione peso_complessivo emissioni_co2
0 273.0 1299.0 44.0 2002.0 1265.0 1630.0
1 475.0 1360.0 55.0 1997.0 1580.0 1700.0
2 425.0 1360.0 55.0 1999.0 1450.0 1570.0
3 360.0 899.0 29.0 1998.0 1150.0 1600.0
4 345.0 998.0 50.0 2000.0 1335.0 1370.0
Codice
import seaborn as sb
x=subst[["portata", "cilindrata", "kw", "dt_prima_immatricolazione", "peso_complessivo", "emissioni_co2"]]
sb.pairplot(x)
Output
<seaborn.axisgrid.PairGrid at 0x18d7482d148>
Questa rappresentazione grafica di insieme ci da già un'idea delle relazioni fra le variabili e ci fa escludere, ad esempio, una stretta correlazione fra anno di prima immatricolazione ed emissioni di CO2.
Dopo aver pulito i dati e dato uno sguardo generale, passiamo al calcolo vero e proprio del coefficiente R.
Codice
from scipy.stats.stats import pearsonr
portata = subst["portata"]
kw = subst["kw"]
dt_prima_immatricolazione = subst["dt_prima_immatricolazione"]
peso_complessivo = subst["peso_complessivo"]
emissioni_co2 =subst["emissioni_co2"]
pearsonr_coefficient, p_value = pearsonr(portata, emissioni_co2)
print("Pearson R coefficient portata vs emissioni_co2 : %0.3f" %(pearsonr_coefficient))
pearsonr_coefficient, p_value = pearsonr(kw, emissioni_co2)
print("Pearson R coefficient kw vs emissioni_co2 : %0.3f" %(pearsonr_coefficient))
pearsonr_coefficient, p_value = pearsonr(dt_prima_immatricolazione, emissioni_co2)
print("Pearson R coefficient dt_prima_immatricolazione vs emissioni_co2 : %0.3f" %(pearsonr_coefficient))
pearsonr_coefficient, p_value = pearsonr(peso_complessivo, emissioni_co2)
print("Pearson R coefficient peso_complessivo vs emissioni_co2 : %0.3f" %(pearsonr_coefficient))
Output
Pearson R coefficient portata vs emissioni_co2 : 0.370
Pearson R coefficient kw vs emissioni_co2 : 0.723
Pearson R coefficient dt_prima_immatricolazione vs emissioni_co2 : -0.248
Pearson R coefficient peso_complessivo vs emissioni_co2 : 0.619
Questi risultati ci dicono che esiste una chiara correlazione innanzitutto fra i kw e le emissioni di CO2. Anche la correlazione fra il peso complessivo e le emissioni è evidente. Con l'aumentare (il passare) degli anni di immatricolazione invece le emissioni calano in modo non significativo; in questo caso i dati paiono sostanzialmente non in relazione.