La lliçó anterior va acabar amb una pregunta incòmoda: la correlació de 0,35 entre inactivitat i churn, és real o és un miratge de la mostra? La inferència estadística és la disciplina que respon aquest tipus de preguntes: com passar del que veiem en una mostra a afirmacions fiables sobre la població (distinció que vam definir a 02-01), quantificant la incertesa a cada pas. En aquesta lliçó aprendràs a estimar amb intervals de confiança, entendràs el teorema central del límit mitjançant simulació, i faràs contrastos d'hipòtesis (t-test i khi quadrat) amb scipy, aplicant-los al test A/B de la nova pàgina de MercaFresh. Aquestes eines t'acompanyaran durant tot el curs: comparar dos models de ML és, en el fons, comparar dues mostres de resultats.
Contingut
- Estimació puntual i per intervals
- El teorema central del límit (amb simulació)
- Contrastos d'hipòtesis: la lògica
- p-valor i errors tipus I i II
- El t-test a la pràctica: test A/B de MercaFresh
- El test khi quadrat per a variables categòriques
- Connexió amb Machine Learning
Estimació puntual i per intervals
Una estimació puntual resumeix un paràmetre poblacional amb un únic nombre calculat de la mostra: "la despesa mitjana per comanda és de 47,20 €". És útil però enganyosament precisa: una altra mostra hauria donat 46,80 o 47,90.
Una estimació per interval hi afegeix la incertesa: "la despesa mitjana és entre 45,90 i 48,50 € amb un 95 % de confiança". Aquest rang és l'interval de confiança (IC).
La peça clau és l'error estàndard (SE): la desviació estàndard de l'estimador, no de les dades. Per a la mitjana mostral:
SE = s / √n
on s és la desviació estàndard mostral i n la mida de la mostra. Fixa't en el √n: per reduir l'error a la meitat calen quatre vegades més dades. L'IC al 95 % per a la mitjana (amb n raonablement gran) és aproximadament:
x̄ ± 1,96 · SE
import numpy as np
from scipy import stats
rng = np.random.default_rng(42)
# Mostra: imports de 400 comandes de MercaFresh
imports_comanda = rng.gamma(shape=4.0, scale=12.0, size=400)
mitjana = imports_comanda.mean()
se = imports_comanda.std(ddof=1) / np.sqrt(len(imports_comanda))
# IC al 95% amb la distribucio t de Student (correcta per a qualsevol n)
ic = stats.t.interval(0.95, df=len(imports_comanda) - 1, loc=mitjana, scale=se)
print(f"Mitjana mostral: {mitjana:.2f} EUR")
print(f"IC 95%: ({ic[0]:.2f}, {ic[1]:.2f}) EUR")Sortida aproximada:
std(ddof=1)força la desviació mostral (n−1) perquèimports_comandaés un array de NumPy (recorda la diferència de valors per defecte vista a 02-01).stats.t.intervalfa servir la distribució t de Student, una campana amb cues una mica més pesades que la normal que corregeix la incertesa extra d'estimar s; amb n = 400 és gairebé idèntica a fer servir ±1,96.
Interpretació correcta del 95 %: si repetíssim el mostreig moltes vegades i calculéssim un IC cada vegada, el 95 % d'aquests intervals contindria la veritable mitjana poblacional. No és exactament "hi ha un 95 % de probabilitat que μ sigui dins aquest interval" (μ és fixa; l'aleatori és l'interval), tot i que a la pràctica es llegeixi així de manera informal.
El teorema central del límit (amb simulació)
Per què podem fer servir campanes (normal o t) per a la mitjana, si els imports de MercaFresh són asimètrics amb cua dreta? Pel resultat més important de l'estadística:
Teorema central del límit (TCL): la distribució de la mitjana de n observacions independents s'aproxima a una normal quan n creix, sigui quina sigui la distribució original de les dades (mentre tingui variància finita). El seu centre és μ i la seva desviació és σ/√n.
En lloc de demostrar-ho, vegem-ho:
import matplotlib.pyplot as plt
rng = np.random.default_rng(0)
# Poblacio MOLT asimetrica: imports exponencials amb mitjana 40 EUR
poblacio = lambda size: rng.exponential(scale=40, size=size)
fig, axes = plt.subplots(1, 4, figsize=(14, 3.2), sharey=False)
# Panell 0: la distribucio original (res de campana)
axes[0].hist(poblacio(10_000), bins=60, color="gray")
axes[0].set_title("Dades originals\n(exponencial)")
# Panells 1-3: distribucio de la MITJANA de mostres de mida n
for ax, n in zip(axes[1:], [5, 30, 200]):
mitjanes = np.array([poblacio(n).mean() for _ in range(5_000)])
ax.hist(mitjanes, bins=60, color="steelblue")
ax.set_title(f"Mitjanes de mostres\nn = {n}")
plt.tight_layout()
plt.show()Què fa el codi: extreu 5.000 mostres de mida n d'una població exponencial (asimètrica total) i dibuixa l'histograma de les seves 5.000 mitjanes. El resultat:
- Amb n = 5, l'histograma de mitjanes encara hereta asimetria.
- Amb n = 30, ja és una campana força decent.
- Amb n = 200, és una normal de llibre, molt més estreta (efecte σ/√n).
Aquest és el fonament que legitima els intervals de confiança i els tests d'aquesta lliçó fins i tot amb dades no normals, sempre que n no sigui minúscula. També explica el paper estel·lar de la distribució normal anunciat a 02-02.
Contrastos d'hipòtesis: la lògica
Un contrast d'hipòtesis és un procediment per decidir, amb regles explícites, si les dades aporten prou evidència contra una afirmació per defecte.
- Hipòtesi nul·la (H₀): l'afirmació "avorrida", de no-efecte. "La nova pàgina de producte no canvia la despesa mitjana."
- Hipòtesi alternativa (H₁): el que sospitem. "La nova pàgina canvia la despesa mitjana."
La lògica és anàloga a un judici: H₀ és innocent fins que es demostri el contrari. Calculem com d'estranyes serien les nostres dades si H₀ fos certa; si són prou estranyes, rebutgem H₀.
graph TD
A["Formular H0 i H1"] --> B["Triar test i nivell alfa (p.ex. 0.05)"]
B --> C["Recollir dades i calcular estadistic"]
C --> D["Calcular p-valor"]
D --> E{"p-valor < alfa?"}
E -- "Si" --> F["Rebutjar H0:<br>efecte estadisticament significatiu"]
E -- "No" --> G["No rebutjar H0:<br>evidencia insuficient"]
Important: "no rebutjar H₀" no és "demostrar H₀". L'absència d'evidència no és evidència d'absència; potser l'efecte existeix però la mostra és petita.
p-valor i errors tipus I i II
El p-valor és la probabilitat d'observar dades tan extremes com les nostres (o més) suposant que H₀ és certa. Un p-valor de 0,03 significa: "si la nova pàgina no tingués cap efecte, només en un 3 % dels experiments veuríem una diferència com aquesta per pur atzar".
El que el p-valor no és:
- No és la probabilitat que H₀ sigui certa.
- No mesura la mida de l'efecte: amb una n gegant, una diferència irrisòria de 0,02 € pot donar p < 0,001.
El llindar α (típicament 0,05) fixa quant de risc de falsa alarma acceptem, i d'aquí surten els dos errors possibles:
| H₀ és certa (no hi ha efecte) | H₀ és falsa (hi ha efecte) | |
|---|---|---|
| Rebutgem H₀ | Error tipus I (falsa alarma), prob. α | Encert (potència del test) |
| No rebutgem H₀ | Encert | Error tipus II (efecte no detectat), prob. β |
A MercaFresh: un error tipus I seria redissenyar tota la web per una millora que no existia; un error tipus II, descartar una pàgina que realment venia més. Abaixar α redueix les falses alarmes però augmenta els efectes perduts: és un compromís, no una veritat revelada. (Aquesta mateixa tensió reapareixerà al mòdul 6 com l'equilibri entre falsos positius i falsos negatius d'un classificador.)
El t-test a la pràctica: test A/B de MercaFresh
Cas: MercaFresh llança una nova pàgina de producte i vol saber si va millorar la despesa mitjana per comanda. Durant dues setmanes, la meitat dels visitants veu la pàgina antiga (grup A, control) i l'altra meitat la nova (grup B, tractament), assignats a l'atzar. L'assignació aleatòria és la clau que permet parlar de causalitat, tancant el cercle de "correlació no és causalitat" de 02-03.
El t-test de dues mostres independents contrasta H₀: "les mitjanes de tots dos grups són iguals".
rng = np.random.default_rng(7)
# Simulem l'experiment: la pagina nova apuja la despesa mitjana ~2 EUR
grup_A = rng.gamma(shape=4.0, scale=12.0, size=980) # mitjana ~48 EUR
grup_B = rng.gamma(shape=4.0, scale=12.5, size=1020) # mitjana ~50 EUR
print(f"Mitjana A: {grup_A.mean():.2f} | Mitjana B: {grup_B.mean():.2f}")
print(f"Diferencia observada: {grup_B.mean() - grup_A.mean():.2f} EUR")
# t-test de Welch (equal_var=False): no assumeix variancies iguals
t_stat, p_valor = stats.ttest_ind(grup_B, grup_A, equal_var=False)
print(f"t = {t_stat:.2f}, p-valor = {p_valor:.4f}")Sortida aproximada:
Interpretació pas a pas:
- La diferència observada és d'uns 2,50 € per comanda a favor de la nova pàgina.
- El p-valor ≈ 0,02 < 0,05: si la pàgina nova no tingués efecte, una diferència així només apareixeria en ~2 % dels experiments. Rebutgem H₀: la millora és estadísticament significativa.
- Decisió de negoci: significativa i rellevant (2,50 € × milers de comandes/mes justifica el canvi). Comprova sempre totes dues coses: significació estadística i mida de l'efecte.
Notes tècniques:
stats.ttest_indimplementa el t-test per a mostres independents;equal_var=False(test de Welch) és l'opció segura per defecte perquè no exigeix variàncies iguals entre grups.- Dades asimètriques com aquestes? El TCL ens protegeix: amb ~1.000 observacions per grup, les mitjanes es comporten com a normals.
- També existeix
stats.ttest_relper a mostres aparellades (el mateix client mesurat abans i després) istats.ttest_1sampper comparar una mostra contra un valor fix ("el temps mitjà de lliurament supera els 40 min promesos?").
El test khi quadrat per a variables categòriques
El t-test compara mitjanes de variables numèriques. Quan totes dues variables són categòriques, el test adequat és el khi quadrat d'independència: contrasta H₀: "les dues variables són independents" a partir de la seva taula de contingència.
Cas MercaFresh: la taxa de conversió (comprar o no) depèn de la versió de la pàgina?
import pandas as pd
# Taula de contingencia observada del test A/B
# compra no_compra
taula = pd.DataFrame({"compra": [312, 368],
"no_compra": [2688, 2632]},
index=["pagina_A", "pagina_B"])
print(taula)
print(f"Conversio A: {312/3000:.1%} | Conversio B: {368/3000:.1%}")
chi2, p_valor, gl, esperats = stats.chi2_contingency(taula)
print(f"chi2 = {chi2:.2f}, p-valor = {p_valor:.4f}, graus de llibertat = {gl}")Sortida:
compra no_compra
pagina_A 312 2688
pagina_B 368 2632
Conversio A: 10.4% | Conversio B: 12.3%
chi2 = 5.15, p-valor = 0.0232, graus de llibertat = 1Com funciona per dins (intuïció): el test calcula quina taula esperaríem si hi hagués independència (les mateixes proporcions a totes dues files: esperats la retorna) i mesura quant es desvien els recomptes observats dels esperats. Desviació gran → khi² gran → p-valor petit.
Aquí p ≈ 0,023 < 0,05: la conversió sí que depèn de la pàgina; la versió B converteix significativament més (12,3 % vs. 10,4 %). El khi quadrat també serveix per a preguntes com "el mètode de pagament depèn de la província?" o "el churn depèn del nivell de fidelitat?".
| Pregunta | Variables | Test |
|---|---|---|
| Difereix la despesa mitjana entre dos grups? | Numèrica vs. binària | t-test de dues mostres |
| Va canviar la mitjana després d'una intervenció (mateixos subjectes)? | Numèrica, aparellada | t-test aparellat |
| La mitjana supera un valor de referència? | Numèrica vs. constant | t-test d'una mostra |
| Dues categòriques són independents? | Categòrica vs. categòrica | Khi quadrat |
Connexió amb Machine Learning
La inferència impregna la pràctica del ML més del que sembla:
- Comparar models. "El model nou encerta el 84,1 % i el vell el 83,6 %": millora real o soroll de la mostra d'avaluació? La diferència entre dues accuracies és una diferència entre dues proporcions mostrals, exactament el terreny d'aquesta lliçó. Al mòdul 6 veurem com la validació creuada (06-03) genera diverses mesures per model, cosa que permet raonar sobre la variabilitat del rendiment en lloc de refiar-se d'un únic nombre.
- Tests A/B de models en producció. Desplegar el model nou per al 50 % del trànsit i comparar mètriques de negoci és literalment l'experiment d'aquesta lliçó; ho reprendrem al mòdul 8.
- Escepticisme quantificat. L'hàbit mental del p-valor —"podria ser atzar, això?"— és la millor vacuna contra conclusions precipitades en explorar dades, incloses les correlacions "prometedores" de la lliçó anterior.
Errors Comuns i Consells
- Interpretar el p-valor com a P(H₀ certa). És P(dades així d'extremes | H₀ certa): condiciona en la direcció contrària. Aquesta distinció connecta directament amb la propera lliçó (Bayes).
- Confondre significació amb rellevància. Amb una n enorme, tot és "significatiu". Reporta sempre la mida de l'efecte (la diferència en euros, en punts de conversió) juntament amb el p-valor.
- Mirar els resultats cada dia i aturar el test quan p < 0,05. Aquest "peeking" infla dràsticament els falsos positius: fixa la durada o la mida mostral abans de començar.
- Fer molts tests i quedar-se amb els que surten. Amb 20 tests a α = 0,05, el que cal esperar és ~1 fals positiu. Si fas comparacions múltiples, ajusta-ho (p. ex., correcció de Bonferroni: fer servir α/20) o com a mínim declara-ho.
- Fer servir el t-test amb mostres minúscules i molt asimètriques. El TCL necessita una n suficient; amb n < 20-30 i cues fortes, desconfia (existeixen tests no paramètrics com Mann-Whitney,
stats.mannwhitneyu, com a alternativa). - Oblidar l'assignació aleatòria en un A/B. Si el grup B són "els usuaris de l'app nova", ja no compares pàgines, compares tipus d'usuari: el confusor de 02-03 en acció.
- Consell: abans de llançar un experiment, escriu H₀, H₁, α i la mida de mostra en un document. Els experiments definits a posteriori troben el que volen trobar.
Exercicis
Exercici 1
Amb una mostra de 100 temps de lliurament de MercaFresh (mitjana mostral 41,3 min, desviació estàndard mostral 9,8 min), calcula a mà l'error estàndard i un IC del 95 % aproximat per a la mitjana (fes servir ±1,96·SE). MercaFresh promet "lliurament mitjà per sota de 40 min": l'interval és compatible amb aquesta promesa?
Exercici 2
Simula amb NumPy el TCL per a una distribució uniforme entre 0 i 10: dibuixa l'histograma de les mitjanes de 5.000 mostres de mida n = 2 i n = 50. Què observes en la forma i en l'amplada? Quina amplada teòrica prediu el TCL per a n = 50? (σ d'una uniforme(0,10) ≈ 2,89).
Exercici 3
MercaFresh prova dos assumptes d'email per reactivar clients inactius. Assumpte A: 1.500 enviaments, 129 reactivacions. Assumpte B: 1.500 enviaments, 168 reactivacions. Planteja H₀ i H₁, construeix la taula de contingència, executa el khi quadrat amb scipy i conclou amb α = 0,05.
Solucions
Solució 1
- SE = 9,8 / √100 = 0,98 min.
- IC 95 % ≈ 41,3 ± 1,96 · 0,98 = 41,3 ± 1,92 → (39,4, 43,2) minuts.
- L'interval conté valors per sota de 40, així que no podem descartar que la mitjana real compleixi la promesa... però la major part de l'interval és per sobre de 40 i l'estimació puntual també. Formalment: un t-test d'una mostra contra 40 no rebutjaria H₀ al 5 % (l'evidència d'incompliment no és concloent), tot i que operativament MercaFresh faria bé de vigilar el repartiment.
Solució 2
import numpy as np, matplotlib.pyplot as plt
rng = np.random.default_rng(3)
fig, axes = plt.subplots(1, 2, figsize=(9, 3))
for ax, n in zip(axes, [2, 50]):
mitjanes = rng.uniform(0, 10, size=(5_000, n)).mean(axis=1)
ax.hist(mitjanes, bins=50, color="steelblue")
ax.set_title(f"n = {n} (std = {mitjanes.std():.2f})")
plt.tight_layout(); plt.show()Amb n = 2 la distribució de mitjanes és triangular (encara no normal); amb n = 50 és una campana clara i molt més estreta. El TCL prediu una desviació σ/√n = 2,89/√50 ≈ 0,41, que coincidirà amb la std empírica del panell dret. Truc del codi: generar una matriu 5.000×n i fer la mitjana per files (mean(axis=1)) evita el bucle.
Solució 3
- H₀: la taxa de reactivació és independent de l'assumpte (mateixa taxa a A i B). H₁: les taxes difereixen.
import pandas as pd
from scipy import stats
taula = pd.DataFrame({"reactiva": [129, 168],
"no_reactiva": [1371, 1332]},
index=["assumpte_A", "assumpte_B"])
chi2, p, gl, esp = stats.chi2_contingency(taula)
print(f"Taxa A: {129/1500:.1%} | Taxa B: {168/1500:.1%}")
print(f"chi2 = {chi2:.2f}, p = {p:.4f}")Resultat: taxes del 8,6 % vs. 11,2 %, khi² ≈ 5,4, p ≈ 0,020 < 0,05. Rebutgem H₀: l'assumpte B reactiva significativament més clients. Amb una mida d'efecte de +2,6 punts percentuals sobre 1.500 enviaments, a més de significatiu és accionable: MercaFresh hauria d'adoptar l'assumpte B (idealment confirmant-ho sense "peeking" en una segona onada).
Conclusió
Has recorregut el nucli de la inferència estadística: estimar amb intervals de confiança en lloc de nombres secs, entendre per què el teorema central del límit fa que les mitjanes es comportin com a normals, i executar contrastos d'hipòtesis complets —t-test per a mitjanes i khi quadrat per a categòriques— interpretant p-valors i vigilant els errors tipus I i II. El test A/B de MercaFresh ha mostrat el circuit complet, de la hipòtesi a la decisió de negoci, i has deixat anotada la connexió amb el ML: comparar models és comparar mostres. Però la inferència clàssica deixa una pregunta sense respondre de cara: com actualitzar el que ja crèiem en rebre evidència nova? Aquesta és exactament l'especialitat del teorema de Bayes, amb el qual tancarem el mòdul a la propera lliçó.
Curs de Machine Learning
Mòdul 1: Introducció al Machine Learning
- Què és el Machine Learning?
- Història i evolució del Machine Learning
- Tipus de Machine Learning
- Aplicacions del Machine Learning
- El flux de treball d'un projecte de Machine Learning
Mòdul 2: Fonaments d'Estadística i Probabilitat
- Conceptes bàsics d'estadística
- Distribucions de probabilitat
- Correlació i covariància
- Inferència estadística
- Teorema de Bayes
Mòdul 3: Preprocessament de Dades
- Neteja de dades
- Gestió de dades mancants
- Transformació de dades
- Codificació de variables categòriques
- Normalització i estandardització
- Enginyeria de característiques
Mòdul 4: Algorismes de Machine Learning Supervisat
- Regressió lineal
- Regressió logística
- Arbres de decisió
- Màquines de suport vectorial (SVM)
- K veïns més propers (K-NN)
- Naive Bayes
- Xarxes neuronals
Mòdul 5: Algorismes de Machine Learning No Supervisat
- Clustering: K-means
- Clustering jeràrquic
- Anàlisi de components principals (PCA)
- Anàlisi d'agrupament DBSCAN
- Visualització de dades amb t-SNE i UMAP
Mòdul 6: Avaluació i Validació de Models
- Divisió de dades: entrenament, validació i prova
- Mètriques d'avaluació
- Validació creuada
- Corba ROC i AUC
- Overfitting i underfitting
Mòdul 7: Tècniques Avançades i Optimització
- Regularització: Ridge, Lasso i Elastic Net
- Ensemble Learning
- Gradient Boosting
- Xarxes neuronals profundes (Deep Learning)
- Optimització d'hiperparàmetres
Mòdul 8: Implementació i Desplegament de Models
- Frameworks i biblioteques populars
- Implementació de models en producció
- Manteniment i monitoratge de models
- Consideracions ètiques i de privadesa
Mòdul 9: Projectes Pràctics
- Projecte 1: Predicció de preus d'habitatges
- Projecte 2: Classificació d'imatges
- Projecte 3: Anàlisi de sentiments a les xarxes socials
- Projecte 4: Detecció de fraus
- Projecte 5: Segmentació de clients
