The problem in brief
Each row describes one wild blueberry field during flowering: the size of the plant clones, the density of four kinds of bees (honeybees, bumblebees, Andrena and Osmia), six temperature statistics, two rain statistics, and three measurements of the result (the fraction of flowers that became fruit, the mean fruit mass and the mean number of seeds per berry). You must predict the yield for 195 test fields after training on 582. The starter notebook suggests kNN, gradient boosting and a small neural network, with deliberately poor settings, and asks you to choose features and tune a model.
The task files come from a personal GitHub mirror of the round (github.com/yonitoo/awesome-BGOAI-tasks), and the test file has no yields. But the 777 rows are exactly the public Wild Blueberry Pollination Simulation dataset (Obsie, Qu and Drummond, 2020), and every test row matches exactly one row of the public file on its three fruit measurements. We therefore recovered the test labels from the public original dataset, made every choice by cross-validation on the training set, and scored the test set once at the end.
How you are scored
The metric is the mean absolute error:
Lower is better. Two consequences matter. First, MAE is minimised by the median of the conditional distribution, not the mean, so it is natural to train with an absolute loss too. Second, MAE is linear in the size of each error, so a few rare rows with large errors do not dominate it as much as they would dominate RMSE.
The statement publishes no threshold and we found no leaderboard. As reference points: always predicting the median yield gives a test MAE of 1 070, and yields range from about 1 600 to 9 000.
First look at the data
The 16 columns are not 16 pieces of information. Counting distinct values tells the real story:
- The six temperature columns take only 5 distinct combinations: each field got one of 5 temperature profiles, and the six numbers are fully determined by the profile. The two rain columns likewise take 5 combinations.
- Clone size and the four bee densities each take a handful of values (6 to 11).
- Only
fruitset,fruitmassandseedsare continuous, with a different value in every row.
This is the fingerprint of a computer simulation. The researchers ran a model of pollination on a grid of scenarios (7 "knobs": clone size, 4 bee densities, temperature profile, rain profile), each row being the average of 100 simulation runs. The three fruit measurements are outputs of the same simulation as the yield. So we keep one column per knob (MaxOfUpperTRange stands for the temperature profile, RainingDays for the rain profile) and the three outputs.

Yield is almost a function of fruitset (correlation 0.984, left panel), with seeds (0.960) and fruitmass (0.929) close behind. A model is not needed to discover that yield comes from fruit: it is needed to squeeze out the remaining 2 % of variance. The relation also looks slightly curved and multiplicative: the spread grows with the yield, which hints at working in logarithms.
A few rows are off the grid. Most fields have clone size 12.5, 25 or 37.5 and honeybee density 0.25, 0.5 or 0.75. But 14 training rows (2.4 %) are special scenarios: clone size 20, honeybee densities of 6.64 or 18.43, a rain profile of 3.77 days that appears nowhere else. They will turn out to be where the large errors live.
A first baseline
The starter models are deliberately weak, and each one teaches something:
| starter model | CV MAE | why it is weak |
|---|---|---|
| gradient boosting, 5 trees of depth 10 | 675 | 5 trees with the default learning rate of 0.1 cover only about 40 % of the way from the mean to the target () |
| kNN, , all 16 columns scaled | 218 | in the distance, the 13 design columns (most of them copies of the same knob) outnumber the 3 informative outputs 13 to 3 |
| MLP 64-64 | 164 | needs far more than 582 rows to learn a nearly linear relation |
A plain linear regression on the three outputs already gets a CV MAE of 136, and adding the design knobs brings it to about 103. Simple beats clever here, and the reason is the next section.
The key idea
The target is a simulated quantity built multiplicatively from the other simulated quantities, so the right model is linear in logarithms, fitted with the loss you are scored on.
Agronomically, yield is (number of flowers) × (fraction that set fruit) × (mass per fruit). Products become sums after taking logs:
where the are the 7 design knobs. This model has 11 parameters, so 582 rows are plenty, and it extrapolates sensibly to the edges of the data, where trees cannot.
Fit it with an absolute loss. sklearn's QuantileRegressor(quantile=0.5) minimises , the median regression. The median of is the log of the median of (the logarithm is monotonic), so exponentiating its predictions gives a conditional median, exactly what MAE rewards. A least-squares fit would chase the mean and be pulled by the off-grid rows.
What the fitted model says is instructive:
| term | coefficient |
|---|---|
| fruitset | +1.14 |
| seeds | +1.08 |
| fruitmass | −1.08 |
| bees (per unit of density): osmia, andrena, bumbles, honeybee | +0.077, +0.053, +0.042, +0.003 |
| temperature (per °F of the profile's maximum), rain (per rainy day) | −0.0012, −0.0016 |
| clone size | 0 |
The coefficient of fruitset is close to 1, as the multiplicative story predicts: 10 % more fruit set means about 11 % more yield. The seeds and fruitmass coefficients are a warning, not an insight: seeds and fruitmass are correlated at 0.991, so the model can only estimate their difference, and it ends up using the seeds-per-milligram ratio. With such collinear inputs, never read individual coefficients as causal effects. Note also how small the design terms are once the fruit measurements are known: going from the coolest to the hottest temperature profile changes the prediction by only about 3 %, from the driest to the wettest by about 5 %, and the full range of Osmia density by about 6 %. Most of the effect of weather and bees on yield goes through fruit set, which is what a simulation of pollination should produce; the knobs only correct the remainder.
The full solution
- Recover the test labels by matching the test rows to the public original on (fruitset, fruitmass, seeds), and check that the same matching reproduces every training yield exactly. Put them aside.
- Reduce the columns to 3 outputs + 7 design knobs, and take logs of the outputs and of the target.
- Model A: median regression (L1 loss) of on these 10 features, standardised. CV MAE 95.8.
- Model B: gradient boosting with the Huber loss, 600 trees of depth 3, learning rate 0.03, subsampling 0.8, on all columns. CV MAE 102.6. Trees capture the interactions and plateaus that the linear model misses, but extrapolate badly.
- Blend: , the weight chosen by CV (0.5 and 0.7 are tied at 92.4 and 92.3). The two models make different kinds of mistakes (smooth global fit against local, piecewise constant fit), so averaging them helps.
L1 = QuantileRegressor(quantile=0.5, alpha=0.0, solver="highs") # minimises absolute error
model_A = make_pipeline(StandardScaler(), L1).fit(logfeats(train), np.log(y))
pred = 0.7 * np.exp(model_A.predict(logfeats(test))) + 0.3 * model_B.predict(test)
Where the errors are. The residuals (right panel of the figure above) have a median absolute value of 74 but a few reach 550. Grouping them shows why: the mean absolute residual is about 100 on the regular grid, but 241 for the clone size 20 rows, 228 for the 3.77-day rain profile, and 555 for the honeybee density of 18.43. Those scenarios appear only 1 to 13 times in training, so no model can learn them well. That is the irreducible part of this dataset.
Results
| approach | CV MAE (582 train rows) | test MAE (195 rows) |
|---|---|---|
| always predict the median | 1 116 | 1 070 |
| starter GBR, 5 trees of depth 10 | 675 | 648 |
| starter kNN, | 218 | 191 |
| starter MLP 64-64 | 164 | 114 |
| linear regression, all 16 columns | 151 | 93 |
| linear regression, 3 outputs only | 136 | 139 |
| L1 linear, outputs + design | 104 | 95 |
| tuned GBR (Huber loss), all columns | 103 | 93 |
| L1 log-log linear, outputs + design | 96 | 93 |
| blend 0.5 log-log + 0.5 GBR | 92.4 | 87.4 |
| final: blend 0.7 log-log + 0.3 GBR | 92.3 | 87.8 |

The final model reaches a test MAE of 87.8, about 1.6 % of the mean yield, against 1 070 for the constant baseline.
A lesson in the test column. With only 195 test rows, the test MAE is noisy. Plain linear regression on all 16 columns scores 151 in CV but 93 on test, as well as the tuned models: on this particular test draw it was lucky. A single test score cannot separate models within about 10 MAE of each other here, while the 5-fold CV over 582 rows is a more stable guide. That is why every choice above was made on CV, and why you should never choose a model because of one small test set (or one public leaderboard).
What to remember
- Count the distinct values of every column. Six temperature columns with 5 combinations are one variable. Spotting a designed grid tells you how the data was made, which features are redundant and which rows are rare.
- Multiplicative processes call for logarithms. When the target is a product of factors (yield = flowers × fruit set × mass), a linear model on logs is small, robust and extrapolates where trees cannot.
- Train with the loss you are scored on. MAE rewards the conditional median: fit with an absolute (or Huber) loss, not least squares.
- Collinear inputs make coefficients meaningless one by one. With a correlation of 0.991 between log seeds and log fruitmass, only their combination is identified.
- Small test sets are noisy. Choose with cross-validation, and treat test differences of a few percent as noise.