A les dues lliçons anteriors vam analitzar cada variable de MercaFresh per separat: la seva forma, el seu centre, la seva dispersió. Però les preguntes interessants de negoci són gairebé sempre sobre relacions: els clients que més triguen a rebre les comandes es donen de baixa més? Les comandes grans fan servir més el pagament amb targeta? La covariància i la correlació són les eines que quantifiquen si dues variables es mouen juntes, en quina direcció i amb quina força. Dominar-les és clau en Machine Learning: guien la selecció de variables, avisen de redundàncies i són el primer radar per trobar senyals de churn. També n'aprendràs el límit més important: correlació no implica causalitat.

Contingut

  1. Covariància: la idea i la seva limitació
  2. Correlació de Pearson: interpretació i rangs
  3. Correlació de Spearman: quan fer-la servir
  4. Matrius de correlació i heatmaps amb pandas
  5. Correlació no implica causalitat
  6. Rellevància per al Machine Learning
  7. Cas MercaFresh: quines variables es relacionen amb el churn?

Covariància: la idea i la seva limitació

La covariància entre dues variables X i Y mesura si tendeixen a desviar-se de les seves mitjanes en la mateixa direcció:

cov(X, Y) = Σ (xᵢ − x̄)(yᵢ − ȳ) / (n − 1)

La intuïció del producte (xᵢ − x̄)(yᵢ − ȳ):

  • Si quan X és per sobre de la seva mitjana, Y també ho és (i viceversa), els productes són positius → covariància positiva.
  • Si quan X puja, Y tendeix a baixar, els productes són negatius → covariància negativa.
  • Si no hi ha patró, positius i negatius es cancel·len → covariància propera a 0.
import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
n = 500

# Dades ficticies de 500 clients de MercaFresh
n_articles = rng.poisson(lam=14, size=n)                       # articles per comanda
import_comanda = 3.2 * n_articles + rng.normal(0, 8, size=n)   # mes articles -> mes euros
minuts_lliurament = rng.gamma(9, 4.5, size=n)                  # independent de l'anterior

df = pd.DataFrame({"n_articles": n_articles,
                   "import_comanda": import_comanda.round(2),
                   "minuts_lliurament": minuts_lliurament.round(1)})

print(df["n_articles"].cov(df["import_comanda"]).round(2))      # ~44 (positiva)
print(df["n_articles"].cov(df["minuts_lliurament"]).round(2))   # ~0-2 (propera a 0)
  • Generem l'import com 3,2 € per article més un soroll normal: hi ha relació real per construcció.
  • .cov() de pandas calcula la covariància mostral (divideix entre n−1, coherent amb el que hem vist a 02-01).

La limitació d'escala. La covariància entre articles i import surt ≈ 44... 44 què? Les seves unitats són "articles × euros". Si expresséssim l'import en cèntims, la covariància es multiplicaria per 100 sense que la relació canviés gens ni mica. La magnitud de la covariància no és interpretable per si sola: només ho és el seu signe. Ens cal una versió sense unitats: la correlació.

Correlació de Pearson: interpretació i rangs

La correlació de Pearson normalitza la covariància dividint-la pel producte de les desviacions estàndard:

r = cov(X, Y) / (sₓ · s_y)

El resultat és un nombre sense unitats, sempre entre −1 i +1, invariant a canvis d'escala:

  • r = +1: relació lineal positiva perfecta (tots els punts en una recta ascendent).
  • r = −1: relació lineal negativa perfecta.
  • r = 0: absència de relació lineal (hi pot haver una altra mena de relació).

| |r| aproximat | Interpretació habitual | |---|---| | 0,0 – 0,2 | Molt feble o nul·la | | 0,2 – 0,4 | Feble | | 0,4 – 0,6 | Moderada | | 0,6 – 0,8 | Forta | | 0,8 – 1,0 | Molt forta |

(Els llindars són orientatius i depenen del domini: en màrqueting un r = 0,3 pot ser or; en un sensor físic, decebedor.)

print(df["n_articles"].corr(df["import_comanda"]).round(3))      # ~0.85 (molt forta)
print(df["n_articles"].corr(df["minuts_lliurament"]).round(3))   # ~0.0

Dues advertències fonamentals sobre Pearson:

  1. Només detecta relacions lineals. Una relació en forma d'U perfecta (per exemple, despesa vs. edat, amb màxim a la mitjana edat) pot donar r ≈ 0.
  2. És sensible als outliers. Una única comanda d'hostaleria de 900 € pot inflar o enfonsar la correlació. Recorda el boxplot de la lliçó 02-01: inspecciona abans de calcular.

Per això el mantra: dibuixa sempre l'scatter plot (plt.scatter(x, y) o df.plot.scatter(...)) abans de refiar-te d'un coeficient.

Correlació de Spearman: quan fer-la servir

La correlació de Spearman aplica la fórmula de Pearson als rangs de les dades (la posició de cada valor un cop ordenats) en lloc dels valors bruts. Mesura si la relació és monòtona (quan X creix, Y creix —o decreix— de manera consistent), encara que no sigui lineal.

Fes-la servir quan:

  • La relació sembla monòtona però corba (p. ex., la despesa creix amb l'antiguitat, però saturant-se).
  • Hi ha outliers forts: els rangs els domestiquen (la comanda de 900 € passa a ser simplement "la primera").
  • Alguna variable és ordinal (satisfacció baixa/mitjana/alta): Pearson no està justificat, Spearman sí.
# Relacio monotona pero NO lineal: despesa ~ arrel de l'antiguitat
antiguitat = rng.uniform(1, 60, size=n)                        # mesos com a client
despesa_mensual = 20 * np.sqrt(antiguitat) + rng.normal(0, 6, size=n)
s = pd.DataFrame({"antiguitat": antiguitat, "despesa": despesa_mensual})

print(s["antiguitat"].corr(s["despesa"], method="pearson").round(3))   # ~0.93
print(s["antiguitat"].corr(s["despesa"], method="spearman").round(3))  # ~0.95

Amb una corba suau totes dues són altes, però Spearman captura millor la monotonia; amb outliers o corbes més agressives, la diferència entre totes dues s'engrandeix, i aquesta discrepància és en si mateixa un diagnòstic: si Spearman ≫ Pearson, sospita de no linealitat o d'outliers.

Criteri Pearson Spearman
Què mesura Relació lineal Relació monòtona
Dades requerides Numèriques Numèriques o ordinals
Sensibilitat als outliers Alta Baixa
Relació corba monòtona La infravalora La captura

Matrius de correlació i heatmaps amb pandas

Amb moltes variables, calcular correlacions per parelles a mà és inviable. La matriu de correlació les calcula totes de cop:

import matplotlib.pyplot as plt

# Dataset de clients de MercaFresh amb variables candidates per al churn
clients = pd.DataFrame({
    "comandes_mes": rng.poisson(6, n),
    "despesa_mitjana": rng.gamma(4, 12, n).round(2),
    "dies_des_ultima_comanda": rng.exponential(9, n).round(0),
    "incidencies_lliurament": rng.poisson(0.7, n),
    "minuts_lliurament_mitja": minuts_lliurament,
})
# Introduim relacions realistes a ma:
clients["dies_des_ultima_comanda"] += 30 / (clients["comandes_mes"] + 1)
clients["incidencies_lliurament"] += (clients["minuts_lliurament_mitja"] > 55).astype(int)

matriu = clients.corr(method="pearson").round(2)
print(matriu)

# Heatmap amb matplotlib pur
fig, ax = plt.subplots(figsize=(7, 6))
im = ax.imshow(matriu, cmap="coolwarm", vmin=-1, vmax=1)
ax.set_xticks(range(len(matriu)), matriu.columns, rotation=45, ha="right")
ax.set_yticks(range(len(matriu)), matriu.columns)
for i in range(len(matriu)):
    for j in range(len(matriu)):
        ax.text(j, i, matriu.iloc[i, j], ha="center", va="center", fontsize=9)
fig.colorbar(im, label="Correlacio de Pearson")
ax.set_title("Matriu de correlacio - clients MercaFresh")
plt.tight_layout()
plt.show()

Detalls del codi:

  • df.corr() retorna una matriu simètrica amb uns a la diagonal (tota variable correlaciona 1 amb ella mateixa). Accepta method="pearson" (per defecte) o "spearman".
  • imshow amb cmap="coolwarm" i límits vmin=-1, vmax=1 pinta de vermell el positiu, de blau el negatiu i de blanc el nul; fixar els límits és important perquè el color sigui comparable entre anàlisis.
  • El doble bucle escriu el valor numèric a cada cel·la: un heatmap sense nombres obliga a endevinar.
  • Si tens la llibreria seaborn instal·lada, sns.heatmap(matriu, annot=True, cmap="coolwarm", vmin=-1, vmax=1) fa el mateix en una línia.

Com llegir-la: busca (1) cel·les intenses fora de la diagonal —relacions fortes—, i (2) blocs de variables molt correlacionades entre si, que indiquen informació redundant.

Correlació no implica causalitat

Que X i Y es moguin juntes no demostra que X causi Y. Hi ha com a mínim quatre explicacions possibles:

graph LR
    subgraph "1. X causa Y"
        A[X] --> B[Y]
    end
    subgraph "2. Y causa X"
        C[Y] --> D[X]
    end
    subgraph "3. Causa comuna Z"
        E[Z] --> F[X]
        E --> G[Y]
    end
    subgraph "4. Casualitat"
        H[X] -.sense relacio real.- I[Y]
    end

Exemples:

  • Causa comuna (confusor). A MercaFresh, les vendes de gelat correlacionen amb les de gaspatxo. Cap no causa l'altra: l'estiu causa totes dues. Si el ML de demanda no inclou l'estació, aprendrà relacions espúries.
  • Direcció invertida. "Els clients que contacten amb suport fan més churn." Contactar amb suport causa la baixa? Més aviat al revés: els problemes que porten a la baixa causen també el contacte amb suport.
  • Casualitat pura. Amb centenars de variables, algunes correlacionaran fort per pur atzar (existeixen col·leccions senceres de "correlacions espúries" cèlebres, com ofegaments en piscines vs. pel·lícules d'un actor concret). Com més parelles miris, més troballes falses: la lliçó 02-04 donarà eines per jutjar si una relació observada és estadísticament creïble.

Per a la feina predictiva, una correlació estable pot ser suficient (si suport-contactat prediu churn, és útil encara que no en sigui la causa). Però per intervenir ("reduïm el churn si millorem X?") cal raonament causal o experiments controlats, com el test A/B que veurem a 02-04.

Rellevància per al Machine Learning

  • Selecció de variables. Les correlacions de cada variable amb l'objectiu (target) són una primera criba barata de quines característiques prometen. La construcció i selecció sistemàtica de característiques es desenvolupa a la lliçó 03-06.
  • Detecció de redundància (multicolinealitat). Si dues variables d'entrada correlacionen a 0,97 (p. ex., "import amb IVA" i "import sense IVA"), aporten gairebé la mateixa informació; mantenir-les totes dues desestabilitza alguns models lineals i complica interpretar coeficients. De moment, queda't amb la idea: blocs vermells al heatmap = candidats a podar; el detall dels seus efectes apareixerà en tractar la regressió i la regularització (mòduls 4 i 7).
  • Comprensió del domini. Abans de modelar, la matriu de correlació és la radiografia més ràpida de quina història expliquen les dades, i detecta també fuites d'informació (una variable "sospitosament" correlacionada amb el target al 0,99 sol ser una còpia disfressada d'ell).

Cas MercaFresh: quines variables es relacionen amb el churn?

L'equip vol una primera llista de senyals d'abandonament. El churn és binari (0/1); correlacionar una binària amb una numèrica mitjançant Pearson es coneix com a correlació punt-biserial i pandas la calcula amb el mateix .corr():

# Simulem el churn amb dependencia real de dues variables
logit = (-2.2
         + 0.09 * clients["dies_des_ultima_comanda"]
         + 0.8  * clients["incidencies_lliurament"]
         - 0.15 * clients["comandes_mes"])
p_churn = 1 / (1 + np.exp(-logit))              # transforma a probabilitat (0,1)
clients["churn"] = rng.binomial(1, p_churn)     # Bernoulli per client (llico 02-02)

correlacions_churn = (clients.corr(numeric_only=True)["churn"]
                      .drop("churn")
                      .sort_values(key=abs, ascending=False))
print(correlacions_churn.round(3))

Sortida aproximada:

dies_des_ultima_comanda     0.35
incidencies_lliurament      0.20
comandes_mes               -0.17
minuts_lliurament_mitja     0.09
despesa_mitjana            -0.02

Lectura:

  • dies_des_ultima_comanda és el senyal més fort: com més temps sense comprar, més probable la baixa. Correlació positiva moderada, molt valuosa en churn.
  • incidencies_lliurament suma senyal: els problemes de repartiment empenyen a l'abandonament.
  • comandes_mes correlaciona en negatiu: la freqüència protegeix.
  • minuts_lliurament_mitja gairebé no correlaciona directament amb el churn... però sí que causa incidències, que sí que correlacionen: un exemple de cadena causal que la correlació simple no desembulla.
  • despesa_mitjana gairebé no aporta res: candidata a descartar com a predictor de churn (encara que no del negoci).

Aquesta taula és exactament el tipus d'anàlisi exploratòria que al mòdul 4 alimentarà la regressió logística per predir el churn; aquí ens limitem a mesurar relacions.

Errors Comuns i Consells

  • Interpretar la magnitud de la covariància. Només el seu signe és interpretable; per a magnituds, fes servir sempre la correlació.
  • Concloure causalitat a partir de correlació. Abans de dir "X provoca Y", descarta la direcció inversa, els confusors i l'atzar; idealment, dissenya un experiment.
  • Refiar-se de r sense mirar l'scatter plot. El quartet d'Anscombe (quatre datasets amb la mateixa r i formes radicalment diferents) és el recordatori clàssic: dibuixa abans de concloure.
  • Fer servir Pearson amb variables ordinals o amb outliers extrems. Spearman és l'opció robusta en tots dos casos.
  • Confondre r ≈ 0 amb independència. Pearson només mesura relació lineal; una U perfecta dona r ≈ 0. Si sospites corbes, mira el gràfic i prova Spearman.
  • Minar correlacions en massa sense escepticisme. Amb 50 variables hi ha 1.225 parelles: per pur atzar diverses semblaran "fortes". Prioritza les que tinguin sentit de negoci i valida-les amb les tècniques de la propera lliçó.
  • Consell: ordena les correlacions amb el target per valor absolut (sort_values(key=abs)), com hem fet amb el churn: el signe importa per interpretar, però la força és el que prioritza.

Exercicis

Exercici 1

Sense fer servir codi: la covariància entre minuts_lliurament i incidencies de MercaFresh és 3,1. (a) Pots afirmar que la relació és forta? (b) Si convertim els minuts a segons, què li passa a la covariància? I a la correlació de Pearson?

Exercici 2

Genera dues variables amb relació quadràtica pura: x = np.linspace(-3, 3, 200) i y = x**2 + soroll normal (σ=0.5). Calcula Pearson i Spearman entre x i y. Explica els resultats i quina lliçó pràctica en treus.

Exercici 3

Amb el DataFrame clients del cas pràctic (inclosa la columna churn), calcula la matriu de correlació de Spearman i compara-la amb la de Pearson per a la parella (dies_des_ultima_comanda, churn). Canvia gaire? Per què Spearman pot ser bona idea amb dies_des_ultima_comanda?

Solucions

Solució 1

  • (a) No. La covariància no té una escala interpretable: 3,1 "minuts × incidències" pot correspondre a una relació forta o feble segons la dispersió de cada variable. Caldria la correlació.
  • (b) En passar minuts a segons (×60), la covariància es multiplica per 60. La correlació de Pearson no canvia gens ni mica: és invariant a canvis lineals d'escala, que és exactament la seva raó de ser.

Solució 2

import numpy as np, pandas as pd
rng = np.random.default_rng(1)
x = np.linspace(-3, 3, 200)
y = x**2 + rng.normal(0, 0.5, 200)
s = pd.DataFrame({"x": x, "y": y})
print(s["x"].corr(s["y"]).round(3))                      # ~0.0
print(s["x"].corr(s["y"], method="spearman").round(3))   # ~0.0

Totes dues surten properes a 0, tot i que y depèn totalment de x. Pearson falla perquè la relació no és lineal; Spearman també, perquè tampoc no és monòtona (y baixa i després puja). Lliçó: cap coeficient de correlació no substitueix l'scatter plot; r ≈ 0 significa "sense relació lineal/monòtona", no "sense relació".

Solució 3

parella = clients[["dies_des_ultima_comanda", "churn"]]
print(parella.corr(method="pearson").iloc[0, 1].round(3))    # ~0.35
print(parella.corr(method="spearman").iloc[0, 1].round(3))   # similar, p.ex. ~0.33

Els valors seran semblants (la relació simulada és aproximadament monòtona). Tot i així, Spearman és defensable aquí perquè dies_des_ultima_comanda prové d'una exponencial amb cua dreta (lliçó 02-02): els seus outliers (clients amb 60+ dies inactius) influeixen menys sobre els rangs que sobre els valors bruts, i això fa la mesura més robusta.

Conclusió

Ara ja saps mesurar relacions entre variables: la covariància dona el signe, la correlació de Pearson hi afegeix una escala universal entre −1 i +1 per a relacions lineals, i Spearman cobreix relacions monòtones, ordinals i dades amb outliers. Has construït matrius de correlació i heatmaps amb pandas, has identificat les variables que més es relacionen amb el churn de MercaFresh i, sobretot, has interioritzat que correlació no implica causalitat. Però queda un dubte incòmode: aquest r = 0,35 entre inactivitat i churn, és un senyal real o podria ser fruit de l'atzar d'aquesta mostra concreta? Respondre rigorosament aquesta pregunta —quantificar la incertesa del que mesurem en una mostra— és la feina de la inferència estadística, protagonista de la propera lliçó.

Curs de Machine Learning

Mòdul 1: Introducció al Machine Learning

Mòdul 2: Fonaments d'Estadística i Probabilitat

Mòdul 3: Preprocessament de Dades

Mòdul 4: Algorismes de Machine Learning Supervisat

Mòdul 5: Algorismes de Machine Learning No Supervisat

Mòdul 6: Avaluació i Validació de Models

Mòdul 7: Tècniques Avançades i Optimització

Mòdul 8: Implementació i Desplegament de Models

Mòdul 9: Projectes Pràctics

Mòdul 10: Recursos Addicionals

© Copyright 2026. Tots els drets reservats