Sistemes de recomanació
- Introducció
- Mètriques d’avaluació
- Predictors Baseline
- Filtrat basat en contingut
- Filtrat col·laboratiu
- Tècniques avançades
- Com evolucionar el recomanador
- Oportunitats i riscos
Introducció
Què és un sistema de recomanació?
Farem servir com a exemple conductor el problema de predir les valoracions de pel·lícules.
Imaginem que tens una plataforma de streaming i que els teus usuaris puntuen les pel·lícules d’1 a 5 estrelles. En un sistema típic de recomanació tenim:
- Un conjunt d’usuaris (per exemple: Alice, Bob, Carol i Dave, numerats de 1 a 4).
- Un conjunt d’ítems (en aquest cas, pel·lícules: Love at Last, Romance Forever, Cute Puppies of Love, Nonstop Car Chases, Sword vs. Karate).
- Les puntuacions que cada usuari dona (o no dona) a cadascuna de les pel·lícules.
Per simplicitat, suposem que les valoracions poden anar de 0 a 5 estrelles (0 = “gens interessant”). Quan un usuari encara no ha puntuat una pel·lícula, ho representarem amb un “?”.
Exemple:
| Movie | Alice (1) | Bob (2) | Carol (3) | Dave (4) |
|---|---|---|---|---|
| Love at last | 5 | 5 | 0 | 0 |
| Romance forever | 5 | ? | ? | 0 |
| Cute puppies of love | ? | 4 | 0 | ? |
| Nonstop car chases | 0 | 0 | 5 | 4 |
| Swords vs. karate | 0 | 0 | 5 | ? |
- Alice puntua Love at Last amb 5 estrelles i Romance Forever amb 5, però no ha vist Cute Puppies of Love (per tant, “?”).
- Bob dona 5 estrelles a Love at Last, 4 a Cute Puppies of Love, i 0 a dues altres pel·lícules.
- Carol posa 0 estrelles a dues, però li encanten Nonstop Car Chases i Sword vs. Karate.
- Dave té un altre patró de puntuacions.
Notació
Per generalitzar:
-
Direm que hi ha nu usuaris. En el nostre exemple, nu=4.
-
Direm que hi ha nm pel·lícules (o ítems en general). En el nostre exemple, nm=5.
-
Definim una variable r(i,j):
r(i,j)={1si l’usuari j ha puntuat la pel·lícula i0si l’usuari j no l’ha puntuada
Exemple:
- Alice (usuari 1) ha puntuat la pel·lícula 1 → r(1,1)=1.
- Però no ha puntuat la pel·lícula 3 → r(3,1)=0.
-
Definim y(i,j) com la puntuació donada per l’usuari j a la pel·lícula i. Exemple: si l’usuari 2 dona un 4 a la pel·lícula 3, llavors y(3,2)=4.
Aquesta distinció és important: no tots els usuaris puntuen totes les pel·lícules. Saber quines puntuacions existeixen i quines no, és clau pel sistema.
Sparsity: En sistemes reals, la immensa majoria de caselles són “?” (sense valorar). Per exemple, a Netflix cada usuari veu ~100 pel·lícules d’un catàleg de desenes de milers, deixant >99% de la matriu buida. Això té implicacions importants tant per l’algorisme (com aprendre amb tan poques dades?) com per la implementació (emmagatzematge eficient amb sparse matrices).
Quin és l’objectiu?
Donat que hi ha moltes caselles buides (pel·lícules no puntuades), un sistema de recomanació ha d’intentar predir quina puntuació posaria un usuari a una pel·lícula que encara no ha vist.
A partir d’aquestes prediccions podem suggerir als usuaris les pel·lícules (o productes, restaurants, articles…) que és més probable que valorin amb 5 estrelles.
Assumpció inicial
Per començar a desenvolupar un algoritme, farem una suposició especial: suposarem que tenim característiques addicionals de les pel·lícules, com ara si són de gènere romàntic o d’acció.
Amb aquesta informació extra podrem començar a construir un primer algoritme. Més endavant, veurem què passa si no disposem d’aquestes característiques i haurem de fer que el sistema aprengui igualment.
Mètriques d’avaluació
Necessitem mètriques diferents segons la natura de la predicció: ratings numèrics vs llistes ordenades d’ítems.
Mètriques per a prediccions de ratings
Per sistemes que prediuen ratings numèrics (1-5 estrelles), fem servir:
- RMSE (Root Mean Squared Error): Penalitza errors grans. Netflix Prize va usar RMSE com a mètrica oficial.
- MAE (Mean Absolute Error): Menys sensible a valors atípics que RMSE.
Vegeu ml_metrics.md per a les fórmules i explicacions detallades.
Exemple: Si predim 4.2 estrelles per un usuari que dona 5, l’error és 0.8. RMSE eleva aquest error al quadrat (0.64), penalitzant-lo més que MAE (0.8).
Mètriques per a recomanació de llistes (ranking)
Quan el sistema recomana una llista ordenada d’ítems (top-10 pel·lícules recomanades), necessitem mètriques específiques que avaluïn la qualitat del ranking.
Precision@K i Recall@K
Precision@K respon: “dels K ítems que he recomanat, quants eren bons?”
Recall@K respon: “dels ítems bons que existeixen, quants he recomanat?”
Direm que un ítem és rellevant quan rating ≥ 4 estrelles (explícit) o interacció com clic/compra (implícit).
Precision@K=Ítems rellevants en top-KK
Intuïció de la fórmula: El denominador és K (el nombre total de recomanacions que hem fet). El numerador compta quantes d’aquestes recomanacions eren bones. Per tant, Precision@K mesura la qualitat de les recomanacions: quin percentatge del que hem recomanat és realment útil.
Recall@K=Ítems rellevants en top-KTotal ítems rellevants
Intuïció de la fórmula: El denominador és el total d’ítems que li agraden a l’usuari (tots els que tenen ≥4 estrelles, per exemple). El numerador compta quants d’aquests hem aconseguit incloure a les nostres K recomanacions. Per tant, Recall@K mesura la cobertura: quin percentatge dels ítems bons hem “rescatat” o trobat.
Nota sobre Recall@K: Recall@K té un límit superior natural: si l’usuari té 100 pel·lícules que li agraden i només recomanem K=10, el màxim Recall@10 possible és 10/100 = 0.10 (10%). Per això, valors “baixos” de Recall@K no són necessàriament dolents — cal interpretar-los en funció de K i del total d’ítems rellevants.
Exemple concret:
Imaginem que en Eva té 15 pel·lícules que li agraden (va donar ≥ 4 estrelles) d’un catàleg de 100 pel·lícules. El nostre sistema li recomana una llista de 10 pel·lícules (K=10), de les quals 6 són pel·lícules que li agraden.
- Precision@10 = 6/10 = 0.60 → El 60% de les recomanacions són bones
- Recall@10 = 6/15 = 0.40 → Hem cobert el 40% de totes les pel·lícules que li agraden
Si canviem a K=20 i ara cobrim 9 pel·lícules bones:
- Precision@20 = 9/20 = 0.45 → Baixa (diluïm amb més recomanacions)
- Recall@20 = 9/15 = 0.60 → Puja (cobrim més pel·lícules bones)
Comparació amb random: Si recomanéssim 10 pel·lícules a l’atzar d’un catàleg de 100, donat que la probabilitat d’encertar-hi una és 15/100, esperaríem encertar 10 × (15/100) = 1.5 pel·lícules bones de mitjana:
- Precision@10 random = 1.5/10 = 0.15 (15%)
- Recall@10 random = 1.5/15 = 0.10 (10%)
El nostre model (Precision 0.60, Recall 0.40) és 4× millor que random — senyal que el model aporta valor real.
NDCG@K (Normalized Discounted Cumulative Gain)
Mètrica que penalitza quan ítems rellevants apareixen més avall a la llista. A diferència de Precision@K, NDCG considera que la posició importa: recomanar un bon ítem al lloc 1 és millor que al lloc 10. NDCG ∈ [0, 1], on 1 = ordre perfecte.
Intuïció: Si recomano [pel·lícula excel·lent, excel·lent, dolenta, dolenta] és millor que [dolenta, dolenta, excel·lent, excel·lent], encara que Precision@4 sigui igual.
Taula resum: Què mesurar segons la tasca
| Tasca | Mètrica Principal | Mètriques Secundàries |
|---|---|---|
| Predir ratings explícits | RMSE | MAE, R² |
| Recomanar top-N ítems | Precision@K, Recall@K | NDCG@K, F1@K |
Mètriques offline vs online
Les mètriques offline (RMSE, Precision@K) es calculen sobre dades històriques. Les mètriques online (CTR, conversions) mesuren comportament real en producció. Important: Un model amb millor RMSE no sempre funciona millor amb usuaris reals.
Predictors Baseline
Abans de construir models sofisticats, és fonamental establir predictors simples que serveixin com a punt de referència.
Per què són importants els baselines?
Si un model complex no millora un baseline simple, probablement:
- Té errors d’implementació
- Està sobreajustat
- No està ben configurat
Els baselines també són útils com a fallback: quan tenim un usuari nou sense gairebé dades, podem usar el baseline mentre recopilam més informació.
Tipus de baselines
1. Predicció per mitjana global
El predictor més simple possible:
ˆy(i,j)=μ
on μ és la mitjana de totes les valoracions del dataset.
Exemple: Si la mitjana de totes les valoracions és 3.5, predeiem 3.5 estrelles per a qualsevol parella usuari-ítem. Simple però ignora preferències individuals i qualitat dels ítems.
2. Predicció per mitjana d’ítem
Millora el baseline anterior tenint en compte que alguns ítems són objectivament millors que altres:
ˆy(i,j)=μi
on μi és la mitjana de les valoracions de l’ítem i.
Exemple: Si The Shawshank Redemption té una mitjana de 4.8 estrelles, predeiem 4.8 per a qualsevol usuari. Captura la qualitat dels ítems però ignora preferències individuals.
3. Predicció per mitjana d’usuari
Considera que alguns usuaris són més generosos o més crítics en les seves valoracions:
ˆy(i,j)=μj
on μj és la mitjana de les valoracions de l’usuari j.
Exemple: Si l’Alice normalment valora amb 4-5 estrelles (generosa) i en Bob amb 1-2 (crític), això es reflecteix en les prediccions. Captura comportament individual però ignora qualitat dels ítems.
4. Model de bias (usuari + ítem)
El millor baseline combina els dos efectes anteriors:
ˆy(i,j)=μ+bi+bj
on:
- μ és la mitjana global de totes les valoracions
- bi=μi−μ és el bias de l’ítem (desviació de l’ítem respecte la mitjana global)
- bj=μj−μ és el bias de l’usuari (desviació de l’usuari respecte la mitjana global)
Exemple detallat:
- Mitjana global: μ=3.5
- The Shawshank Redemption: μi=4.8 → bi=+1.3 (pel·lícula excel·lent)
- Alice (generosa): μj=4.2 → bj=+0.7 (usuària que valora alt)
- Predicció: ˆy=3.5+1.3+0.7=5.5
- Com el màxim és 5, la predicció final és 5 estrelles
Altre exemple:
- Mitjana global: μ=3.5
- Pel·lícula mediocre: μi=2.8 → bi=−0.7
- Bob (crític): μj=2.5 → bj=−1.0
- Predicció: ˆy=3.5−0.7−1.0=1.8 → ~2 estrelles
Càlcul dels bias: El bias de l’ítem és simplement la diferència entre la seva mitjana i la mitjana global. El bias de l’usuari es calcula de manera anàloga.
Quan usar cada baseline?
| Situació | Baseline recomanat |
|---|---|
| Usuari nou, ítem conegut | Mitjana d’ítem (μi) |
| Usuari conegut, ítem nou | Mitjana d’usuari (μj) |
| Usuari i ítem nous | Mitjana global (μ) |
| Usuari i ítem coneguts | Model de bias (μ+bi+bj) |
Filtrat basat en contingut
El filtrat basat en contingut utilitza característiques dels ítems (i opcionalment dels usuaris) per fer recomanacions, en lloc de dependre exclusivament de les valoracions d’altres usuaris. Si disposem de característiques dels ítems (per exemple, gènere de pel·lícules), podem construir un model personalitzat per a cada usuari.
Exemple amb característiques
Partim del mateix conjunt de dades amb 4 usuaris que han valorat algunes de les 5 pel·lícules. Ara, a més, suposem que disposem de característiques de cada pel·lícula. Per exemple, definim:
- X₁: grau en què la pel·lícula és romàntica.
- X₂: grau en què la pel·lícula és d’acció.
| Movie | Alice (1) | Bob (2) | Carol (3) | Dave (4) | X₁ (romance) | X₂ (action) |
|---|---|---|---|---|---|---|
| Love at last | 5 | 5 | 0 | 0 | 0.9 | 0 |
| Romance forever | 5 | ? | ? | 0 | 1.0 | 0.01 |
| Cute puppies of love | ? | 4 | 0 | ? | 0.99 | 0 |
| Nonstop car chases | 0 | 0 | 5 | 4 | 0.1 | 1.0 |
| Swords vs. karate | 0 | 0 | 5 | ? | 0 | 0.9 |
Exemples:
- Love at Last: molt romàntica (X₁=0.9), gens d’acció (X₂=0).
- Nonstop Car Chases: una mica romàntica (X₁=0.1), molt d’acció (X₂=1.0).
- Cute Puppies of Love: gairebé totalment romàntica (X₁=0.99), gens d’acció (X₂=0).
Ja havíem definit:
- nu=4: nombre d’usuaris.
- nm=5: nombre de pel·lícules.
Ara afegim:
- n=2: nombre de característiques de cada pel·lícula (X₁ i X₂).
Predicció per a un usuari
Per l’usuari 1 (Alice), volem predir la seva valoració d’una pel·lícula i. Definim:
ˆy(1)(i)=w(1)⋅X(i)+b(1)
on w(1)⋅X(i) és el producte escalar (dot product) entre el vector de preferències de l’usuari i el vector de característiques de la pel·lícula.
Això és molt semblant a una regressió lineal.
Exemple: si prenem
- w(1)=[5,0]
- b(1)=0,
llavors per a la pel·lícula 3 (Cute Puppies of Love) amb X(3)=[0.99,0]:
ˆy(1)(3)=5⋅0.99+0⋅0=4.95
Aquest resultat és raonable: Alice valora molt positivament les pel·lícules romàntiques i poc les d’acció.
Per això, per a cada usuari j, tindrem un conjunt propi de paràmetres w(j) i b(j).
Model general
Per tant, la predicció de la valoració de l’usuari j sobre la pel·lícula i és:
ˆy(j)(i)=w(j)⋅X(i)+b(j)
on:
- X(i) és el vector de característiques de la pel·lícula i.
- w(j),b(j) són els paràmetres específics de l’usuari j.
Així, és com si entrenéssim una regressió lineal diferent per a cada usuari.
Entrenament
Volem trobar w i b que minimitzin l’error entre prediccions i valoracions reals. Això és exactament una regressió lineal per a cada usuari, amb regularització per evitar sobreajustament.
En essència: minimitzem (predicció - real)² + penalització per pesos grans.
Per entrenar tots els usuaris alhora, simplement sumem el cost de cada usuari i optimitzem amb descens de gradient.
Però… d’on surten aquestes característiques? Sovint no disposem de característiques prèvies tan clares. En aquest cas, necessitarem aprenentatge automàtic per descobrir característiques latents (filtrat col·laboratiu).
Filtrat col·laboratiu
La idea clau: si molts usuaris que t’assemblen van valorar bé una pel·lícula, probablement a tu també t’agradarà. Això és “col·laboratiu” perquè els usuaris col·laboren indirectament a través de les seves valoracions.
Però per fer-ho, necessitem representar cada usuari i cada pel·lícula amb vectors numèrics. Si no tenim característiques prèvies x1,x2 per a les pel·lícules, les podem aprendre automàticament a partir de les dades.
Diferència clau amb l’aprenentatge supervisat: En un problema de classificació o regressió típic, les característiques x vénen donades i el model aprèn els pesos w. En el filtrat col·laboratiu, no tenim característiques prèvies — el model ha d’aprendre tant els vectors dels usuaris com els dels ítems. Aquestes representacions apreses s’anomenen factors latents o embeddings.
Per entendre com funciona, ho construirem en tres passos:
Pas 1: Suposem que coneixem els vectors
Per entendre com funciona la predicció, primer suposarem que ja tenim els vectors dels usuaris w i els vectors dels ítems x. Més endavant veurem d’on surten.
Imaginem que disposem de vectors w per a cada usuari i vectors x per a cada pel·lícula (més un biaix per usuari i un per ítem). Les dues dimensions corresponen als factors latents que capturen preferències: en aquest exemple simplificat, podem interpretar-los com “romanticisme” i “acció”.
- Usuari 1 (Alice): w(1)=(5,0) → li encanta el romanticisme, no li agrada l’acció
- Usuari 2 (Bob): w(2)=(5,0) → mateix perfil que Alice
- Usuari 3 (Carol): w(3)=(0,5) → no li agrada el romanticisme, li encanta l’acció
- Usuari 4 (Dave): w(4)=(0,5) → mateix perfil que Carol
Per simplicitat, suposem que tots els biaixos són zero: b(j)u=0, b(i)i=0.
La predicció de la valoració de l’usuari j sobre la pel·lícula i és:
ˆy(i,j)=w(j)⋅x(i)+b(j)u+b(i)i≈w(j)⋅x(i)
on ˆy(i,j) és la predicció de la valoració que l’usuari j donaria a la pel·lícula i.
Intuïció del producte escalar: El producte escalar és alt quan els dos vectors “apunten en la mateixa direcció”. Si l’usuari té w=(5,0) (li encanta el romanticisme) i la pel·lícula té x=(1,0) (molt romàntica), el producte escalar serà alt → predicció alta → recomanem!
Exemple: Predim la valoració d’Alice per Love at Last (x=(0.9,0), molt romàntica):
ˆy=w(1)⋅x=(5,0)⋅(0.9,0)=5×0.9+0×0=4.5 estrelles
I per Nonstop Car Chases (x=(0.1,1.0), molt d’acció):
ˆy=(5,0)⋅(0.1,1.0)=5×0.1+0×1.0=0.5 estrelles
Les prediccions tenen sentit: Alice valorarà alt les pel·lícules romàntiques i baix les d’acció.
Pas 2: Deduir els vectors dels ítems
Ara invertim el problema: si coneixem els vectors dels usuaris w, podem deduir els vectors dels ítems x?
Suposem que Love at Last (pel·lícula 1) va rebre aquestes valoracions:
- Alice i Bob (amants del romanticisme): 5 estrelles
- Carol i Dave (amants de l’acció): 0 estrelles
Quin vector x(1) fa que les prediccions s’ajustin a aquestes valoracions?
- w(1)⋅x(1)=(5,0)⋅x(1)≈5 → Alice
- w(2)⋅x(1)=(5,0)⋅x(1)≈5 → Bob
- w(3)⋅x(1)=(0,5)⋅x(1)≈0 → Carol
- w(4)⋅x(1)=(0,5)⋅x(1)≈0 → Dave
La solució és x(1)=(1,0): plenament romàntica i gens d’acció. Comprovem:
- Alice: (5,0)⋅(1,0)=5 ✓
- Carol: (0,5)⋅(1,0)=0 ✓
Intuïció clau: Els usuaris que estimen el romanticisme li donen 5 estrelles, i els que estimen l’acció li donen 0. Això ens diu que la pel·lícula és romàntica! El patró de valoracions revela les característiques de l’ítem.
De la mateixa manera, per a Nonstop Car Chases (on Carol i Dave donen 5 i Alice i Bob donen 0), deduiríem x=(0,1): gens romàntica, plenament d’acció.
Al filtrat col·laboratiu, podem esbrinar els vectors dels ítems a partir dels vectors dels usuaris. Això és possible gràcies a tenir múltiples usuaris amb preferències diferents. Amb només un usuari, no hi hauria prou informació per deduir res.
Pas 3: Aprendre tots els vectors alhora
Recapitulem: al Pas 1 hem suposat que coneixíem w i hem vist com predir. Al Pas 2 hem vist que, si coneixem w, podem deduir x. Tenim un problema circular: per deduir x necessitem w, i per deduir w necessitaríem x. En realitat, no coneixem ni w (usuaris) ni x (ítems). La solució: aprendre’ls tots alhora!
Funció de cost: Minimitzem l’error quadràtic entre les prediccions i les valoracions reals, només per a les parelles usuari-ítem que tenen un rating associat:
J=∑(i,j)∈observats(yi,j−ˆy(i,j))2+λ(‖W‖2+‖X‖2)
El terme de regularització λ evita que els vectors creixin massa (sobreajustament). Optimitzem amb descens de gradient — exactament com faríem amb una xarxa neuronal.
Intuïció geomètrica: com es posicionen els vectors?
Recordem que la predicció (ignorant biaixos) és ˆy(i,j)≈w(j)⋅x(i). El producte escalar és alt (predicció alta) quan els dos vectors apunten en la mateixa direcció, i baix (predicció baixa) quan són ortogonals o oposats. El descens de gradient aprofita això:
- Valoracions altes → el gradient ajusta els vectors perquè s’alineïn més.
- Valoracions baixes → el gradient ajusta els vectors perquè siguin més ortogonals.
Com a resultat, usuaris amb gustos similars acaben amb vectors w semblants, i ítems valorats de manera similar acaben amb vectors x semblants — emergeix un clustering natural a l’espai d’embeddings.
Dimensió dels embeddings: El nombre de factors (la longitud dels vectors) és un hiperparàmetre. Valors típics són 32-128. Més dimensions permeten capturar patrons més complexos però augmenten el risc de sobreajustament i el cost computacional.
Factorització de matrius: Aquesta tècnica s’anomena factorització de matrius (matrix factorization) perquè estem descomponent la matriu de valoracions Y en el producte de dues matrius més petites:
Y≈W⋅XT
on W conté els vectors de tots els usuaris (una fila per usuari) i X conté els vectors de tots els ítems (una fila per ítem). A la pràctica, optimitzem aquests vectors amb descens de gradient — exactament el que fan les xarxes neuronals amb nn.Embedding a PyTorch.
Biaixos d’usuari i d’ítem
A més dels embeddings, molts models aprenen un biaix per a cada usuari i cada ítem. Això captura tendències globals: usuaris que puntuen alt o baix de mitjana, i ítems que reben puntuacions sistemàticament altes o baixes.
Per què és útil? Sense biaixos, l’embedding hauria de codificar què t’agrada (romanticisme vs acció) i com de generós ets puntuant. Amb biaixos, aquestes dues coses se separen: l’embedding captura el gust, el biaix captura la tendència. Això manté l’espai latent “net” — usuaris amb gustos similars queden propers, independentment de si puntuen alt o baix — i millora la precisió de les prediccions.
Nota: Un biaix és un escalar, no un vector multidimensional com els embeddings que capturen factors latents. Tot i això, a PyTorch sovint s’implementen amb nn.Embedding(dim=1) per comoditat.
Intuïció del Filtrat col·laboratiu
Aquest mètode rep el nom de filtrat col·laboratiu perquè:
- Diversos usuaris han valorat les mateixes pel·lícules.
- Això permet deduir característiques implícites de les pel·lícules.
- Amb aquestes característiques, podem predir com valorarà un nou usuari una pel·lícula que encara no ha vist.
En resum:
- En molts algoritmes de ML les característiques han de ser donades externament.
- Aquí, les característiques s’aprenen automàticament a partir de les dades dels usuaris.
Resum de conceptes nous:
- Factors latents: Dimensions ocultes que capturen patrons (romanticisme, acció…). No els definim nosaltres — els descobreix el model.
- Factorització de matrius: Descompondre Y≈W⋅XT per aprendre els vectors d’usuaris i ítems simultàniament.
- Embedding: Vector numèric dens que representa un usuari o ítem. És el terme que fan servir les xarxes neuronals per referir-se als factors latents.
El terme “embedding”
Hem vist que el filtrat col·laboratiu aprèn:
- Un vector x(i) per a cada ítem (les seves característiques latents).
- Un vector w(j) per a cada usuari (els seus “pesos” o preferències).
En el món de les xarxes neuronals, aquests vectors apresos s’anomenen embeddings:
- x(i) és l’embedding de l’ítem.
- w(j) és l’embedding de l’usuari.
Un embedding és simplement una representació numèrica densa d’un objecte (usuari, ítem, paraula…) que el model aprèn durant l’entrenament. A PyTorch, es defineixen amb nn.Embedding(num_objects, embedding_dim), que crea una taula de vectors on cada fila correspon a un objecte. Quan passem l’ID d’un usuari o ítem, obtenim el seu vector embedding.
Nota terminològica: Aquests vectors apresos també s’anomenen “factors latents” (latent factors) en alguna bibliografia. En aquest curs usarem “embedding” de manera consistent.
Comparant vectors: predicció vs similitud
Amb els embeddings apresos podem fer dues operacions diferents:
| Operació | Què compara | Propòsit | Mètode |
|---|---|---|---|
| Predicció | Usuari ↔ Ítem | Predir valoració | Producte escalar w(j)⋅x(i) |
| Similitud d’ítems | Ítem ↔ Ítem | Trobar ítems similars | Distància euclidiana |
| Similitud d’usuaris | Usuari ↔ Usuari | Trobar usuaris similars | Distància euclidiana |
La predicció (producte escalar entre usuari i ítem) ja l’hem vist: ens diu quant agradarà un ítem a un usuari. Ara veurem com usar la similitud entre ítems per recomanar productes relacionats.
Trobant ítems similars
Un cop tenim els embeddings dels ítems, podem aprofitar-los per trobar ítems similars.
Imagina que entres en una botiga en línia i mires un producte concret, per exemple, un llibre. Sovint, la web et mostra missatges com: “Aquí tens altres llibres semblants a aquest” o bé, si estàs mirant una pel·lícula: “Aquí tens altres pel·lícules semblants a aquesta”.
Com ho fan? Comparant els embeddings dels ítems: si dos ítems tenen vectors similars, és que els usuaris els valoren de manera semblant.
Com funciona?
En el collaborative filtering, cada element (una pel·lícula, un llibre, etc.) aprèn un conjunt de característiques x(i). Per exemple, en una explicació simplificada podríem imaginar que una característica indica si la pel·lícula és més aviat romàntica o d’acció.
A la pràctica, però, quan l’algorisme aprèn automàticament aquestes característiques, els valors x1,x2,x3,… són difícils d’interpretar individualment. Pot ser complicat dir: “aquest component correspon a acció” i “aquest altre a cinema estranger”.
Tot i això, el conjunt de característiques sí que conté informació rellevant sobre el que defineix un ítem.
Per exemple, després d’entrenar amb les valoracions d’Alice, Bob, Carol i Dave, podríem tenir:
- Pel·lícula 1 (Love at Last): x(1)=(1,0)
- Pel·lícula 2 (Romance Forever): x(2)=(0.98,0)
- Pel·lícula 4 (Nonstop Car Chases): x(4)=(0,1)
Aquests valors són coherents amb els que hem deduït abans: les pel·lícules romàntiques tenen la primera component alta i les d’acció la segona.
Mesurant la semblança
Donades les característiques d’un ítem x(i), podem buscar-ne d’altres similars calculant la distància euclidiana entre vectors:
d(i,k)=√n∑l=1(x(k)l−x(i)l)2
O simplement la distància quadrada (més ràpida de calcular, mateix ordre):
d2(i,k)=n∑l=1(x(k)l−x(i)l)2
Exemple concret:
Per trobar pel·lícules semblants a Love at Last (x(1)=(1,0)):
- Distància a Romance Forever: d2=(0.98−1)2+(0−0)2=0.0004 → molt similar!
- Distància a Nonstop Car Chases: d2=(0−1)2+(1−0)2=2 → molt diferents
Implementació pràctica:
Si en comptes de quedar-nos amb l’ítem més proper, seleccionem els 5 o 10 més propers, obtenim una llista de productes relacionats.
Algoritme:
- Calcular distàncies entre l’ítem i i tots els altres ítems
- Ordenar per distància creixent
- Retornar els K primers (excloent l’ítem mateix)
Optimització crítica: Aquestes similituds es poden precomputar offline:
- Cada nit, calcular les 20 pel·lícules més similars a cada pel·lícula
- Guardar en una taula de consulta ràpida
- Quan un usuari visita una pel·lícula, només cal consultar la taula (millisegons!)
Així, en un lloc web, podem recomanar productes semblants a aquell que l’usuari està consultant instantàniament, sense recalcular distàncies.
Tècniques avançades
Aquestes tècniques milloren el rendiment dels sistemes de recomanació, independentment de l’enfocament utilitzat (contingut o col·laboratiu).
Normalització de la mitjana
Aplicar normalització de la mitjana (mean normalization) no només accelera l’aprenentatge, sinó que també millora la qualitat de les prediccions, especialment per a usuaris nous.
El problema amb un usuari nou
Imaginem que afegim un nou usuari, l’Eva, que encara no ha valorat cap pel·lícula.
Si entrenem un sistema amb regularització, per a l’Eva obtindríem els paràmetres:
- w(5)=[0,0]
- b(5)=0
Com que no hi ha valoracions seves, l’algorisme tendeix a portar w(5) cap a zero. Això significa que les prediccions serien:
ˆy(5,i)=w(5)⋅X(i)+b(5)=0
És a dir, l’algorisme prediu 0 estrelles a totes les pel·lícules. Això no és gaire útil.
Què és la normalització de la mitjana?
La idea és centrar les valoracions al voltant de la seva mitjana:
-
Calculem la mitjana μi de cada pel·lícula i (tenint en compte només els usuaris que l’han valorat).
-
Construïm una nova matriu de valoracions Y′ restant aquestes mitjanes.
-
L’algorisme aprèn sobre Y′. La predicció per un usuari j i pel·lícula i és:
ˆy′(j,i)=w(j)⋅x(i)+b(j)
A la predicció final cal tornar a afegir la mitjana:
ˆy(j,i)=ˆy′(j,i)+μi
Per exemple, si l’Eva té w(5)=[0,0], b(5)=0, per a una pel·lícula amb mitjana μ1=2.5:
ˆy(5,1)=0+2.5=2.5
Això és molt més raonable: per a un usuari nou, les primeres prediccions seran la mitjana de cada pel·lícula.
Beneficis
- Prediccions inicials més raonables per a usuaris amb poques o cap valoració.
- Millor comportament del sistema de recomanació, evitant prediccions trivials.
- L’optimització numèrica és més ràpida, perquè les dades estan centrades.
Feedback implícit
Fins ara hem treballat amb valoracions explícites (ratings): l’usuari expressa directament la seva opinió (1-5 estrelles, polze amunt/avall). Però en molts sistemes reals, aquest tipus de dades són escasses. La majoria d’usuaris no valoren el contingut que consumeixen.
Tipus de feedback
Existeixen dues categories principals:
Feedback explícit:
- L’usuari proporciona una valoració directa
- Exemples: estrelles (1-5), polze amunt/avall, puntuació (0-10)
- Avantatge: senyal molt clara de preferència
- Desavantatge: poques dades (la majoria d’usuaris no valoren)
Feedback implícit:
- Es dedueix del comportament de l’usuari
- Exemples:
- YouTube: va veure el vídeo? Quant de temps?
- Spotify: va escoltar la cançó sencera o la va saltar?
- Amazon: va clicar el producte? El va comprar?
- Netflix: va acabar la pel·lícula o la va abandonar?
- Avantatge: MOLTA més informació (tothom clica, pocs valoren)
- Desavantatge: senyal més sorollós (no clicar ≠ no m’agrada)
Implicació per al modelatge: El feedback implícit és inherentment binari (va clicar o no, va comprar o no). Per tant, els models amb feedback implícit són problemes de classificació binària (predir probabilitat d’interacció), mentre que els models amb feedback explícit són problemes de regressió (predir un valor numèric com 1-5 estrelles).
Quan és útil el feedback explícit?
El feedback explícit és especialment valuós quan:
- Necessitem saber la intensitat de la preferència: Un rating de 5 estrelles indica entusiasme; un 3 indica indiferència. El feedback implícit (clic/no clic) no captura aquests matisos.
- El cost d’un error és alt: En recomanacions mèdiques o financeres, és millor tenir poques dades però fiables que moltes dades sorolloses.
- L’usuari té motivació per valorar: Comunitats com Goodreads o Letterboxd funcionen perquè els usuaris volen expressar opinions.
Limitacions del feedback explícit:
- Biaix de selecció: Els usuaris tendeixen a valorar contingut que els ha agradat molt o molt poc, però no el contingut “normal”. Això distorsiona la distribució de ratings.
- Escassetat: En la majoria de plataformes, <1% dels usuaris valoren. Amb poques dades, els models són menys precisos.
- Inconsistència temporal: El mateix usuari pot donar valoracions diferents en moments diferents segons el seu estat d’ànim.
Conversió d’explícit a implícit
Quan tenim ratings explícits però volem usar tècniques de feedback implícit, apliquem un llindar (threshold):
labeli,j={1si yi,j≥llindar(interacció positiva)0si yi,j<llindar(interacció negativa)
Exemple amb MovieLens:
- Si l’usuari dona ≥ 4 estrelles → label = 1 (li va agradar)
- Si l’usuari dona < 4 estrelles → label = 0 (no li va agradar)
Això converteix el problema de regressió (predir un valor numèric) en classificació binària (predir una probabilitat).
Per què convertir explícit a implícit?
Avantatges de la conversió:
- Simplicitat del model: La classificació binària és més senzilla que la regressió. Només cal predir “li agradarà?” en lloc de “quina nota posarà?”.
- Objectiu més alineat amb el negoci: Sovint l’important és si l’usuari consumirà el contingut, no la nota exacta que li posarà.
- Combinació de fonts de dades: Permet unificar ratings explícits amb senyals implícits (clics, visualitzacions) en un sol model.
- Robustesa al soroll: Les diferències entre un 3 i un 4 són subjectives; la distinció “li va agradar / no li va agradar” és més estable.
Inconvenients de la conversió:
- Pèrdua d’informació: Un 5 i un 4 es tracten igual, però l’usuari que dona un 5 probablement és més entusiasta.
- Elecció del llindar: Quin valor triar? 3.5? 4? La decisió és arbitrària i afecta els resultats.
- Distribució desbalancejada: Si la majoria de ratings són alts (com passa habitualment), tindrem molts més positius que negatius.
Quan fer la conversió?
| Situació | Recomanació |
|---|---|
| Vols predir si l’usuari consumirà un ítem | ✅ Convertir a implícit |
| Vols ordenar ítems per rellevància (ranking) | ✅ Convertir a implícit |
| Necessites predir la satisfacció exacta | ❌ Mantenir explícit |
| Tens molt poques dades explícites | ✅ Convertir i combinar amb implícit |
| El negoci requereix explicar “per què aquesta nota” | ❌ Mantenir explícit |
Model per feedback implícit
Amb feedback implícit, la predicció canvia:
Abans (ratings explícits): ˆy(i,j)=w(j)⋅x(i)+b(j)(valor entre 0 i 5)
Ara (feedback implícit): pi,j=σ(w(j)⋅x(i)+b(j))(probabilitat entre 0 i 1)
on σ és la funció sigmoide: σ(z)=11+e−z
Funció de cost
També canvia la funció de pèrdua:
- Ratings explícits: MSE (Mean Squared Error) o MAE
- Feedback implícit: Binary Cross-Entropy (BCE)
BCE=−1m∑(i,j)∈observats[yi,jlog(pi,j)+(1−yi,j)log(1−pi,j)]
on yi,j∈{0,1} és el label real i pi,j és la probabilitat predita.
Per què és important?
En sistemes de producció reals:
- YouTube: milers de milions de visualitzacions diàries, però poques valoracions amb polze
- Spotify: centenars de milions de reproduccions, però poques cançons “marcades com a favorites”
- Amazon: milers de milions de clics, però moltes menys compres i encara menys ressenyes
El feedback implícit multiplica per 100-1000× la quantitat de dades disponibles per entrenar el model.
Interpretació negativa
Precaució: El senyal negatiu és sorollós:
- No clicar un producte pot significar:
- No m’interessa (senyal útil)
- No l’he vist encara (no és senyal)
- Ja el tinc (no és senyal)
Per això, alguns sistemes només fan servir interaccions positives i ignoren les negatives, o les mostregen de manera especial.
Negative Sampling
Quan entrenem amb feedback implícit, tenim un problema: només tenim exemples positius (ítems que l’usuari ha clicat). Però per entrenar un classificador binari, necessitem també exemples negatius (ítems que no li interessen).
El problema
Una opció seria considerar tots els ítems no clicats com a negatius. Però això té dos problemes:
- Escala: Per cada clic, hi ha milions d’ítems no clicats. Calcular la pèrdua per tots és computacionalment inviable.
- Senyal: No clicar no significa “no m’agrada” — potser l’usuari simplement no ha vist l’ítem.
La solució: mostrejar negatius
En lloc de considerar tots els negatius, mostrejem aleatòriament uns pocs per cada positiu:
- Per cada parella positiva (usuari, ítem clicat), seleccionem K ítems aleatoris que l’usuari no ha clicat
- Entrenem el model per puntuar el positiu més alt que els K negatius
- Típicament, K ∈ [1, 20] segons el dataset
Exemple: L’usuari ha clicat la pel·lícula A. Mostrejem 4 pel·lícules aleatòries (B, C, D, E) que no ha clicat. El batch d’entrenament seria:
| Usuari | Ítem | Label |
|---|---|---|
| Alice | A | 1 (positiu) |
| Alice | B | 0 (negatiu) |
| Alice | C | 0 (negatiu) |
| Alice | D | 0 (negatiu) |
| Alice | E | 0 (negatiu) |
El model aprèn a donar una puntuació més alta a A que a B, C, D, E.
Per què funciona?
Intuïció: Si mostrejem ítems a l’atzar d’un catàleg de milions, la probabilitat que un ítem aleatori realment interessi a l’usuari és molt baixa. Per tant, els negatius aleatoris són “probablement correctes”.
Matemàticament: El negative sampling és una aproximació a la funció de pèrdua completa. Amb prou mostres aleatòries, el gradient estimat s’aproxima al gradient real, però amb un cost computacional molt menor.
En termes de rendiment:
- Sense negative sampling: O(milions) càlculs per cada positiu → entrenar un epoch triga dies
- Amb negative sampling (K=5): O(5) càlculs per cada positiu → entrenar un epoch triga minuts
Quants negatius mostrejar?
| K | Avantatge | Desavantatge |
|---|---|---|
| K=1 | Molt ràpid | Gradient sorollós |
| K=5-10 | Bon equilibri | Estàndard en la indústria |
| K=20+ | Gradient més estable | Més lent, rendiments decreixents |
YouTube i Spotify típicament usen K entre 5 i 20.
Negatius diferents cada epoch
Un detall important: els negatius es mostregen aleatòriament cada vegada que es recorre el dataset. Això significa que a cada epoch el model veu el mateix positiu (l’ítem que l’usuari va clicar) però amb negatius diferents.
Avantatge: Al llarg de l’entrenament, el model acaba veient una gran varietat de negatius per a cada positiu, millorant la seva capacitat de generalització. A més, aquesta variabilitat actua com una forma de regularització implícita que ajuda a evitar el sobreajustament.
Split temporal
En la majoria de problemes de ML, fem split aleatori: barregem les dades i agafem 80% train, 20% test. En recomanadors, això és un error greu.
Per què?
Les dades de recomanació tenen ordre temporal: l’usuari va clicar A el dilluns, B el dimarts, C el dimecres. Si fem split aleatori, el model pot “veure el futur” durant l’entrenament (saber que l’usuari va clicar C el dimecres) i haver de predir el passat (B el dimarts). Això és data leakage (fuita de dades) i dona mètriques falsament optimistes.
Data leakage: Es produeix quan, durant l’entrenament o l’avaluació d’un model, s’utilitza informació que en realitat no estaria disponible en el moment de fer prediccions reals, fet que provoca resultats artificialment bons.
La solució
Dividir les dades per temps, no aleatòriament:
- Train: totes les interaccions fins a una data X
- Test: totes les interaccions després de la data X
Així, el model només veu el passat i ha de predir el futur — exactament el que farà en producció.
Impacte
Un model avaluat amb split aleatori pot mostrar Precision@10 = 0.40, però amb split temporal baixa a 0.25. La diferència reflecteix el rendiment real en producció.
Com evolucionar el recomanador
Ara que hem vist els diferents enfocaments, podem comparar-los i entendre com evolucionar el sistema a mesura que creix.
| Aspecte | Basat en contingut | Col·laboratiu |
|---|---|---|
| Senyal principal | Característiques dels ítems | Comportament dels usuaris |
| Utilitza altres usuaris? | ❌ No | ✅ Sí |
| Funciona amb ítems nous? | ✅ Sí (usa metadades) | ❌ No (necessita valoracions) |
| Funciona amb usuaris nous? | ⚠️ Parcial (si té dades demogràfiques) | ❌ No (necessita historial) |
| Risc principal | Sobre-especialització | Cold start |
| Idea clau | “Contingut similar” | “Persones similars” |
Fases d’un projecte de recomanació
Un sistema de recomanació evoluciona amb el temps. A cada fase, les estratègies disponibles canvien segons les dades de què disposem.
Fase 1: Llançament (sense usuaris ni dades)
Quan el sistema és nou, no tenim valoracions. Les opcions són limitades:
- Predictors baseline: recomanar ítems populars o amb millor valoració externa (crítiques professionals, puntuacions d’altres plataformes)
- Basat en contingut: si tenim metadades dels ítems (gènere, any, actors…), podem recomanar ítems similars als que l’usuari indica que li agraden durant el registre
Fase 2: Primers usuaris (cold start d’usuaris)
A mesura que arriben usuaris, ens trobem amb el problema del cold start d’usuaris: un usuari nou no té historial.
- Usuaris nous: apliquem baselines (mitjana global μ o mitjana per ítem μi) combinats amb normalització de la mitjana per fer prediccions més raonables
- Usuaris amb algunes valoracions: podem començar a aprendre les seves preferències amb filtrat basat en contingut
Fase 3: Catàleg creixent (cold start d’ítems)
Quan el catàleg creix, apareix el cold start d’ítems: ítems nous sense valoracions.
- El filtrat col·laboratiu no pot recomanar ítems nous (no té dades)
- El basat en contingut sí que funciona: usa metadades (gènere, any, actors…) per trobar ítems similars
Fase 4: Sistema madur
Amb prou usuaris i valoracions, podem aprofitar tot el potencial:
- Filtrat col·laboratiu: alta precisió gràcies a patrons d’altres usuaris
- Sistemes híbrids: combinen col·laboratiu i contingut per cobrir tots els casos
| Fase | Dades disponibles | Estratègia recomanada |
|---|---|---|
| Llançament | Cap | Baselines, contingut (si hi ha metadades) |
| Primers usuaris | Pocs usuaris, algunes valoracions | Baselines + normalització mitjana |
| Catàleg creixent | Usuaris actius, ítems nous | Contingut per ítems nous, col·laboratiu per la resta |
| Sistema madur | Moltes dades | Híbrid (col·laboratiu + contingut) |
Sistemes híbrids: arquitectura two-tower
En un sistema madur, la millor estratègia és combinar col·laboratiu i contingut. L’arquitectura two-tower (dues torres) és la implementació dominant a la indústria (YouTube, Spotify, Pinterest, Airbnb…).
Estructura
Utilitzem dues xarxes neuronals independents que transformen les entrades en vectors de la mateixa dimensió:
- La torre d’usuari rep l’ID de l’usuari + característiques (edat, país, historial…) i produeix un vector vu.
- La torre d’ítem rep l’ID de l’ítem + característiques (gènere, any…) i produeix un vector vm.
- La predicció és el producte escalar vu⋅vm.
Per què és híbrid?
Comparem els diferents enfocaments que hem vist:
| Enfocament | Entrada | Fortalesa | Debilitat |
|---|---|---|---|
| Filtrat basat en contingut | Només features | Funciona amb ítems nous | Limitat a similitud explícita |
| Factorització de matrius | Només IDs | Alta precisió amb dades | Cold start |
| Híbrid | IDs + features | Precisió + cold start | Més complex |
L’arquitectura two-tower és la manera més habitual d’implementar un sistema híbrid: combina l’ID (informació col·laborativa apresa de les interaccions) amb les característiques (informació de contingut) en una sola arquitectura.
Recordem que en la factorització de matrius, cada usuari i cada ítem tenen un embedding fix (una fila a la taula nn.Embedding). El problema: si arriba un usuari o ítem nou, no té embedding — és el cold start.
L’arquitectura two-tower resol això: les torres són xarxes neuronals que aprenen una funció que transforma característiques en embeddings (no una simple taula de cerca).
Exemple: Entrenem el model amb milers d’usuaris existents (amb les seves característiques i valoracions). Després arriba una usuària nova, Maria, que no ha valorat res encara.
- Factorització de matrius: L’ID de Maria no existeix a la taula d’embeddings → no podem fer prediccions.
- Two-tower: Sabem que Maria té 28 anys, viu a Espanya, usa l’app mòbil i ha navegat per sci-fi i documentals. La torre d’usuari (ja entrenada) transforma aquestes característiques en un embedding. Durant l’entrenament, la xarxa va aprendre que “usuaris de 28 anys que naveguen sci-fi en mòbil” tenen preferències similars a cert patró → podem recomanar des del primer moment.
La diferència clau: la factorització de matrius memoritza (un vector fix per cada ID vist durant l’entrenament), mentre que two-tower generalitza (aprèn una funció que pot generar vectors per a qualsevol combinació de característiques, incloent les no vistes).
Avantatges per escalabilitat
- Precomputació: Els vectors vm de tots els ítems es poden calcular offline i guardar.
- Servei ràpid: Quan arriba un usuari, només cal calcular vu una vegada i fer productes escalars amb els candidats.
- Cerca aproximada: Els vectors permeten usar algoritmes ANN (Approximate Nearest Neighbors) com FAISS o ScaNN per trobar els ítems més similars en mil·lisegons.
Escalabilitat
En els sistemes de recomanació actuals sovint cal seleccionar un petit conjunt d’ítems per recomanar, d’entre un catàleg que pot contenir milers, milions o fins i tot desenes de milions d’opcions. La pregunta clau és: com fer això de manera eficient computacionalment?
El repte computacional
Imaginem una xarxa neuronal que fem servir per predir la puntuació que un usuari donaria a un ítem. Un servei de vídeo en línia pot tenir milers de pel·lícules; una plataforma de publicitat, milions d’anuncis; un servei de música, desenes de milions de cançons; i una botiga en línia, milions de productes.
Quan un usuari entra a la web, disposem del seu vector de característiques Xu. Però si haguéssim de passar tots els milions d’ítems per la xarxa neuronal per calcular el producte intern amb Xu, el cost seria prohibitiu: fer inferència milions de vegades per cada visita és inviable.
Estratègia en dos passos
Per resoldre aquest problema, molts sistemes a gran escala utilitzen dos passos:
- Recuperació (retrieval): generar una llista inicial d’ítems candidats plausibles.
- Classificació (ranking): ordenar aquests candidats segons el model i escollir els millors.
Pas 1: Recuperació
L’objectiu és obtenir una llista prou àmplia i variada d’ítems que puguin ser interessants per a l’usuari. És acceptable que aquesta llista contingui molts ítems que l’usuari realment no voldrà.
Exemple d’estratègies de recuperació:
- Per cada una de les últimes 10 pel·lícules vistes, afegir les 10 pel·lícules més similars (calculades amb els embeddings x(i) i x(k)).
- Afegir les 10 pel·lícules més populars de cadascun dels tres gèneres preferits de l’usuari (per exemple, romàntic, comèdia i drama històric).
- Afegir les 20 pel·lícules més vistes al país de l’usuari.
Això es pot fer ràpidament si les similituds entre pel·lícules estan precomputades i accessibles en una taula de consulta. El resultat és una llista de centenars de candidats, amb bona cobertura i diversitat.
Finalment, es poden eliminar duplicats i ítems que l’usuari ja ha consumit.
Pas 2: Classificació
Ara treballem amb uns centenars de candidats. Per cada parella (usuari, ítem):
- Passem Xu (vector de l’usuari) i Xm (vector de l’ítem) pel model.
- Calculem la predicció ˆy(u,m), que pot ser la puntuació estimada o la probabilitat que l’usuari li doni una valoració positiva.
Això ens permet ordenar els ítems segons la seva rellevància prevista.
Optimització: Si hem precomputat els vectors Vm de tots els ítems, només cal calcular Vu una vegada per usuari. Després, la puntuació de cada candidat és un simple producte escalar — molt més ràpid que fer inferència completa sobre milions d’opcions.
En resum: els sistemes de recomanació a gran escala funcionen amb una estratègia de dos passos —recuperació i classificació— que els permet ser alhora ràpids i precisos, fins i tot amb catàlegs de desenes de milions d’ítems.
Oportunitats i riscos
Els sistemes de recomanació han estat molt profitosos per a moltes empreses. Tanmateix, alguns usos han tingut conseqüències negatives per a la societat. L’objectiu hauria de ser contribuir al benestar de les persones, no només generar benefici econòmic.
Engagement vs. benestar
Un sistema pot optimitzar diferents objectius:
- Recomanar pel·lícules que l’usuari valorarà bé → benefici per l’usuari
- Maximitzar temps de permanència → benefici per l’empresa (més anuncis)
- Mostrar productes amb més marge de benefici → benefici per l’empresa
El problema: maximitzar l’engagement (temps d’ús, clics) ha conduït algunes plataformes a amplificar contingut tòxic —conspiracions, odi, desinformació— perquè aquest contingut reté l’usuari. Filtrar-lo és difícil i controvertit.
Transparència
Molts usuaris pensen que les apps els recomanen allò que més els agradarà, però sovint el criteri és maximitzar el benefici de l’empresa. Fomentar la transparència —explicar amb quins criteris es decideixen les recomanacions— pot augmentar la confiança i reduir danys.
Responsabilitat
Quan dissenyem aquests sistemes, hem de pensar en els possibles danys, no només en els beneficis. La responsabilitat és col·lectiva: només construïm tecnologies que creiem que milloren la societat.