DealTracker - Genèse du projet
Contexte
En 2021, je travaillais chez designstripe. J'étais chargé de trouver des solutions de machine learning adaptables à l'univers du design graphique, et d'entrainer des modèles pour ajouter des features au produit.
Bien sûr, j'avais toujours envie de lancer de nouveaux projets sur mon temps personnel, et d'essayer de nouvelles choses. J'ai donc acheté la sacro-sainte RTX 3090, graal de l'époque. J'avais réussi le petit exploit de l'acheter à 1500€ sur le site de LDLC, alors que les prix d'occasion étaient aux alentours de 3000€ durant la pandémie de Covid-19. Quelle joie ! J'étais soudainement propriétaire du meilleur GPU grand public, avec ses 24Go de VRAM !
L'idée de DealTracker m'est venue alors que je regardais une vidéo parlant du prix d'occasion d'une chaise de bureau que je voulais acheter, la Aeron de Herman Miller qui vaut environs 500€ en seconde main. Il s'agit de cette vidéo là: https://www.youtube.com/watch?v=x-aeDaHIEbY
À la fin de cette vidéo, Ahnestly nous fait part d'une réflexion intéressante:
"Si vous voulez trouver cette chaise moins cher, passez en revue une dizaine de pages de ventes de 'chaises de bureau' sur le marché de l'occasion, chaque jour. Vous finirez par trouver quelqu'un vendant cette chaise à un prix dérisoire, parce qu'il ne sait pas qu'elle a de la valeur".
Et c'est là que je me suis dit "tiens ça serait sympa d'automatiser cette tâche avec du Machine Learning". (précision: à cette époque, aucune plateforme d'occasion n'avait de fonctionnalité de recherche d'annonces par image)
Le premier entrainement
Ni une ni deux, le projet est lancé. Je bricole quelques scripts pour récupérer les annonces d'occasion vendant actuellement des chaises de bureau, et me voilà confronté au noeud du problème: comment trouver celles où le vendeur vend une Aeron, sans que ça soit marqué dans l'annonce ? La solution bien sûr, est de passer par les images.
En apparence, le problème est une tâche de classification binaire très scolaire: il faut différencier les images qui montrent une Aeron (classe A), et celles qui montrent n'importe quoi d'autre (classe B).
Je fais donc un petit dataset. Pour la classe A, je met mes meilleures photos d'Aeron. Pour la classe B, je met des images diverses et variées (des vaches, un lavabo, de la moutarde...). Et comme modèle, je choisis un standard éprouvé: ResNet-18.
[schéma]
Les métriques furent excellentes, et je fut ravi de lancer mes premières inférences avec le modèle. Mauvaise surprise: le modèle détecte correctement les Aeron, mais j'ai aussi beaucoup de faux positifs. Mon modèle me dit souvent "Regarde, une Aeron !" alors que les images n'ont rien à voir.
En fait, comme j'allais l'apprendre, "détecter uniquement les Aeron" est un challenge bien plus difficile que juste "détecter les Aeron". Mon dataset constitué à la va-vite n'était pas représentatif des images auxquelles le modèle était confronté durant son inférence, et le modèle s'était contenté de tracer des délimitations grossières permettant de mettre mes quelques images d'Aeron d'un côté, et les images aléatoires de l'autre. Je parlerai de ça plus en détail dans la prochaine page.
Toujours est-il, cela ne m'a pas arrêté. Bien qu'ayant énormément de faux-positif, le modèle faisait tout de même un excellent travail de filtrage, et facilitait déjà grandement mes recherche.
Les premiers résultats
La première trouvaille
Je me rappellerai toujours de la première fois où mon système a détecté une Aeron vendue en tant que "chaise de bureau". Ce jour là, je me suis levé à grand bond de ma chaise et je me suis exclamé "J'AI RÉUSSIII".
L'annonce était là, magnifique. Elle était exactement comme toutes ces autres annonces vendant des Aeronn, à un léger détail près: le prix. La chaise était vendue à 50€ au lieu de 500€. Bon, le seul problème était que le vendeur était à Perpignan, alors que j'habite à Paris. Ce n'est pas grave. Des annonces, il y en a beaucoup, et j'allais sûrement en détecter d'autres.
Le casse du siècle
La patience paie, et en l'occurrence, je n'ai pas eu longtemps à attendre. Car j'ai fini par trouver l'une des meilleures affaires qu'il m'aie été donné de trouver: une liquidation de bureau.
C'était une PME dans le XVIème qui vendait tous ses meubles dans une annonce, et qui avait beaucoup de photos. Sur la 7ème photo: une Aeron, ce qui n'était pas indiqué dans l'annonce. J'ai donc appelé la personne qui gérait la vente.
- Moi: "Oui bonjour ! J'ai vu que vous aviez de jolies chaises de bureau !"
- La dame au bout du fil: "Oui tout à fait ! Vous en proposez combien ?"
- Moi: "50€ ?"
- La dame au bout du fil: "50€ ? Mais quel prix incroyable, avec grand plaisir."
- Moi: "Vous en avez combien par curiosité ?"
- La dame au bout du fil: "6 je crois..."
- Moi: "Je prends tout !"
Et voilà comment je me suis allé récupérer le lot de chaises. Je me rappelle du trajet retour avec le transporteur, durant lequel j'ai eu envie de rire: grâce à mon système, j'avais acheté à 300€ un lot de chaises qui en valait bien 2500€. J'avais trouvé l'impression d'avoir trouvé une faille dans le système, ce qui n'est pas vraiment faux.
L'évolution du projet
À ce stade, j'étais convaincu de la pertinence de cette approche qui permettait de dénicher des trésors cachés autour de chez soi. J'ai donc décidé de pousser le projet plus loin et d'élargir la recherche à plus de produits, et de marketplaces.
En ajoutant plus de produits, je ne pouvais plus me permettre de définir manuellement le "prix où ça devient intéressant", il fallait créer un système se basant sur l'analyse des tendances du marché.
Pour une Aeron par exemple, voici la répartition habituelle des prix sur le marché de l'occasion. Tout ce qui est en dessous d'un certain prix peut être considéré comme une bonne affaire:
[Graphique]
Bien sûr, pour que cela fonctionne, il y a un challenge de taille à résoudre: éliminer tous les faux positifs afin de pouvoir se baser sur des données fiables et propres. Et ça, je n'avais absolument pas anticipé la quantité de temps et d'énergie que ça allait me demander.