Case study, part 1: will a lost item be returned? Tasks 1 to 8
The real EPITA 2026 exam, run in the studio, under exam conditions: 258 902 items, fourteen tasks, a mission that checks each one
Objectives
By the end of this session you will be able to:
- Work an exam subject as written, without rewriting it to suit the tool
- Concatenate four annual files and check the total to the row
- Build a target from a date, then remove that date from the inputs
- Chain four left joins without changing the row count once
- Produce a baseline and a first real classifier under time pressure
- Use hints when you are stuck, and know that they are counted
Prerequisites
- A rakoon-ds account on https://rakoon-ds.apps.way-up.io (free, browser only, nothing to install), and the group join code your instructor gives you
- A recent Chrome, Edge or Firefox. Computation runs either in your own tab (browser engine) or on the server; the header pill tells you which
- The
epita-2026f-objets-trouvesmission, assigned to your group. Your instructor imports it in one click from the embedded examples (Partir d'un exemple on the missions page, or the EPITA exam sandbox button which creates the space, three groups and eight missions at once) - The data pack (see below)
- Practical works 1 to 13. This session assumes all of them
- Transformation, chart and algorithm names come from the rakoon-ds registry and are served in French even when the interface is in English. Every step below gives you the French label you will click and, in
code font, the registry key the mission checks against.
Data
The SNCF lost-property exam pack. Seven files, all semicolon-separated and UTF-8.
| File | Rows | What one row is |
|---|---|---|
objets-trouves-restitution-2019 to -2022 | 88 263 + 47 350 + 61 989 + 61 300 = 258 902 | one lost item, 7 columns |
liste-des-gares.csv | 4 144 | one station and one railway line: 3 471 distinct stations |
frequentation-gares.csv | 2 967 | annual traffic per station |
departements-regions.csv | 94 | department, region, school holiday zone |
holidays.xml | 1 609 <row> | one date and one zone, 607 distinct dates |
The files are not shipped with rakoon-ds: the platform delivers the mission, not the data. Get them from your instructor, folder Content/exams/data-exploration-preparation/2026f/. Public equivalents: SNCF open data (data.sncf.com: lost property and returns, station list, station traffic) and data.gouv.fr for regions and school holidays.
Two traps announced in the subject itself. First, the timestamps carry a variable UTC offset (+01:00 in winter, +02:00 in summer): an item recorded at 11:47 must not become 09:47. Second, the UIC station code has ten characters in the lost-property files (0087474007) and eight everywhere else, and the station list has several rows per station, so a naive join multiplies rows.
Timing
The steps below add up to the announced duration. If you fall behind, Step 1 to Step 3 are the ones that must be finished.
| # | What you do | Time |
|---|---|---|
| Step 1 | Set up, and load the four annual files | 15 min |
| Step 2 | Task 1: merge, dates, and the 93 rows without a station | 15 min |
| Step 3 | Task 2: the target, and the date that must not stay | 15 min |
| Step 4 | Task 3: enrich, four joins, zero row lost | 20 min |
| Step 5 | Task 4: explore, and pin what you will use | 15 min |
| Step 6 | Task 5: baseline, then a real classifier | 15 min |
| Step 7 | Tasks 6 to 8: delay, geography, seasonality | 10 min |
| Total | 105 min | |
Instructions
Step 1: Set up, and load the four annual files15 min
- Missions page: the mission is there. Expand it, click Créer le projet and name it
EPITA 2026f lost property. - Open the workshop, then the Mission button: the panel opens with fourteen steps, each with what it checks and up to four hints.
- Import the four annual files, one at a time. Roughly 0.3 s each; the largest is 12.4 MB.
- Check each node: 88 263, 47 350, 61 989, 61 300.
Every hint you open is counted and shown to your instructor. That is not a punishment, it is data: a step where the whole room opened hint 3 is a step that was badly written. Use them when you are stuck, and not before.
Step 2: Task 1: merge, dates, and the 93 rows without a station15 min
- Family Combiner, card Concaténation (
concat): stack the four. Name the resultobjets-trouves-2019-2022. - Check: 258 902 rows. The mission checks this number exactly, and so does the marking scheme.
- Family Dates, card Convertir en date (
to_date) onDateand onDate et heure de restitution. Read the preview note: it says how many values it could not parse. Zero is what you want. - Count the rows with no station: apply Supprimer les lignes vides (
dropna) on the station column and subtract. 93 rows, leaving 258 809.
There is no "count the missing values in this column" transformation: you get the number by removing them and subtracting. It works, it is two clicks, and it is worth saying in your report that this is how you got it.
Step 3: Task 2: the target, and the date that must not stay15 min
The target is returned: yes when the return date is filled in, no otherwise.
- Build it. The click-only route is Colonne par formule (
expression) on the return date, or Catégoriser (seuils) (categorize) on a derived numeric column. Either is accepted. - Check the balance: 40.14 % yes over the whole period, and by year 36.32 / 36.90 / 40.23 / 48.04 %.
- Now remove the return date, and every column derived from it, with Supprimer des colonnes (
drop_columns). - Write the Question et contexte section: what is predicted, when it is predicted, and why the return date cannot be an input.
Try it wrong once, deliberately, and keep the screenshot: train with Date et heure de restitution_year among the inputs. Accuracy 0.9991, and a red banner above the metrics: leak_association, association 1.00. The tool catches for you what a human marker would have caught. Then delete that model and move on.
Step 4: Task 3: enrich, four joins, zero row lost20 min
This is the task the subject is built around, and the one where rows multiply if you are not careful.
- Time of day and calendar. Décomposer une date/heure (
date_parts) onDate:year,month,day,hour,weekday,is_weekend. - Stations. Deduplicate
liste-des-gares.csvwith Supprimer les doublons (drop_duplicates) on the UIC code first: 4 144 rows become 3 471. Then Fusion (join) (join), typeleft. Check the count: 258 809 in, 258 809 out. - Traffic. Join
frequentation-gares.csvon the station code. Same check. - Regions. Join
departements-regions.csvon the department code. Same check. - Holidays. Import
holidays.xmlwith Mapper XML / JSON, deduplicate on the date, then join on three keys: year, month, day. Same check.
After every join, read the row count in the preview note. The subject is designed so that a naive join on the station code multiplies the dataset by roughly twenty. The preview now says so in red before you apply, which is help the students who sat this exam before you did not have. Use it, and write the four before / after pairs in your report.
The connectivity feature the subject suggests as an "external source" is already in the file: liste-des-gares.csv has one row per station and per line, so an Agréger (group by) (aggregate) with count before deduplicating gives the number of lines serving each station. Two transformations, no external file.
Step 5: Task 4: explore, and pin what you will use15 min
Six figures, each with one written sentence. Suggested set:
| Question | Chart |
|---|---|
| Return rate by item type | Comptage / moyenne (barres) (bar) |
| Return rate by station, twenty biggest | Comptage / moyenne (barres) (bar) |
| Items per month, one series per year | Comptage / moyenne (barres) (bar) |
| Items by hour of day | Histogramme (histogram) |
| Traffic against item volume | Nuage de points (scatter) |
| Where the stations are | Carte (géographique) (map) |
- Pin all six and pour them into the Exploration section with captions.
- One number the marking scheme expects: April 2020, 58 items, against 7 904 in April 2019. Find it and explain it in one sentence.
To chart a rate rather than a count you need a 0 / 1 column first (the aggregation menu has no "rate of"). Build it with Colonne par formule (expression), then aggregate it with mean. And the bar chart shows the twenty highest values, not the twenty most frequent categories: on a rate, that means the twenty stations with three items each. Filter on a minimum count first.
Step 6: Task 5: baseline, then a real classifier15 min
- Train Modèle de référence (classe majoritaire) (
dummy_clf) onreturned. Reference: accuracy 0.5986. That is the bar. - Train Forêt aléatoire (
rf_clf), 100 trees, default depth 10. Reference: 0.649. Roughly 13 seconds. - Raise the depth to 40 and retrain. Reference: 0.689, and roughly 200 seconds.
- Write the Évaluation section: the three numbers, the time each one cost, and whether the last four points were worth fifteen times the compute.
That deep forest weighs about 500 MB on disk and pushes the server past 2.5 GB of memory while it trains. On a shared classroom instance that is the number that matters, not the four points of accuracy. The studio now compresses artefacts and warns above 100 MB; it is still the single heaviest thing you can do in this course.
The exam screenshot sets two forest hyperparameters that rakoon-ds does not expose (max_features, min_samples_split). You cannot reproduce that configuration, and you should say so in your report rather than pretend. The spirit of the task, a reference model, is intact.
Step 7: Tasks 6 to 8: delay, geography, seasonality10 min
Three shorter tasks. Do what you can in ten minutes and note where you stop; Session 15 continues from here.
- Task 6, return delay. A regression on the number of days between recording and return. Reference: median 3 days (the marking scheme says 2.9), baseline MAE 10.25 / RMSE 33.43, forest 12.41 / 31.33.
- Task 7, geography. A Carte (géographique) (
map) of the 156 stations, plus two correlations. Reference: traffic against return rate 0.07, traffic against item volume 0.67. Say what that pair of numbers means. - Task 8, seasonality and school holidays. Join the holiday table on four keys (year, month, day, zone) to get the per-zone flag. Reference: 39.4 % return rate during holidays against 40.5 % outside. A 1.1 point difference.
There is no way to express a difference between two dates in days: the subtraction gives an unreadable duration. Task 6 goes through an approximation in calendar days, and that is a genuine gap in the tool. Write it in your report; do not hide it behind a rounded number.
End of session: click Vérifier. Steps 1 to 8 of the mission should be green. Your instructor sees the progress table, one row per student, one column per step.
What you should have
- 258 902 rows concatenated, then 258 809 after dropping the stationless items
- A target at 40.14 % yes, and the return date removed from the inputs
- Four joins, each verified at 258 809 rows in and out
- Six pinned figures with captions
- Three classifiers: 0.599, 0.649, 0.689
- Mission steps 1 to 8 validated
Deliverables
- Mission:
epita-2026f-objets-trouves, steps 1 to 8 - Report: Question et contexte, Données and Exploration written, six figures poured in
- The join log: four lines, keys and rows before / after
Bonus
- Reproduce the leak on purpose, screenshot the banner, and put it in the report as the proof that you looked.
- Compute the connectivity feature (lines per station) with a count aggregation before deduplicating, and check whether it helps the model.
- Run the same eight tasks on the
epita-2024smission, whose target is a count per day and per station and which is judged on RMSE. Reference: baseline RMSE 5.853, forest on the date alone 5.466, forest on the full feature set 3.493.
Resources
- Session 14 slides (the lecture this practical work follows)
- Course page: both programmes, all fifteen sessions
- rakoon-ds studio
missions/dep-14.json: which steps of the embedded mission belong to this session, and the two extra checkpoints- The embedded mission itself: missions page, Partir d'un exemple →
epita-2026f