Machine Learning Academy · Lektion

Udtræk af features fra dato og tid

De lærende opdeler datetime-kolonner i år, måned, ugedag og time samt cykliske sinus-/cosinusrepræsentationer, der indfanger periodicitet.

Lektion 2 af 413 trin

Udtræk af features fra dato og tid er en gratis Machine Learning Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Machine Learning Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvorfor rå tidsstempler er ubrugelige

Et råt Unix-tidsstempel som 1718784000 eller en datotidsstreng som '2024-06-19 14:30:00' indeholder værdifulde oplysninger — klokkeslæt, ugedag og måned — men en model kan ikke tilgå disse oplysninger fra råværdien. En lineær model ser tidsstemplet som ét stort heltal og kan kun lære, at senere tidsstempler forudsiger højere eller lavere mål, mens alle periodiske mønstre overses. Funktionsudtræk opdeler tidsstemplet i meningsfulde numeriske komponenter, som modeller kan bruge direkte.

Parsing af datotidskolonner med Pandas

Pars altid dato- og tidsstrenge til datatypen pd.Timestamp eller datetime64 ved hjælp af pd.to_datetime(), før du udtrækker funktioner. Når de er parset, stiller Pandas en .dt-adgang til rådighed med dusinvis af attributter: .dt.year, .dt.month, .dt.day, .dt.hour, .dt.minute, .dt.dayofweek (0=mandag), .dt.dayofyear, .dt.quarter, .dt.is_weekend og mange flere. Hver attribut bliver til en ny heltalskolonne i din funktionsmatrix.

import pandas as pd

dates = pd.Series(['2024-01-15 08:30:00', '2024-06-21 17:45:00', '2024-12-25 12:00:00'])
dts = pd.to_datetime(dates)

df = pd.DataFrame({
    'year': dts.dt.year,
    'month': dts.dt.month,
    'day': dts.dt.day,
    'hour': dts.dt.hour,
    'dayofweek': dts.dt.dayofweek,  # 0=Mon, 6=Sun
    'quarter': dts.dt.quarter,
    'is_weekend': (dts.dt.dayofweek >= 5).astype(int)
})
print(df.to_string())

Problemet med rå cykliske funktioner

Klokkeslæt 23 og 0 ligger ved siden af hinanden (én time fra hinanden), men er numerisk langt fra hinanden (23 enheder). Hvis du koder klokkeslættet som et heltal fra 0 til 23, kan en lineær model ikke lære, at mønstre omkring midnat ligner mønstre omkring kl. 23. Det samme gælder måneder (december og januar ligger ved siden af hinanden), ugedage (søndag=6 og mandag=0) og alle andre cykliske størrelser. Når du behandler dem som rå heltal, skaber du en kunstig diskontinuitet ved cyklusgrænsen, som modellerne skal forsøge at håndtere.

Cyklisk kodning med sinus og cosinus

Løsningen er at kode cykliske funktioner som sinus- og cosinuspar. For en variabel, der går fra 0 til T-1, koder du den som: sin(2π × value / T) og cos(2π × value / T). Det afbilder cyklussen på en cirkel i et todimensionalt rum. Klokkeslæt 23 og klokkeslæt 0 er nu nabopunkter på cirklen, så deres euklidiske afstand er lille. Alle modeller, der beregner afstande eller lineære kombinationer, kan nu indfange cykliske mønstre korrekt ved at bruge sinus- og cosinuskomponenterne sammen.

import numpy as np
import pandas as pd

hours = np.arange(24)
df = pd.DataFrame({'hour': hours})
df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)

# Distance between hour 23 and hour 0 on the circle
def circle_dist(h1, h2):
    s1, c1 = df.loc[df['hour'] == h1, ['hour_sin', 'hour_cos']].values[0]
    s2, c2 = df.loc[df['hour'] == h2, ['hour_sin', 'hour_cos']].values[0]
    return np.sqrt((s1-s2)**2 + (c1-c2)**2)

print('Distance 23 to 0:', round(circle_dist(23, 0), 4))  # small
print('Distance 0 to 12:', round(circle_dist(0, 12), 4))  # large

Anvendelse af cyklisk kodning på flere funktioner

Mønstret for cyklisk kodning kan generaliseres til alle periodiske funktioner: måned (T=12), ugedag (T=7), klokkeslæt (T=24), minut (T=60), dag i året (T=365). Hver cyklisk funktion genererer to nye funktioner (sinus og cosinus). For træbaserede modeller fungerer rå heltalskodning ofte fint, fordi træer opdeler efter tærskler og kan indfange cykliske mønstre gennem flere opdelinger. Men for lineære modeller, neurale netværk og afstandsbaserede algoritmer er cyklisk kodning vigtig.

import numpy as np
import pandas as pd

def cyclical_encode(df, col, period):
    df[col + '_sin'] = np.sin(2 * np.pi * df[col] / period)
    df[col + '_cos'] = np.cos(2 * np.pi * df[col] / period)
    return df

df = pd.DataFrame({'hour': [8, 12, 20, 23], 'month': [1, 6, 11, 12], 'dow': [0, 2, 4, 6]})
df = cyclical_encode(df, 'hour', 24)
df = cyclical_encode(df, 'month', 12)
df = cyclical_encode(df, 'dow', 7)
print(df[['hour', 'hour_sin', 'hour_cos', 'month', 'month_sin', 'month_cos']].round(3))

Tid siden reference: relative tidsstempler

I stedet for at udtrække kalenderkomponenter er det nogle gange den forløbne tid siden en hændelse, der er vigtig: dage siden sidste køb, timer siden systemgenstart eller måneder siden kontoen blev oprettet. Disse relative varighedsfunktioner indfanger effekter af aktualitet, som absolutte kalenderfunktioner overser. Beregn dem som simple differenser: (now - event_date).dt.days eller (now - event_date).dt.total_seconds(). Aktualitetsfunktioner er især værdifulde i modeller for kundeadfærd (churn, LTV) og forudsigende vedligeholdelse.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'last_purchase': pd.to_datetime(['2024-01-10', '2024-05-20', '2024-06-15']),
    'signup_date': pd.to_datetime(['2023-01-01', '2023-06-15', '2024-01-01'])
})
reference = pd.Timestamp('2024-06-19')
df['days_since_purchase'] = (reference - df['last_purchase']).dt.days
df['account_age_days'] = (reference - df['signup_date']).dt.days
print(df[['days_since_purchase', 'account_age_days']])

Er weekend og åbningstid-indikatorer

Booleske indikatorfunktioner, der udledes af tidsstempler, er enkle, men ofte effektive. is_weekend, is_business_hours, is_holiday, is_month_end — de skaber tydelige binære opdelinger, som træmodeller kan udnytte i en enkelt opdeling. Lineære modeller drager også fordel af dem, fordi disse indikatorer skaber særskilte justeringer af skæringen. En indikator for helligdage kan have særlig stor betydning i modeller for detailsalg, trafik og energiforbrug, hvor helligdage medfører systematiske ændringer i efterspørgslen.

import pandas as pd

dates = pd.to_datetime(['2024-06-17', '2024-06-19', '2024-06-21', '2024-06-22', '2024-12-25'])
df = pd.DataFrame({'date': dates})
df['is_weekend'] = (df['date'].dt.dayofweek >= 5).astype(int)
df['is_month_end'] = df['date'].dt.is_month_end.astype(int)
df['is_quarter_end'] = df['date'].dt.is_quarter_end.astype(int)
df['week_of_year'] = df['date'].dt.isocalendar().week.astype(int)
print(df.to_string())

Forsinkelsesfunktioner og rullende statistikker

For tidsseriedata er tidligere værdier af målvariablen ofte blandt de bedste prædiktorer. Forsinkelsesfunktioner forskyder målet med N tidstrin: df['target_lag1'] = df['target'].shift(1) opretter en funktion, der er lig med gårsdagens mål. Rullende statistikker opsummerer den seneste historik: df['rolling_mean_7'] = df['target'].rolling(7).mean() giver det rullende syvdagesgennemsnit. Disse funktioner koder tidsmæssigt momentum og sæsonvariation, som kalenderfunktioner alene ikke kan indfange.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
sales = np.array([100, 120, 95, 130, 110, 145, 160, 155, 170, 180])
df = pd.DataFrame({'date': dates, 'sales': sales})

df['lag_1'] = df['sales'].shift(1)
df['lag_7'] = df['sales'].shift(7)
df['rolling_mean_3'] = df['sales'].rolling(3).mean()
df['rolling_std_3'] = df['sales'].rolling(3).std()
print(df.to_string())

Kombination af datofunktioner i en pipeline

Hvis du vil bruge dato- og funktionsudtræk i en scikit-learn Pipeline uden lækage, skal du oprette en tilpasset transformer ved hjælp af BaseEstimator og TransformerMixin. Det sikrer, at datofunktioner beregnes ensartet og reproducerbart i hver fold under krydsvalidering. Vær ekstra forsigtig med forsinkelses- og rullende funktioner — rullende statistikker, der beregnes på hele datasættet (inklusive fremtidige testdata), lækker oplysninger. Beregn altid forsinkelses- og rullende funktioner kun frem til skæringsdatoen for træningsdataene.

import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin

class DateFeatureExtractor(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        X = X.copy()
        dt = pd.to_datetime(X['date'])
        X['hour'] = dt.dt.hour
        X['dayofweek'] = dt.dt.dayofweek
        X['month'] = dt.dt.month
        X['hour_sin'] = np.sin(2 * np.pi * X['hour'] / 24)
        X['hour_cos'] = np.cos(2 * np.pi * X['hour'] / 24)
        X = X.drop('date', axis=1)
        return X

df = pd.DataFrame({'date': ['2024-06-19 08:00', '2024-06-20 15:30'], 'value': [10, 20]})
print(DateFeatureExtractor().fit_transform(df))

Valg af funktioner baseret på domæneviden

Effektiv funktionsudvikling for datotid kræver forståelse af hvilke tidsmæssige mønstre der er vigtige for dit problem. For efterspørgsel efter samkørselstjenester er klokkeslæt og ugedag afgørende. For detailsalg er ugedag, uge i året, afstand til helligdage og udviklingen fra år til år vigtige. For detektering af netværksindtrængen er tid siden seneste hændelse og burst-rate vigtige. For energiforbrug er interaktioner mellem klokkeslæt, dag og temperatur vigtige. Start altid med at afbilde målet mod hver tidsmæssig komponent for at identificere synlige periodiske mønstre, før du udvikler funktioner.

Håndtering af flere tidszoner

Når dit datasæt spænder over flere tidszoner, skal du altid konvertere tidsstempler til én fælles referencetidszone, før du udtrækker funktioner. Det er standardpraksis at bruge UTC som den kanoniske tidszone. Når funktionerne er udtrukket, kan du anvende lokale tidsforskydninger igen, hvis lokale mønstre er vigtige (f.eks. er klokkeslættet i kundens lokale tid mere forudsigende end UTC-klokkeslættet ved modellering af brugeradfærd). Pandas-metoderne dt.tz_localize() og dt.tz_convert() håndterer tidszonekonvertering på en enkel måde.

import pandas as pd

# Timestamps in mixed timezones
timestamps = ['2024-06-19 08:00:00-05:00',  # US/Chicago
              '2024-06-19 14:00:00+01:00',   # Europe/London
              '2024-06-19 22:00:00+09:00']   # Asia/Tokyo
df = pd.DataFrame({'ts': pd.to_datetime(timestamps, utc=True)})
df['utc_hour'] = df['ts'].dt.hour  # all in UTC after conversion
df['ts_ny'] = df['ts'].dt.tz_convert('America/New_York')
df['ny_hour'] = df['ts_ny'].dt.hour  # local time hour
print(df[['utc_hour', 'ny_hour']])

Hurtigt tjek

Test din forståelse af funktionsudtræk fra dato og tid i denne lektion.

Opsummering af lektionen

I denne lektion har du lært, at rå tidsstempler skal opdeles i meningsfulde komponenter, før de bruges som funktioner, at cykliske funktioner som klokkeslæt og måned kræver sinus/cosinus-kodning for at undgå diskontinuiteter ved grænser, og at forsinkelses- og rullende funktioner koder tidsmæssige mønstre til forudsigelsesopgaver med tidsserier. Næste gang ser vi på funktionsudvælgelse med Variance Threshold og SelectKBest for at frasortere uinformative funktioner.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Udtræk af features fra dato og tid” gratis?

Ja — hele teksten til “Udtræk af features fra dato og tid” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Machine Learning Academy-kurset, skal du opgradere til CoddyKit PRO. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Udtræk af features fra dato og tid”?

De lærende opdeler datetime-kolonner i år, måned, ugedag og time samt cykliske sinus-/cosinusrepræsentationer, der indfanger periodicitet. Du øver dig i Machine Learning Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Machine Learning Academy?

Der kræves ingen tidligere erfaring. Machine Learning Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Udtræk af features fra dato og tid”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Machine Learning Academy-lektion?

Ja. Alle Machine Learning Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Oprettelse af nye features: Logtransformationer, binning og interaktioner
  2. Udtræk af features fra dato og tid
  3. Featureudvælgelse: VarianceThreshold og SelectKBest
  4. Rekursiv featureeliminering med krydsvalidering
← Tilbage til Machine Learning Academy