Models: learning from examples
In short: A machine learning model learns the rule from examples (features X and a target y) with fit, predicts with predict and is checked on the test set against a baseline.
Problem
“How many people do I put in the warehouse?”
The manager makes the warehouse schedule for next week: how many people take in and pack the orders every day. Until now they guess by feel. They want a number for every day. Here are the orders from the last year, by day:
There are 365 days, and on average 30.45 orders come in per day. We count all the orders, the cancelled ones too: the question is how many arrive, and a cancelled order is also received and handled. Next to every day are the day of the week (0 is Monday, 6 is Sunday) and the month. How do you get a number for Friday, 6 November, from these examples?
The idea
The question first
Before the model you ask what decision you will make with the forecast. Here it is how many people to have every day. Three things follow from it:
- What you predict. The number of orders in the day, not the revenue: packing depends on the orders.
- What you know in advance. The schedule is made on Sunday. Then you know the day of the week and the month of every day. How many orders will come in until noon on Wednesday you do not know.
- How accurate it must be. Enough not to change the decision: if the forecast misses by less than one person handles, the schedule is the same.
If the schedule does not change whatever the forecast shows, you do not need a model.
The idea
A model is a function learned from examples
A model is a function: you give it the day and it returns a forecast. You do not write the rule. You give examples, days with their known number of orders, and the model finds a rule that fits them by itself. The input is called the features and is written X. What you predict is the target, y.
The day of the week is a number from 0 to 6, but it is not a quantity: Sunday (6) is not “three times Wednesday” (2). So every value becomes its own column of 0 and 1. This is one-hot encoding, and pd.get_dummies does it:
There are 19 columns: 7 for the days and 12 for the months. 1 November 2025 is a Saturday, so its row has a 1 only in weekday_5 (and in month_11, which is further to the right).
The idea
fit, predict and the test
The models in scikit-learn have the same two steps:
fit(X, y)learns from the examples;predict(X)gives a forecast for new rows.
Whether the model is good, you check on days it has not seen. train_test_split shuffles the rows and splits them: 75% are for training, and 25% for the test. With random_state=42 the split is the same on every run. The first load of scikit-learn (together with scipy) downloads about 18 MB and takes a few seconds:
The model learns from 273 days, and 92 days are for the test. On them it misses by 4.38 orders a day on average: the mean of the differences between the fact and the forecast, without the sign. On the training days the error is 4.09. There the model always looks better, because it has seen the answers. So the number you report is from the test.
LinearRegression is a model that adds up one number for each column. How it finds them is in the next lesson. Here only fit and predict matter, and they are the same for every model.
More precisely, if you are curious
The days are ordered in time, and train_test_split shuffles them. Here this is a simplification: the model learns about September from days after the test day too. In the next lesson you will see why for a forecast it is more honest to split by time: you train on the earlier months and check on the later ones. How a model learns by hand, without a library, is in the lesson Linear regression of the AI course.
The idea
A baseline first
Is an error of 4.38 orders good? Without a comparison you do not know. You compare with a baseline: a forecast without a model, one anyone could come up with. For example “always the mean”. DummyRegressor is exactly that, with the same fit and predict:
The baseline says 30.34 for every day: the mean of the training days. It misses by 5.76 orders, and the model by 4.38. The model is 1.38 orders more accurate, with a 24% smaller error. It makes sense.
A model that does not beat the baseline is worth nothing. It is code, data and upkeep, and it gives as much as “always 30”. That is why the baseline comes first. Another good baseline is what people do now, for example “as many as on the same day last week”.
Try it
The rule “like last week”
Right now the manager plans “as many as on the same day last week”. How much does this rule miss on the test days? Put in last_week the orders from 7 days earlier for every day, and in err the mean error without the sign on the days of y_test.
Solution
import numpy as np
import pandas as pd
orders = pd.read_csv('year_orders.csv')
orders['ordered_at'] = pd.to_datetime(orders['ordered_at'])
daily = orders.set_index('ordered_at').resample('D').size().rename('orders').to_frame()
daily['weekday'] = daily.index.dayofweek
daily['month'] = daily.index.month
X = pd.get_dummies(daily[['weekday', 'month']], columns=['weekday', 'month'], dtype=int)
y = daily['orders']
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
model = LinearRegression().fit(X_train, y_train)
last_week = y.shift(7)
err = (y_test - last_week[y_test.index]).abs().mean()
print(round(err, 2))The rule misses by 6.16 orders on average on the test days: more than “always the mean” too (5.76). One day from last week carries its own noise, and the mean of 273 days smooths it out. shift(7) takes the value from 7 rows earlier, that is from a week earlier. Three of the test days are in the first week and have no previous week, and mean() skips the empty ones. shift(-7) would take next week: a future you do not know when you make the schedule.
Exercise
Is the day enough? And the plan for next week
Is the day of the week enough on its own, without the month? Fit LinearRegression only on the weekday columns of X_train. Put in err the mean error on the test days, in base the error of “always the training mean”, and in beats whether the model beats it.
Solution
import numpy as np
import pandas as pd
orders = pd.read_csv('year_orders.csv')
orders['ordered_at'] = pd.to_datetime(orders['ordered_at'])
daily = orders.set_index('ordered_at').resample('D').size().rename('orders').to_frame()
daily['weekday'] = daily.index.dayofweek
daily['month'] = daily.index.month
X = pd.get_dummies(daily[['weekday', 'month']], columns=['weekday', 'month'], dtype=int)
y = daily['orders']
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
model = LinearRegression().fit(X_train, y_train)
week_cols = [c for c in X.columns if c.startswith('weekday')]
week_model = LinearRegression().fit(X_train[week_cols], y_train)
err = np.abs(y_test - week_model.predict(X_test[week_cols])).mean()
base = np.abs(y_test - y_train.mean()).mean()
beats = err < base
print(round(err, 2), round(base, 2), beats)With the day only, the model misses by 5.52 orders, and the baseline by 5.76. It beats it, but by 0.24 orders: by a hair. The month brings more: with it the error is 4.38. Measured on the training days the model looks better (5.00), but it has seen those days. And the mean of y_test as a baseline is an answer you are not supposed to know.
The test said that the model with the day and the month beats the baseline. Now the forecast for the real week, from Monday 2 to Sunday 8 November 2026. Fit the model again on all 365 days, make X_new with the columns of X and put in plan the forecast for every day (a Series with the dates as the index).
Solution
import numpy as np
import pandas as pd
orders = pd.read_csv('year_orders.csv')
orders['ordered_at'] = pd.to_datetime(orders['ordered_at'])
daily = orders.set_index('ordered_at').resample('D').size().rename('orders').to_frame()
daily['weekday'] = daily.index.dayofweek
daily['month'] = daily.index.month
X = pd.get_dummies(daily[['weekday', 'month']], columns=['weekday', 'month'], dtype=int)
y = daily['orders']
from sklearn.linear_model import LinearRegression
final = LinearRegression().fit(X, y)
dates = pd.date_range('2026-11-02', periods=7)
week = pd.DataFrame({'weekday': dates.dayofweek, 'month': dates.month}, index=dates)
X_new = pd.get_dummies(week, columns=['weekday', 'month'], dtype=int).reindex(columns=X.columns, fill_value=0)
plan = pd.Series(final.predict(X_new), index=dates).round(1)
print(plan)The forecast is 32.9, 32.0, 31.6, 33.1, 37.9, 29.6 and 26.0 orders from Monday to Sunday. Friday is the strongest, and Sunday the weakest. After the check, the model is fitted on all the days: the last months are the closest to what is coming. get_dummies on the seven days gives only month_11, and reindex(columns=X.columns, fill_value=0) adds the missing columns with 0 in the order of X. If you give the model the day and the month as numbers, the forecast falls evenly from 35.6 on Monday to 31.3 on Sunday: the model sees the day as a quantity.
Test
Check yourself
Related lessons
Section titled "Related lessons"- Builds on: Selecting: [], loc and iloc · New columns · Types and missing values · Dates and time series
- Continues in: Linear regression · Classification · Data leakage · Cross-validation
- Tasks on this topic: Models with scikit-learn