When the End Is Beside the Beginning
The hour after 23 is zero, yet ordinary subtraction puts those hour numbers far apart. A repeating feature needs a representation that keeps its beginning beside its end.
12 sections · 3 questions · 2 coding challenges
The arrow keys move between sections too.
Representing a Repeating Cycle as a Position
BOTIE
Sine and cosine coordinates use the familiar geometry of a circle to preserve a cycle's continuity. Scikit-learn's time-feature example documents this representation among several modelling choices. Our greenhouse clock is an invented teaching example, and we are not presenting the circle representation as a newly invented algorithm.
Sources for this history
Why Does Midnight Look So Far From Eleven?
Botie records greenhouse temperatures throughout the day. If we encode the hour as a number from zero to 23, late evening and early morning sit at opposite ends of the number line. On a clock they are neighbours.
A clock gives us a useful picture here. The hour moves around the face and returns to its starting position each day. We can put our hour values on a circle too, then use two coordinates to describe each position. Hours on either side of midnight will stay close together.
The hours locate positions in a repeating day, not measured greenhouse outcomes.
Step 1 of 3
The written hour wraps around
The order continues through midnight. Zero belongs immediately after 23 on the next day.
Late evening to morning
- Consecutive hour 122
- Consecutive hour 223
- Consecutive hour 30
- Consecutive hour 41
Step 2 of 3
Use two coordinates on a clock face
Quarter turns give easily recognised positions. The coordinate order here is cosine, then sine.
Vertical: Sine coordinate
Horizontal: Cosine coordinate
Step 3 of 3
The cycle closes
The position at hour 24 is the same as the position at hour zero. Here eleven at night and one in the morning sit beside midnight. The date must be stored separately if it matters.
Vertical: Sine coordinate
Horizontal: Cosine coordinate
Two coordinates preserve a repeating position
Dividing identifies the fraction of a cycle. Sine and cosine locate that fraction on a circle, so a full turn returns to the start.
Can midnight stay close to the hour before it?
An hour number jumps at midnight even though very little time has passed. Change the hour around that boundary and compare the two coordinates of its position on the cycle.
BOTIE
Cosine and sine coordinates
- 01
- 10
Follow the operations
1. Hour or cycle position
0
2. Length of one cycle
24
3. Divide
0
4. Full turn in radians
6.2832
5. Multiply
0
6. Cosine of an angle
1
7. Sine of an angle
0
8. Collect two results
- 01
- 10
9. Result
- 01
- 10
This encodes a fixed-period feature. It does not fit a temperature curve or handle calendar irregularities.
1. Decide What Repeats
An hour of day repeats every 24 hours. Elapsed time since an experiment began does not. We should use a circular representation only for the repeating feature, while keeping nonrepeating information elsewhere.
For this lesson, the input is an hour measured from midnight and the period is 24 hours. Fractions such as half past six can be represented too.
The period is a modelling assumption. A weekly pattern needs a different period, and calendar months do not all contain the same number of days.
2. Turn the Fraction of a Cycle Into an Angle
Divide the hour by the period to find how far around the cycle we are. A full circle is two pi radians. Multiplying by that full-turn angle places the hour around the circle.
Hour 6: fraction = 6 / 24 = 1/4
angle = (1/4) × 2π = π/2
Hour 12: fraction = 12 / 24 = 1/2
angle = (1/2) × 2π = πRadians are a way to measure an angle. The important fact here is that a full period brings us back to the same position.
3. Use Both Coordinates
Cosine gives the horizontal coordinate of our point on a unit circle. Sine gives its vertical coordinate. We need both because a single coordinate is shared by different positions.
Hour 0: [cos(0), sin(0)] = [1, 0]
Hour 6: [cos(π/2), sin(π/2)] = [0, 1]
Hour 12: [cos(π), sin(π)] = [-1, 0]
Hour 18: [cos(3π/2), sin(3π/2)] = [0, -1]Sine alone would give zero at both midnight and noon. The cosine coordinate distinguishes them. Near midnight, both coordinates change smoothly across the written day boundary.
4. The Representation Is Not the Whole Prediction Rule
Two coordinates tell a model where we are in the cycle. They do not guarantee that the daily temperature follows a simple sinusoid. Weather, heating controls, and the season can still matter.
A linear combination of this single sine-cosine pair describes one smooth daily oscillation. More complicated recurring shapes may need additional harmonics, splines, or a flexible model. Choose that complexity through appropriate evaluation.
The workshop builds the pair for one hour. The Python practice builds it for several times and then changes the period to a week.
5. A Circle Fixes the Boundary, Not Every Daily Pattern
Putting hours on a circle makes late night and early morning neighbours. A linear model using one sine and one cosine can then describe one smooth rise and fall per cycle. It cannot independently place several sharp peaks wherever we choose.
If demand rises at two watering times, additional harmonics or another representation may help. Each additional harmonic introduces a faster repeating pattern. Choose that flexibility with validation rather than assuming a circular representation solves every time-related prediction problem.
6. Represent a Pattern That Repeats Twice a Day
The first harmonic completes one turn over a day. The second completes two. They are separate features, so a model can combine broad daily variation with a repeated morning-and-evening pattern.
Hour-of-day does not identify the date, season or timezone. Preserve those when they matter, and handle irregular or repeated clock times before treating array positions as equal time intervals.
Compare one daily cycle with two
The table samples four six-hour positions. Cosine is enough here to show the different frequencies.
import numpy as np
hour = np.array([0., 6., 12., 18.])
angle = 2 * np.pi * hour / 24
print(np.round(np.cos(angle), 3).tolist())
print(np.round(np.cos(2 * angle), 3).tolist())[1.0, 0.0, -1.0, -0.0]
[1.0, -1.0, 1.0, -1.0]The second feature gives midnight and noon the same value. A model still needs data to learn whether that repetition is relevant.
Check yourself
Questions on Parts 1 to 6
Question 1 of 3
Hour 24 and hour zero share the same cyclical position.
Try it with Botie
Build with Botie
Write and run Python