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
- Per què les dades són el combustible de la IA
- Tipus de dades
- Dades etiquetades i no etiquetades
- El cicle de vida de la dada: recollida, emmagatzematge, qualitat, governança
- Dimensions de la qualitat de les dades, amb els problemes reals de NovaMarket
- Biaix a les dades: l'origen de la injustícia algorísmica
- Dades personals i RGPD: minimització, anonimització i pseudonimització
- Quantitat davant de qualitat; dades sintètiques
- Exemple en Python: un informe de qualitat de
comandes.csv
- 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.
- 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").
- 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 columnaretornatés l'etiqueta si volem predir devolucions. Aressenyes.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.
- 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/AAAAmentre que el sistema intern fa servirAAAA-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 deressenyes.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ó).
- 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.
- 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.
- 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 |
Sí (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.
- 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.
- Exemple en Python: un informe de qualitat de
comandes.csv
comandes.csvFarem 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'exemplePer 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
- Conceptes Fonamentals: Agents, Entorns i Racionalitat
- Tipus d'Intel·ligència Artificial
- Les Dades com a Matèria Primera de la IA
- Ètica i Consideracions en IA
Mòdul 3: Algorismes en IA
- Introducció als Algorismes
- Algorismes de Cerca
- Cerca amb Adversari: Jocs i Minimax
- Algorismes d'Optimització
Mòdul 4: Aprenentatge Automàtic (Machine Learning)
- Conceptes Bàsics de Machine Learning
- Tipus d'Aprenentatge Automàtic
- Preparació de Dades i Característiques
- Algorismes de Machine Learning
- Avaluació i Validació de Models
- Sobreajust, Regularització i Ajust d'Hiperparàmetres
Mòdul 5: Xarxes Neuronals i Deep Learning
- Introducció a les Xarxes Neuronals
- Arquitectura de Xarxes Neuronals
- Com Aprèn una Xarxa: Descens del Gradient i Retropropagació
- Deep Learning i les seves Aplicacions
- Transformers, Grans Models de Llenguatge i IA Generativa
Mòdul 6: Lògica i Sistemes Experts
- Lògica en IA
- Sistemes Experts
- Raonament amb Incertesa: Probabilitat i Xarxes Bayesianes
- Aplicacions dels Sistemes Experts
Mòdul 7: Eines i Llenguatges de Programació en IA
- Llenguatges de Programació per a IA
- Python Científic: NumPy, pandas i Matplotlib
- Eines i Llibreries Populars
- Entorns de Desenvolupament
Mòdul 8: Projectes i Casos d'Estudi
Mòdul 9: Exercicis i Pràctiques
- Exercicis d'Algorismes
- Pràctiques de Machine Learning
- Projectes de Xarxes Neuronals
- Projecte Integrador: de la Idea al Prototip
