Vam acabar la lliçó anterior constatant que la majoria dels sistemes que NovaMarket construirà són subsimbòlics: aprenen de dades. Aquesta lliçó es dedica a aquesta matèria primera. La Marta fa setmanes que ho diu a cada reunió: "abans de parlar de models, parlem de quines dades tenim i en quin estat estan". Té raó, i en aquesta lliçó veurem per què. Explicarem per què les dades són el combustible de la IA, quins tipus de dades existeixen i com s'organitzen, quin és el cicle de vida de la dada en una organització, com se'n mesura la qualitat i quins problemes concrets amaguen els fitxers de NovaMarket, d'on vénen els biaixos que després es converteixen en decisions injustes, quines obligacions conceptuals imposa la protecció de dades personals i per què la qualitat importa més que la quantitat. Tancarem amb un programa en Python que llegeix un comandes.csv d'exemple i produeix un petit informe de qualitat, exactament el tipus de comprovació que hauria de precedir qualsevol projecte d'IA.

Contingut

  1. Per què les dades són el combustible de la IA
  2. Tipus de dades
  3. Dades etiquetades i no etiquetades
  4. El cicle de vida de la dada: recollida, emmagatzematge, qualitat, governança
  5. Dimensions de la qualitat de les dades, amb els problemes reals de NovaMarket
  6. Biaix a les dades: l'origen de la injustícia algorísmica
  7. Dades personals i RGPD: minimització, anonimització i pseudonimització
  8. Quantitat davant de qualitat; dades sintètiques
  9. Exemple en Python: un informe de qualitat de comandes.csv

  1. Per què les dades són el combustible de la IA

Recorda l'esquema de 01-02: en la programació tradicional, dades + programa → resultats; en l'aprenentatge automàtic, dades + resultats → model, i després el model produeix resultats per a dades noves. El model no conté més coneixement que el que hi havia a les dades amb què es va construir. D'aquí se'n deriven tres conseqüències que convé gravar-se:

  • Sense dades no hi ha model. El recomanador de 01-03 no podia recomanar res per al televisor fins que hi va haver comandes amb televisors (l'"arrencada en fred").
  • Amb dades dolentes hi ha models dolents. L'expressió clàssica és garbage in, garbage out: si el 50 % de la columna "causa" d'incidencies.csv és buida, cap algorisme diagnosticarà bé les incidències.
  • El model hereta tot el que hi ha a les dades, inclosos els errors, les llacunes i els biaixos. Si històricament NovaMarket va revisar més les comandes de certs codis postals, un model entrenat amb aquest històric aprendrà a sospitar d'aquests codis postals (ho desenvoluparem a la secció 6 i a 02-04).

Per això, en un projecte real d'IA, entre el 60 % i el 80 % de l'esforç es dedica a obtenir, entendre, netejar i preparar dades, no a entrenar models. És el primer que la Marta va voler que en Diego entengués: el "cost de la IA" és en gran part el cost de posar en ordre les dades, i aquest cost s'amortitza en tots els projectes posteriors.

  1. Tipus de dades

Les dades es classifiquen de diverses maneres complementàries. Conèixer-les ajuda a saber quina tècnica es pot aplicar i quina preparació necessitaran.

2.1 Per la seva estructura

Tipus Què és Exemples a NovaMarket Com s'hi treballa
Estructurades Taules amb files i columnes de tipus fix comandes.csv, clients.csv, productes.csv, la base de dades d'estoc Consultes SQL, fulls de càlcul, ML clàssic directament
Semiestructurades Tenen etiquetes o jerarquia, però no un esquema rígid Respostes JSON de l'API de la missatgeria, fitxers de log del servidor web, correus amb capçaleres Cal extreure'n camps abans d'analitzar-les
No estructurades Sense organització predefinida Text lliure de ressenyes.csv, transcripcions del xat d'atenció al client, fotos de productes retornats, àudios de trucades Requereixen PLN, visió per computador o extracció prèvia

La majoria del volum de dades d'una empresa és no estructurat, i la majoria del valor històric s'ha extret de les estructurades. El deep learning (mòdul 5) ho va canviar en fer explotables el text i la imatge.

2.2 Per la naturalesa del valor

Tipus Descripció Exemples Observació
Numèriques Quantitats amb què té sentit operar Import de la comanda, pes del paquet, unitats venudes Poden ser contínues (import) o discretes (unitats)
Categòriques Etiquetes d'un conjunt finit Ciutat, categoria de producte, estat de la comanda, causa de la incidència Sense ordre (nominal: ciutat) o amb ordre (ordinal: talla S/M/L, satisfacció 1-5)
Text Cadenes de llenguatge natural Ressenyes, missatges del xat, descripcions de producte No estructurat; requereix PLN
Imatge / àudio / vídeo Senyals percebuts Fotos de productes, fotos de danys en devolucions, trucades No estructurat; requereix visió o processament de senyal
Sèries temporals Valors numèrics ordenats en el temps Vendes diàries per producte, trànsit web per hora, temps de lliurament L'ordre importa; base de la previsió de demanda
Dates i identificadors Marques de temps, claus data, id_comanda, id_client Ni numèrics ni categòrics "de debò": serveixen per relacionar i ordenar

Un mateix fitxer en barreja diversos: comandes.csv té identificadors, una data, un import numèric, una ciutat categòrica i una columna retornat categòrica binària. Saber què és cada columna és el primer pas de qualsevol anàlisi, i és sorprenent quants problemes vénen de tractar un identificador com a nombre (sumar codis postals) o un nombre com a text (ordenar imports alfabèticament: "1000" abans que "200").

  1. Dades etiquetades i no etiquetades

Una distinció decisiva per a l'aprenentatge automàtic:

  • Dades etiquetades: cada exemple porta associada la resposta correcta que volem que el model aprengui a produir. A comandes.csv, la columna retornat és l'etiqueta si volem predir devolucions. A ressenyes.csv, una columna "sentiment" (positiu/negatiu) posada per una persona seria l'etiqueta.
  • Dades no etiquetades: només tenim els exemples, sense resposta. Milers de ressenyes sense classificar, l'historial de navegació sense saber què va acabar comprant el client.

Amb dades etiquetades es pot fer aprenentatge supervisat (aprendre la relació entre les característiques i l'etiqueta); amb dades no etiquetades, aprenentatge no supervisat (descobrir estructura: grups de clients semblants, productes que es compren junts). Tots dos es desenvolupen a 04-02; aquí n'hi ha prou amb saber que les etiquetes són cares (sovint cal posar-les a mà) i valuoses, i que la seva qualitat ho condiciona tot.

Un exemple de com n'és, de cara i delicada, l'etiqueta: incidencies.csv té uns 400 registres i la meitat de la columna causa buida. Aquesta columna és l'etiqueta que el cas d'ús 9 (diagnòstic d'incidències) necessitaria aprendre. Amb 200 exemples etiquetats de manera desigual (els operadors omplien la causa quan tenien temps, és a dir, més els dies tranquils i menys en els pics), el sistema aprendria d'una mostra esbiaixada. En Diego va proposar una solució no tècnica però correcta: fer obligatòria la causa al formulari a partir d'ara i organitzar una sessió per etiquetar retrospectivament les 200 que falten.

  1. El cicle de vida de la dada: recollida, emmagatzematge, qualitat, governança

Les dades no apareixen a punt per fer servir; travessen un cicle, i cada etapa pot introduir o corregir problemes:

flowchart LR
    R[Recollida<br/>formularis, sensors,<br/>logs, APIs, compres] --> A[Emmagatzematge<br/>bases de dades, fitxers,<br/>magatzem de dades]
    A --> C[Qualitat<br/>validació, neteja,<br/>deduplicació]
    C --> U[Ús<br/>anàlisi, models,<br/>decisions]
    U --> G[Governança<br/>propietat, accés,<br/>retenció, compliment]
    G -.-> R
  • Recollida: com entren les dades. Cada canal té els seus vicis: el formulari web de devolucions permet deixar camps buits; el terminal del magatzem desa el pes en grams i la web en quilos; la missatgeria externa envia les dates en format DD/MM/AAAA mentre que el sistema intern fa servir AAAA-MM-DD. La regla d'or és validar en origen: és molt més barat obligar a omplir la causa de la incidència en el moment que reconstruir-la mesos després.
  • Emmagatzematge: on i com es desen. Bases de dades transaccionals (les que suporten la botiga), magatzems de dades per a anàlisi, fitxers plans com els CSV amb què treballem al curs. Aquí importen la traçabilitat (d'on ve cada dada?, quan es va carregar?) i l'esquema (què vol dir cada columna, en quines unitats).
  • Qualitat: comprovar i corregir (secció 5). Idealment és un procés continu, no un arranjament puntual abans de cada projecte.
  • Ús: anàlisi, informes, entrenament de models, decisions. És el que justifica tot l'anterior.
  • Governança: el conjunt de normes i responsabilitats sobre les dades: qui és propietari de cada conjunt de dades (la Marta va proposar que cada àrea ho sigui dels seus: operacions d'incidencies.csv, màrqueting de ressenyes.csv), qui pot accedir a què, quant de temps es conserven, com es documenten (un diccionari de dades amb la definició de cada columna) i com es compleix la legislació (secció 7). La governança tanca el cicle perquè les seves normes milloren la recollida següent.

Sense governança, cada projecte d'IA torna a descobrir els mateixos problemes. Amb ella, el segon projecte de NovaMarket (previsió de demanda) reutilitza les dades netes del primer (recomanació).

  1. Dimensions de la qualitat de les dades, amb els problemes reals de NovaMarket

"Dades de qualitat" no és un judici vague: es descompon en dimensions mesurables. Les cinc més usades, amb els problemes que la Marta va trobar en obrir els CSV de NovaMarket per primera vegada:

Dimensió Pregunta Problema real trobat a NovaMarket Conseqüència si no es corregeix Possible correcció
Completesa Falten valors? La meitat de la columna causa d'incidencies.csv és buida; algunes comandes sense codi_postal El diagnòstic d'incidències no pot aprendre; els models que fan servir codi postal descarten files Fer el camp obligatori; etiquetar retrospectivament; per a la resta, decidir si imputar o descartar (04-03)
Exactitud Els valors són correctes? Preus de productes.csv en cèntims en una part del catàleg (importada d'un proveïdor) i en euros a la resta: un cable a "1299" Un model de previsió aprèn que un cable val més que un portàtil; les mitjanes es disparen Unificar la unitat; detectar valors fora de rang amb regles
Consistència Els mateixos fets es representen igual a tot arreu? Dates barrejades: 2026-03-02, 02/03/2026, 03-03-2026; ciutat com a "Zaragoza", "zaragoza", "ZARAGOZA " Ordenar per data falla; "Zaragoza" i "zaragoza" compten com a ciutats diferents Normalitzar formats i majúscules en carregar; validar en origen
Actualitat Les dades reflecteixen l'estat present? Adreces de clients que no s'actualitzen; estoc del magatzem de Getafe amb retard d'hores Rutes mal planificades; assignació de comandes a magatzems sense estoc Definir la freqüència d'actualització acceptable per dada; marcar la data de l'última modificació
Unicitat Hi ha duplicats? Clients duplicats a clients.csv (mateix correu amb majúscules diferents o amb un espai final; mateixa persona amb dos correus); una mateixa comanda carregada dues vegades El recomanador veu dos clients on n'hi ha un; es compten vendes de més Definir la clau d'unicitat; deduplicar amb normalització; evitar la doble càrrega

Dos comentaris importants:

  • La qualitat es mesura, no se suposa. La Marta va fer el que farem a la secció 9: comptar buits, duplicats i formats per columna i posar-hi números. Descobrir que un 58 % de les files d'una mostra tenia algun problema va ser el que va convèncer en Diego de dedicar temps a la neteja abans que als models.
  • La qualitat depèn de l'ús. Un codi postal buit és irrellevant per classificar ressenyes i greu per planificar rutes. No existeix "el" nivell de qualitat: existeix el suficient per a cada cas d'ús.

Com es netegen aquests problemes per preparar un model (imputació de valors, codificació de categories, escalat, tractament d'atípics) és el contingut de 04-03; aquí ens quedem a detectar-los i mesurar-los.

  1. Biaix a les dades: l'origen de la injustícia algorísmica

Un biaix a les dades és una desviació sistemàtica entre el que les dades representen i la realitat que haurien de representar. No és un problema de "dades brutes" (les dades poden estar netíssimes i esbiaixades) sinó de què es va recollir, de qui i com es va etiquetar. Com que el model hereta el que hi ha a les dades, el biaix es converteix en decisions sistemàticament desviades, i quan aquestes decisions afecten persones, en injustícia algorísmica. Els tres orígens principals:

Tipus de biaix Què passa Exemple a NovaMarket Efecte en el model
De mostreig La mostra no representa la població: uns grups estan sobrerepresentats i d'altres gairebé absents Les ressenyes les escriuen sobretot clients molt satisfets o molt enfadats; els clients de ciutats sense repartiment propi gairebé no apareixen a incidencies.csv perquè les seves incidències les gestiona la missatgeria El classificador de ressenyes no reconeix opinions temperades; el diagnòstic d'incidències no sap res de les ciutats amb missatgeria
Històric Les dades reflecteixen fidelment un passat que era injust o diferent Durant anys l'equip va revisar manualment més les comandes de certs codis postals; a l'històric aquests codis tenen més "frau detectat" simplement perquè s'hi va buscar més El model de risc aprèn que aquests codis postals són de risc, i en revisar-hi més hi troba més, reforçant el biaix (bucle de retroalimentació)
D'etiquetatge Les etiquetes les posen persones (o processos) amb criteris inconsistents o prejudicis La causa de les incidències l'omplen operadors diferents: uns posen "error de magatzem" on d'altres posen "producte danyat"; els dies de pic s'etiqueta pitjor El model aprèn el criteri de cada operador, no la causa real

Altres biaixos freqüents: el de supervivència (només veiem les dades que van "sobreviure": analitzem els clients que continuen comprant i oblidem per què se'n van anar els que se'n van anar), el de mesura (un sensor o formulari captura pitjor un grup: el formulari de devolucions a l'app és més incòmode que al web, així que els clients de mòbil l'omplen menys) i el de confirmació en l'anàlisi (buscar a les dades el que ja crèiem, com la regla de 300 € d'en Diego).

L'essencial en aquesta lliçó: el biaix entra per les dades i es manifesta a les decisions. Com avaluar-ne les conseqüències ètiques, com mesurar la disparitat entre grups i què fer-hi és el contingut de la propera lliçó, 02-04.

  1. Dades personals i RGPD: minimització, anonimització i pseudonimització

Bona part de les dades de NovaMarket són dades personals: identifiquen o permeten identificar una persona (nom, correu, adreça, telèfon, historial de compres, fins i tot una combinació de codi postal, data de naixement i sexe). A la Unió Europea el seu tractament està regulat pel Reglament General de Protecció de Dades (RGPD). Aquí no estudiarem la norma (que es reprèn en el marc regulador de 02-04) sinó els principis que afecten directament el treball amb dades per a IA:

  • Finalitat i base jurídica: les dades es recullen per a una finalitat concreta i amb una base legal (contracte, consentiment, interès legítim...). Fer servir l'historial de compres per recomanar productes pot encaixar; fer-lo servir per a alguna cosa no prevista (vendre'l, perfilar amb finalitats alienes) no.
  • Minimització: recollir i fer servir només les dades necessàries per a la finalitat. Si per preveure la demanda n'hi ha prou amb la data, el producte, la ciutat i les unitats, no cal carregar el nom i el correu del client al conjunt d'entrenament. Menys dades personals vol dir menys risc i menys obligacions.
  • Limitació del termini de conservació: no desar dades personals més temps del necessari. Això xoca amb l'instint de "desar-ho tot per si serveix per entrenar alguna cosa"; cal definir terminis.
  • Drets de les persones: accés, rectificació, supressió ("oblit"), oposició al perfilat i a decisions automatitzades amb efectes significatius. Un model entrenat amb les dades d'un client que en demana la supressió planteja preguntes pràctiques que el projecte ha de preveure.
  • Seguretat: protegir les dades davant d'accessos indeguts, especialment quan es copien a entorns d'anàlisi o s'envien a serveis al núvol (recorda la dicotomia núvol/dispositiu de 02-02).

Dues tècniques que redueixen el risc i que apareixeran constantment:

Tècnica Què fa Exemple Continua sent dada personal?
Pseudonimització Substitueix els identificadors directes per un codi; la correspondència es desa a part i protegida clients.csv amb id_client = C1001 en lloc del nom i el correu; la taula que relaciona C1001 amb la persona la custodia un altre equip (es pot revertir amb la taula), però amb menys risc; el RGPD ho reconeix com a mesura de seguretat
Anonimització Elimina o transforma les dades de manera que no sigui possible tornar a identificar la persona, ni combinant-les amb d'altres Agregar vendes per ciutat i setmana sense cap identificador; generalitzar el codi postal als dos primers dígits; eliminar camps únics No, si l'anonimització és real. Però és difícil d'aconseguir: la combinació de poques dades "innocents" pot reidentificar

La Marta va decidir que els conjunts de dades que es facin servir per entrenar models a NovaMarket estiguin sempre, com a mínim, pseudonimitzats, i que la previsió de demanda treballi amb dades agregades (anònimes).

Avís important: tot l'anterior és una descripció conceptual amb finalitats formatives, no assessorament jurídic. Qualsevol projecte que tracti dades personals s'ha de revisar amb el delegat de protecció de dades o un professional legal, que avaluarà la base jurídica, la necessitat d'una avaluació d'impacte i les mesures concretes.

  1. Quantitat davant de qualitat; dades sintètiques

És habitual sentir que "com més dades, millor". És cert a mitges:

  • Més dades ajuden quan són variades i representatives: permeten aprendre patrons més fins i redueixen el perill que el model memoritzi casos concrets (el sobreajust, tema de 04-06). Els grans avenços del deep learning es van recolzar en conjunts enormes.
  • Més dades dolentes no ajuden: multiplicar per deu un conjunt esbiaixat dona un model deu vegades més segur del seu biaix. Dos-cents exemples ben etiquetats de causes d'incidència valen més que dos mil etiquetats de qualsevol manera.
  • Les dades han de ser rellevants: per al recomanador de NovaMarket, les comandes d'una altra botiga d'un altre sector aporten poc.

Regla pràctica: primer qualitat i representativitat; després, quantitat. I mesura sempre si més dades milloren realment el resultat.

Les dades sintètiques són dades generades artificialment (mitjançant regles, simulació o models generatius) que imiten les propietats estadístiques de les reals. Es fan servir per: completar classes poc freqüents (hi ha molt pocs fraus reals dels quals aprendre), provar sistemes sense exposar dades personals, o simular escenaris que encara no han passat (una campanya de Nadal per a un producte nou). Tenen un límit evident: només contenen el que qui les va generar sabia o va suposar; no descobreixen res de nou del món, i si es generen a partir de dades esbiaixades, n'hereten el biaix. Són un complement, no un substitut.

  1. Exemple en Python: un informe de qualitat de comandes.csv

Farem el que va fer la Marta el primer dia: llegir un extracte de comandes.csv, comptar els problemes per dimensió i produir un petit informe. Perquè l'exemple sigui autocontingut, el CSV està escrit dins del programa com una cadena de text; a la pràctica el llegiries amb open("comandes.csv"). Només fem servir la biblioteca estàndard: csv, io, re i collections.

9.1 Les dades i la seva lectura

import csv
import io
import re
from collections import Counter

DADES_COMANDES = """id_comanda,id_client,data,import_comanda,ciutat,codi_postal,retornat
48201,C1001,2026-03-02,89.90,Zaragoza,50001,no
48202,C1002,02/03/2026,15990,Madrid,28045,no
48203,C1003,2026-03-02,,Getafe,28901,si
48204,C1001,2026-03-03,45.00,zaragoza,50001,no
48205,C1004,03-03-2026,320.50,Valencia,46001,si
48206,C1005,2026-03-03,12.99,Madrid,,no
48207,C1002,2026-03-04,159.90,Madrid,28045,no
48202,C1002,02/03/2026,15990,Madrid,28045,no
48208,C1006,2026-13-04,75.00,Sevilla,41001,no
48209,,2026-03-04,210.00,Bilbao,48001,
48210,C1007,2026-03-05,58.40,Zaragoza,50002,no
48211,C1008,2026-03-05,1299.00,Getafe,28901,no
"""

def llegir_comandes(text_csv):
    # io.StringIO converteix la cadena en una cosa que es llegeix com un fitxer.
    # csv.DictReader retorna cada fila com un diccionari {columna: valor}.
    lector = csv.DictReader(io.StringIO(text_csv))
    return list(lector)

comandes = llegir_comandes(DADES_COMANDES)
print(f"Files llegides: {len(comandes)}")
print(comandes[0])

Sortida:

Files llegides: 12
{'id_comanda': '48201', 'id_client': 'C1001', 'data': '2026-03-02', 'import_comanda': '89.90', 'ciutat': 'Zaragoza', 'codi_postal': '50001', 'retornat': 'no'}

Explicació: csv.DictReader llegeix la primera línia com a capçalera i converteix cada línia següent en un diccionari, cosa que ens permet accedir als valors per nom (fila["import_comanda"]). Observa que tot es llegeix com a text: '89.90' és una cadena, no un nombre; convertir-lo serà responsabilitat nostra. Si mires les dades amb atenció ja veuràs els problemes sembrats: un import buit, un id_client buit, un retornat buit, un codi_postal buit, tres formats de data, una data amb mes 13, un import de 15990 que fa olor de cèntims, "zaragoza" en minúscules i la comanda 48202 dues vegades.

9.2 Completesa: comptar buits per columna

def informe_completesa(files):
    columnes = files[0].keys()
    total = len(files)
    print(f"{'columna':15s} {'buits':>7s} {'% buits':>9s}")
    for col in columnes:
        buits = sum(1 for f in files if f[col].strip() == "")
        print(f"{col:15s} {buits:7d} {100*buits/total:8.1f}%")

informe_completesa(comandes)

Sortida:

columna           buits   % buits
id_comanda            0      0.0%
id_client             1      8.3%
data                  0      0.0%
import_comanda        1      8.3%
ciutat                0      0.0%
codi_postal           1      8.3%
retornat              1      8.3%

Explicació: per a cada columna recorrem les files i comptem les que tenen la cel·la buida després de treure espais (strip()); un espai en blanc també és un buit. L'expressió sum(1 for f in files if ...) és una manera compacta de comptar. Amb l'incidencies.csv real, aquest informe és el que mostraria "causa: 50,0 %".

9.3 Unicitat: duplicats

def detectar_duplicats(files, clau):
    # Counter compta quantes vegades apareix cada valor de la clau.
    comptador = Counter(f[clau] for f in files)
    return {valor: vegades for valor, vegades in comptador.items() if vegades > 1}

print(detectar_duplicats(comandes, "id_comanda"))     # {'48202': 2}

Explicació: Counter construeix un diccionari valor → nombre d'aparicions; ens quedem amb els que apareixen més d'una vegada. Aquí el duplicat és exacte (la mateixa fila carregada dues vegades), el cas fàcil. Els duplicats difícils són els de clients.csv: mateix client amb correu en majúscules o amb espai final. Per a aquests, la clau caldria normalitzar-la abans de comptar: f["email"].strip().lower(). Prova-ho com a variant.

9.4 Consistència: formats de data barrejats

PATRONS_DATA = {
    "AAAA-MM-DD": re.compile(r"^\d{4}-\d{2}-\d{2}$"),
    "DD/MM/AAAA": re.compile(r"^\d{2}/\d{2}/\d{4}$"),
    "DD-MM-AAAA": re.compile(r"^\d{2}-\d{2}-\d{4}$"),
}

def classificar_data(text):
    for nom, patro in PATRONS_DATA.items():
        if patro.match(text):
            return nom
    return "desconegut"

formats = Counter(classificar_data(f["data"]) for f in comandes)
print(formats)      # Counter({'AAAA-MM-DD': 9, 'DD/MM/AAAA': 2, 'DD-MM-AAAA': 1})

Explicació: cada patró és una expressió regular: ^\d{4}-\d{2}-\d{2}$ vol dir "exactament quatre dígits, guionet, dos dígits, guionet, dos dígits". classificar_data retorna el nom del primer patró que encaixa. El Counter final ens diu quantes dates hi ha de cada format: tres files no segueixen l'estàndard. Ordenar o comparar aquestes dates com a text donaria resultats absurds, i qualsevol programa que esperés AAAA-MM-DD hi fallaria.

9.5 Exactitud: valors impossibles i unitats sospitoses

def data_valida(text):
    # Nomes comprovem les que ja tenen format estandard.
    if not PATRONS_DATA["AAAA-MM-DD"].match(text):
        return False
    any_, mes, dia = (int(x) for x in text.split("-"))
    return 1 <= mes <= 12 and 1 <= dia <= 31

impossibles = [f["id_comanda"] for f in comandes
               if classificar_data(f["data"]) == "AAAA-MM-DD" and not data_valida(f["data"])]
print("Dates impossibles:", impossibles)         # ['48208']  (mes 13)

def imports_sospitosos(files, llindar=5000):
    sospitosos = []
    for f in files:
        if f["import_comanda"].strip() == "":
            continue                             # el buit ja l'hem comptat a completesa
        valor = float(f["import_comanda"])
        if valor > llindar:
            sospitosos.append((f["id_comanda"], valor))
    return sospitosos

print("Imports sospitosos:", imports_sospitosos(comandes))
# [('48202', 15990.0), ('48202', 15990.0)]

Explicació: l'exactitud no es pot comprovar del tot sense una font de veritat, però sí que podem detectar valors impossibles (mes 13) i valors fora del rang raonable (una comanda de 15.990 € en una botiga el tiquet mitjà de la qual ronda els 100 € fa olor d'import en cèntims: 159,90 €). El llindar de 5.000 € és una regla de negoci que va fixar en Diego. Fixa't que l'import sospitós apareix dues vegades perquè la fila està duplicada: els problemes de qualitat s'acumulen.

9.6 Consistència de categories

def informe_ciutats(files):
    tal_qual = Counter(f["ciutat"] for f in files)
    normalitzades = Counter(f["ciutat"].strip().lower() for f in files)
    print("Ciutats diferents tal qual:", len(tal_qual), sorted(tal_qual))
    print("Ciutats diferents normalitzades:", len(normalitzades))

informe_ciutats(comandes)

Sortida:

Ciutats diferents tal qual: 7 ['Bilbao', 'Getafe', 'Madrid', 'Sevilla', 'Valencia', 'Zaragoza', 'zaragoza']
Ciutats diferents normalitzades: 6

Explicació: comptant els valors tal qual hi ha set ciutats; normalitzant (sense espais, en minúscules) n'hi ha sis. La diferència és exactament el nombre d'inconsistències. Aquest truc (comparar el nombre de valors diferents abans i després de normalitzar) serveix per a qualsevol columna categòrica.

9.7 L'informe de qualitat complet

def informe_qualitat(files):
    total = len(files)
    print("=== INFORME DE QUALITAT: comandes.csv ===")
    print(f"Registres: {total}")

    dup = detectar_duplicats(files, "id_comanda")
    print(f"Unicitat:     {len(dup)} id_comanda repetits {sorted(dup)}")

    buits = sum(1 for f in files for col in f if f[col].strip() == "")
    print(f"Completesa:   {buits} cel·les buides")

    formats = Counter(classificar_data(f["data"]) for f in files)
    no_estandard = total - formats.get("AAAA-MM-DD", 0)
    print(f"Consistencia: {no_estandard} dates fora d'AAAA-MM-DD")

    impossibles = [f["id_comanda"] for f in files
                   if classificar_data(f["data"]) == "AAAA-MM-DD" and not data_valida(f["data"])]
    sosp = imports_sospitosos(files)
    ids_sosp = {s[0] for s in sosp}
    print(f"Exactitud:    {len(impossibles)} dates impossibles, {len(sosp)} imports sospitosos")

    # Una fila es problematica si te almenys un problema de qualsevol tipus
    files_amb_problema = 0
    for f in files:
        problema = (any(f[c].strip() == "" for c in f)
                    or dup.get(f["id_comanda"], 0) > 1
                    or classificar_data(f["data"]) != "AAAA-MM-DD"
                    or f["id_comanda"] in impossibles
                    or f["id_comanda"] in ids_sosp)
        if problema:
            files_amb_problema += 1

    percentatge = 100 * files_amb_problema / total
    print(f"Files amb algun problema: {files_amb_problema} de {total} ({percentatge:.0f}%)")
    print(f"Puntuacio de qualitat: {100 - percentatge:.0f}/100")

informe_qualitat(comandes)

Sortida:

=== INFORME DE QUALITAT: comandes.csv ===
Registres: 12
Unicitat:     1 id_comanda repetits ['48202']
Completesa:   4 cel·les buides
Consistencia: 3 dates fora d'AAAA-MM-DD
Exactitud:    1 dates impossibles, 2 imports sospitosos
Files amb algun problema: 7 de 12 (58%)
Puntuacio de qualitat: 42/100

Explicació: l'informe reuneix les comprovacions anteriors i hi afegeix una mètrica global: el percentatge de files amb almenys un problema. Un 58 % de files problemàtiques en una mostra petita i exagerada; al fitxer real de NovaMarket la xifra va ser menor però suficient per justificar un projecte previ de neteja. La "puntuació de qualitat" és una simplificació (totes les dimensions pesen igual), però converteix una sensació en un nombre que es pot seguir en el temps: l'objectiu de la Marta és que pugi mes a mes. Com a exercici mental, pensa què hi afegiries per mesurar l'actualitat (necessitaries una columna amb la data de l'última actualització) i què necessitaries per mesurar l'exactitud de debò (una font de referència amb què comparar).

Errors Comuns i Consells

  • Començar pel model. L'impuls natural és entrenar alguna cosa com més aviat millor. Comença sempre per un informe de qualitat com el de la secció 9; una hora de comprovacions estalvia setmanes de depurar per què el model "fa coses rares".
  • Confiar que un fitxer net no està esbiaixat. Qualitat i representativitat són coses diferents. Pregunta sempre qui falta a les dades i per què.
  • Tractar el buit com a zero, o com una categoria més, sense pensar-hi. Un import buit no és un import de 0 €; una causa buida no és "sense causa". Abans de decidir què fer amb els buits cal entendre per què falten (és aleatori o falta més els dies de pic?).
  • Ignorar les unitats. Cèntims davant d'euros, grams davant de quilos, hora local davant d'UTC. Documenta les unitats al diccionari de dades i valida els rangs.
  • Desar-ho tot "per si de cas". Xoca amb la minimització i la limitació de conservació del RGPD i augmenta el risc. Recull i conserva el necessari per a una finalitat definida.
  • Anonimitzar traient només el nom. Codi postal + data de naixement + sexe identifiquen una gran part de la població. Si necessites anonimitzar de debò, agrega o generalitza, i demana revisió experta.
  • Consell: crea el diccionari de dades des del primer dia (columna, significat, tipus, unitat, valors permesos, qui n'és responsable). És el document més útil i menys glamurós d'un projecte d'IA.

Exercicis

Exercici 1: Classificar les dades de NovaMarket

Per a cadascun dels cinc fitxers (clients.csv, comandes.csv, productes.csv, ressenyes.csv, incidencies.csv), indica: (a) si és estructurat, semiestructurat o no estructurat (o mixt: quines columnes de cada tipus); (b) quina columna podria ser una etiqueta i per a quin cas d'ús de la llista de 01-03; (c) si conté dades personals i quina mesura (pseudonimització, anonimització, minimització) hi aplicaries abans de fer-lo servir per entrenar.

Exercici 2: Biaix al model de risc de devolució

NovaMarket vol entrenar un model que predigui si una comanda serà retornada, fent servir l'històric de comandes.csv dels últims tres anys. Durant aquest període: (i) les devolucions de l'app mòbil es registraven en un altre sistema i no són al fitxer; (ii) l'equip d'en Diego revisava manualment i anul·lava moltes devolucions "dubtoses" de comandes de més de 300 € (la seva antiga regla); (iii) la columna motiu_devolucio l'omplien els clients lliurement. Identifica quin tipus de biaix introdueix cada circumstància i quin efecte tindria en el model.

Exercici 3: Ampliar l'informe de qualitat

Amplia el programa de la secció 9 amb dues comprovacions: (a) el camp retornat només admet els valors si i no (qualsevol altre, inclòs el buit, és un problema de consistència); (b) el codi_postal, quan no és buit, ha de tenir exactament 5 dígits i els seus dos primers dígits han de ser coherents amb la ciutat almenys per a aquests casos: Zaragoza → 50, Madrid → 28, Getafe → 28 (problema d'exactitud). Afegeix el recompte de totes dues a l'informe.

Solucions

Solució 1.

Fitxer Estructura Etiqueta possible (cas d'ús) Dades personals i mesura
clients.csv Estructurat (nom, correu, adreça, data d'alta) Cap d'evident; es podria afegir "client actiu/inactiu" per predir abandonament (no és a la llista de 9, però és habitual) Sí, plenament: pseudonimitzar (substituir nom i correu per id_client); minimitzar (cal l'adreça completa per recomanar? probablement n'hi ha prou amb la ciutat)
comandes.csv Estructurat retornat (cas 3, risc de devolució); unitats per producte i data són la sèrie temporal del cas 2 (previsió) Sí, mentre contingui id_client vinculable: pseudonimitzat; per a previsió de demanda, agregar per producte/ciutat/dia (anonimitzat)
productes.csv Estructurat (categoria, preu, pes) amb una columna no estructurada (descripció en text) Cap; és informació de context (característiques) per als casos 1, 2 i 6 No conté dades personals
ressenyes.csv Mixt: columnes estructurades (id_producte, puntuacio, data) i text lliure no estructurat puntuacio (1-5) pot servir d'etiqueta aproximada de sentiment per al cas 4; millor una etiqueta posada a mà Sí: id_client i, potencialment, el mateix text (la gent hi escriu el seu nom o dades); pseudonimitzar i revisar el text
incidencies.csv Mixt: columnes estructurades (id_comanda, data, tipus, causa) i descripció lliure causa (cas 9, diagnòstic), amb el problema de ser buida a la meitat de les files Sí, indirectament via id_comanda → client; pseudonimitzar

Solució 2.

  • (i) Devolucions de l'app absents: biaix de mostreig (o de mesura). El model subestimarà les devolucions dels clients que compren per mòbil; si el canal està correlacionat amb l'edat o el tipus de producte, el model s'equivocarà sistemàticament en aquests grups.
  • (ii) Anul·lacions manuals de devolucions dubtoses de més de 300 €: biaix històric (les dades reflecteixen una política passada). L'històric conté menys devolucions "consumades" en comandes altes del que passaria sense la intervenció d'en Diego; el model pot aprendre que les comandes cares es retornen poc, just el contrari del que va motivar la regla, i a més incorpora el criteri subjectiu de què era "dubtós". Si el model es fa servir per decidir què revisar, es crea un bucle de retroalimentació.
  • (iii) Motiu escrit lliurement pel client: biaix d'etiquetatge (i problema de consistència). "No m'agrada", "no era el que esperava", "talla" i "qualitat dolenta" poden ser el mateix o no; el model aprèn les paraules que fa servir cada client, no la causa real. Caldria normalitzar els motius a una llista tancada abans de fer-los servir com a etiqueta.

Solució 3.

def problemes_retornat(files):
    return [f["id_comanda"] for f in files if f["retornat"].strip() not in ("si", "no")]

PREFIXOS_CP = {"zaragoza": "50", "madrid": "28", "getafe": "28"}

def problemes_codi_postal(files):
    dolents = []
    for f in files:
        cp = f["codi_postal"].strip()
        if cp == "":
            continue                                   # ja comptat a completesa
        ciutat = f["ciutat"].strip().lower()
        if not re.fullmatch(r"\d{5}", cp):
            dolents.append((f["id_comanda"], cp, "format"))
        elif ciutat in PREFIXOS_CP and not cp.startswith(PREFIXOS_CP[ciutat]):
            dolents.append((f["id_comanda"], cp, "no coincideix amb " + f["ciutat"]))
    return dolents

print("retornat no valid:", problemes_retornat(comandes))         # ['48209']
print("codi postal:", problemes_codi_postal(comandes))            # [] amb les dades d'exemple

Per incorporar-ho a l'informe n'hi ha prou amb afegir dues línies dins d'informe_qualitat amb len(problemes_retornat(files)) i len(problemes_codi_postal(files)) i incloure aquests identificadors a la condició de "fila amb problema". Amb les dades d'exemple la comprovació de codi postal no troba errors; afegeix una fila 48212,C1009,2026-03-06,20.00,Madrid,50003,no i comprova que la detecta.

Conclusió

En aquesta lliçó hem tractat les dades com el que són a la IA moderna: la matèria primera de la qual el model ho hereta tot, tant el coneixement com els errors i els biaixos. Hem classificat les dades per estructura (estructurades, semiestructurades, no estructurades), per naturalesa (numèriques, categòriques, text, imatge, sèries temporals) i per la presència d'etiquetes, anticipant la distinció entre aprenentatge supervisat i no supervisat. Hem recorregut el cicle de vida de la dada (recollida, emmagatzematge, qualitat, ús, governança) i hem desglossat la qualitat en cinc dimensions mesurables (completesa, exactitud, consistència, actualitat, unicitat) il·lustrades amb els problemes reals dels CSV de NovaMarket: la meitat de la columna causa buida, clients duplicats, dates en tres formats i preus en cèntims. Hem vist que el biaix entra per les dades (mostreig, històric, etiquetatge) i es converteix en decisions desviades, hem presentat els principis del RGPD que afecten el treball amb dades (finalitat, minimització, conservació, drets, seguretat) juntament amb la pseudonimització i l'anonimització, i hem matisat el mite de "més dades sempre és millor". Finalment, hem escrit un programa que llegeix un CSV amb la biblioteca estàndard i produeix un informe de qualitat: la primera eina que s'hauria d'executar en qualsevol projecte d'IA.

Amb les dades ja sobre la taula, la lliçó següent, Ètica i Consideracions en IA, aborda el que passa quan aquestes dades, amb els seus biaixos, alimenten decisions que afecten persones: quins principis ètics han de guiar NovaMarket, quins problemes concrets (discriminació, privadesa, opacitat, responsabilitat, impacte laboral, desinformació, sostenibilitat) cal preveure, què exigeix el marc regulador europeu i quines eines pràctiques (llista de verificació, avaluació d'impacte, revisió humana, mètriques d'equitat) permeten passar de les bones intencions als fets. Hi reprendrem el model de risc de devolució i el codi postal per mesurar, amb números, si un model tracta igual tots els grups.

Fonaments d'Intel·ligència Artificial (IA)

Mòdul 1: Introducció a la Intel·ligència Artificial

Mòdul 2: Principis Bàsics de la IA

Mòdul 3: Algorismes en IA

Mòdul 4: Aprenentatge Automàtic (Machine Learning)

Mòdul 5: Xarxes Neuronals i Deep Learning

Mòdul 6: Lògica i Sistemes Experts

Mòdul 7: Eines i Llenguatges de Programació en IA

Mòdul 8: Projectes i Casos d'Estudi

Mòdul 9: Exercicis i Pràctiques

Mòdul 10: Recursos Addicionals

© Copyright 2026. Tots els drets reservats