Aller au contenu
← Tous les articles
Article

Économie des boîtes LEGO avec science des données

Écouter en version balado

Peut-on prévoir le prix d'une boîte LEGO ? · 2:27 · voix synthétiques, script rédigé avec l’IA

Transcription

Sylvie : Il existe une boîte LEGO de 1965 dont on peut tracer le prix de revente sur un graphique. Alors Antoine s'est demandé : est-ce qu'un modèle simple peut prédire la suite ?

Thierry : Une prévision pour des briques en plastique. J'aime bien où ça va.

Sylvie : Il collectionne les LEGO et il écrit du Python. Il a donc croisé deux sources. Rebrickable, qui publie le catalogue : boîtes, thèmes, pièces, couleurs. Et BrickEconomy, qui a les valeurs de revente, mais pas de bouton de téléchargement.

Thierry : Donc il a scrapé le site.

Sylvie : Avec Playwright, oui. Et petit détail amusant : l'historique des prix n'est pas dans le tableau visible de la page. Il est dans un script intégré qui alimente un graphique, alors son code lit les balises script et en extrait les lignes.

Thierry : Malin. Et le catalogue, il montre quoi ?

Sylvie : Deux tendances. Le nombre de boîtes par année grimpe fortement à partir de la fin des années 1990 et dépasse mille ces dernières années. Le nombre moyen de pièces monte aussi : moins de cent presque toutes les années 1970 et 1980, autour de trois cents au sommet. Star Wars domine les thèmes, et de loin.

Thierry : Et le cas d'essai, la boîte de 1965 ?

Sylvie : La 001-1, la boîte Samsonite Gears. Un long historique et assez de reventes pour tracer une courbe. Il a nettoyé les données, retiré les symboles de devise, écarté les valeurs nulles, puis ajusté une régression linéaire de la valeur selon la date, projetée jusqu'en 2030.

Thierry : Et ça marche ?

Sylvie : Antoine est franc : ce n'est pas un signal de trading. C'est une façon de poser des questions simples, par exemple si la tendance domine ou à quel point les pointes récentes au-dessus de six cents s'écartent du modèle. Il prévient aussi que les prix étaient en dollars canadiens, même si une colonne s'appelle USD.

Thierry : Qu'est-ce qu'il faut encore surveiller ?

Sylvie : Un scraper cassé fait passer des mois manquants pour des chutes de prix. Les boîtes retirées du catalogue faussent les comptes. Et un modèle linéaire sur des boîtes à la mode part en vrille.

Thierry : Alors, à retenir ?

Sylvie : Un super exercice de pandas et de scraping asynchrone, et un rappel que le prix de revente, c'est du sentiment plus du plastique. Le code est dans le dépôt LegosTracker, et l'article complet a tous les graphiques.

Économie des boîtes LEGO avec science des données
Table des matières

Je collectionne les LEGO et j’écris du Python : j’ai donc croisé les exports Rebrickable avec un scraper BrickEconomy pour voir comment les boîtes et les thèmes ont évolué, et si un modèle simple pouvait suivre le prix de revente d’une boîte classique comme la 001-1. Les notebooks et le scraper sont dans AlgoETS/LegosTracker[1].

1. Sources de données

Jeu de donnéesCe qu’il apporte
CSV Rebrickableboîtes, thèmes, pièces, couleurs, inventaires : idéal pour compter et joindre
BrickEconomy (scrapé)historique de valeur et fourchettes de prix des boîtes scellées, absents de Rebrickable

Rebrickable publie sets.csv, themes.csv, parts.csv, colors.csv et les tables d’inventaire. Le schéma ci-dessous montre comment elles se joignent.

Tables Rebrickable et leurs clés

2. Les boîtes au fil des décennies

Regrouper sets par year fait ressortir deux tendances :

sets.groupby('year')['name'].nunique().plot(kind='bar')
plt.title("The Numbers of Sets by Year")
plt.show()

parts_by_year = sets[['year', 'num_parts']].groupby('year', as_index=False).mean()
parts_by_year.plot(x='year', y='num_parts', color="purple")
plt.title("Average Number of Parts by Year")
plt.show()
  1. Le nombre de boîtes par année grimpe fortement à partir de la fin des années 1990 et dépasse 1 000 ces dernières années.
  2. Le nombre moyen de pièces par boîte augmente aussi : moins de 100 pendant presque toutes les années 1970 et 1980, autour de 300 au sommet.

Nombre de boîtes publiées par année

Nombre moyen de pièces par boîte et par année

3. Les thèmes qui dominent le catalogue

On compte les boîtes par theme_id, on joint themes, on garde les thèmes de premier niveau (sans parent_id) et on trace les dix plus gros :

set_themes = sets["theme_id"].value_counts()
set_themes = pd.DataFrame({"id": set_themes.index, "count": set_themes.values})
set_themes = pd.merge(set_themes, themes, on="id")
set_themes_no_parent = set_themes[pd.isnull(set_themes["parent_id"])]
set_themes_top_10 = set_themes_no_parent.sort_values(by=["count"], ascending=False)[:10]
top_10 = set_themes_top_10["count"]
top_10.index = set_themes_top_10["name"]
top_10.plot.bar(color="gold", rot=30)

Les 10 thèmes qui comptent le plus de boîtes

Star Wars arrive loin devant, suivi de Friends, Gear, Ninjago, Bionicle et Technic. Gear et Service Packs rappellent que le catalogue compte bien plus que des boîtes à construire.

4. Pourquoi scraper BrickEconomy ?

Rebrickable dit ce qui existe, pas ce que les gens paient sur le marché secondaire. BrickEconomy affiche, pour chaque boîte, des estimations de valeur, des prévisions de croissance et les tendances de vente. J’ai donc écrit un scraper avec Playwright, asyncio, des modèles pydantic pour la validation et aiohttp.

Ce que BrickEconomy publie pour une boîte : valeur, prévision de croissance, tendance des ventes

pip install playwright pydantic aiohttp pandas scikit-learn matplotlib
playwright install

L’historique des prix n’est pas dans un tableau HTML. Il se trouve dans un script en ligne qui alimente un DataTable Google Charts ; parse_history lit donc les balises <script> et en extrait les lignes.

Le script de graphique qui contient l’historique des prix

La classe LegoAPI complète (navigation, parse_history, parse_set, écriture CSV) est dans le dépôt et dans l’article original sur Medium[2].

5. Historique de prix de la boîte 001-1

La 001-1, la boîte Samsonite Gears de 1965, est un bon cas d’essai : un long historique et assez de reventes pour tracer une courbe.

Page BrickEconomy de la 001-1 Samsonite Gears

Le scraper écrit deux fichiers par boîte. 001-1_history.csv contient des valeurs datées avec des annotations, comme la sortie de la boîte, et 001-1_new.csv des fourchettes de valeur mensuelles pour les exemplaires scellés.

001-1_history.csv : valeurs datées et annotations

001-1_new.csv : fourchettes de valeur mensuelles

Le nettoyage supprime les doublons, retire les symboles monétaires, convertit les dates et écarte les valeurs nulles :

df_0011.drop_duplicates(inplace=True)
df_0011['Currency Value'] = df_0011['Currency Value'].fillna(0)
df_0011['Currency Value'] = df_0011['Currency Value'].str.replace('[^\d.]', '', regex=True)
df_0011['Currency Value'] = pd.to_numeric(df_0011['Currency Value'], errors='coerce')
df_0011.drop(['Value', 'Status'], axis=1, inplace=True)
df_0011['Date'] = pd.to_datetime(df_0011['Date'], errors='coerce')
df_0011.rename(columns={'Currency Value': 'USD Value', 'Description': 'Set Description'}, inplace=True)
df_0011['USD Value'] = df_0011['USD Value'].fillna(0)
df_0011 = df_0011[df_0011['USD Value'] != 0]

Une réserve : BrickEconomy affichait des dollars canadiens pendant ma session (C$ dans les valeurs brutes), et le notebook renomme quand même la colonne USD Value. Lisez l’axe ci-dessous en dollars canadiens.

Sortie du notebook : boîtes la moins chère et la plus chère, prix moyen

6. Une régression linéaire comme prévision modeste

Le modèle est une simple régression linéaire de la valeur en fonction de la date, prolongée jusqu’en 2030 :

X = df_0011['Date'].map(pd.Timestamp.toordinal).values.reshape(-1, 1)
y = df_0011['USD Value'].values

model = LinearRegression().fit(X, y)

future_dates = pd.date_range('2008-12-31', '2030-12-31', freq='Y')
future_dates_ordinal = future_dates.map(pd.Timestamp.toordinal).values.reshape(-1, 1)
future_predictions = model.predict(future_dates_ordinal)

Régression linéaire de la boîte 001-1 et prédictions futures

Ce n’est pas un signal d’achat. C’est une façon de poser des questions simples : la tendance domine-t-elle, les résidus se regroupent-ils par époque, et à quel point les pics récents au-dessus de 600 s’en écartent-ils ? Tracer le gain entre deux observations rend ces pics évidents.

Gain et valeur dans le temps pour la 001-1

7. Quand ne pas se fier à cette analyse

PiègeEffet
Scraper casséDes mois manquants ressemblent à des krachs
Biais du survivant dans la table des boîtesLes boîtes retirées faussent les comptes
Modèle linéaire sur des boîtes à la modeLes résidus explosent
Confondre revente et prix de détailUne tout autre histoire économique

8. À retenir

Les données LEGO sont désordonnées et amusantes : de quoi pratiquer pandas, apprendre la discipline du scraping asynchrone, et se rappeler qu’un prix de revente, c’est du sentiment plus du plastique, pas des fondamentaux.

9. Articles liés

10. Références


Publié à l’origine sur Medium[2] (en anglais).

Références

  1. AlgoETS. (). LegosTracker. [Software repository] github.com.
  2. article original sur Medium. (). [Article] medium.com.
  3. Téléchargements Rebrickable. (). [Web page] rebrickable.com.
  4. BrickEconomy. (). [Web page] www.brickeconomy.com.
  5. hevalhazalkurt. (). exploring_the_data_of_LEGO_history. [Software repository] github.com.

Les références utilisent la date de publication de cet article.