Zeitreihen für den Klimawandel: Ursprung-Ziel-Nachfrageprognose | von Vitor Cerqueira | Juni 2023

0
28


Im Relaxation dieses Artikels prognostizieren wir die Nachfrage nach Taxifahrern in San Francisco, USA. Wir werden dieses Downside als OD-Circulation-Rely-Aufgabe angehen.

Der vollständige Code, der in diesem Tutorial verwendet wird, ist auf Github verfügbar:

Datensatz

Wir werden einen Datensatz verwenden, der von einer Taxiflotte in San Francisco, Kalifornien, USA, gesammelt wurde. Der Datensatz enthält GPS-Daten von 536 Taxis über einen Zeitraum von 21 Tagen. Insgesamt gibt es 121 Millionen GPS-Spuren, verteilt auf 464045 Fahrten. Sie können die Referenz überprüfen [1] für mehr Particulars.

Beispiel des Datensatzes.

Zu jedem Zeitschritt und für jedes Taxi haben wir Informationen über seine Koordinaten und darüber, ob ein Passagier es besetzt.

Das Downside definieren

Endort einer Stichprobe von Taxifahrten in San Francisco, USA. Bild vom Autor.

Unser Ziel ist es, zu modellieren, wohin Menschen aufgrund ihrer Herkunft ziehen. Die Schätzung der OD-Flusszahl kann in vier Unteraufgaben unterteilt werden:

  1. Zerlegung des räumlichen Gitters
  2. Auswahl von Ursprungs-Ziel-Paaren
  3. Zeitliche Diskretisierung
  4. Modellierung und Prognose

Lassen Sie uns nacheinander auf jedes Downside eingehen.

Zerlegung des räumlichen Gitters

Die räumliche Zerlegung ist ein üblicher Vorverarbeitungsschritt für die Schätzung der OD-Flusszahl. Die Idee besteht darin, die Karte in Rasterzellen aufzuteilen, die einen kleinen Teil der Stadt darstellen. Dann können wir zählen, wie viele Menschen jedes mögliche Paar von Gitterzellen durchqueren.

Zwei Beispielgitterzellen in San Francisco. Bild vom Autor.

In dieser Fallstudie haben wir den Stadtplan wie folgt in 10.000 Rasterzellen aufgeteilt:

import pandas as pd

from src.spatial import SpatialGridDecomposition, prune_coordinates

# studying the info set
trips_df = pd.read_csv('journeys.csv', parse_dates=['time'])

# eradicating outliers from coordinates
trips_df = prune_coordinates(trips_df=trips_df, lhs_thr=0.01, rhs_thr=0.99)

# grid decomposition with 10000 cells
grid = SpatialGridDecomposition(n_cells=10000)
# setting bounding field
grid.set_bounding_box(lat=trips_df.latitude, lon=trips_df.longitude)
# grid decomposition
grid.grid_decomposition()

Im obigen Code entfernen wir abgelegene Standorte. Diese können aufgrund von GPS-Fehlfunktionen auftreten.

Erhalten Sie die beliebtesten Reisen

Nach dem räumlichen Zerlegungsprozess erhalten wir den Ursprung und das Ziel jeder Taxifahrt, wenn sie von einem Passagier besetzt ist.

from src.spatial import ODFlowCounts

# getting origin and vacation spot coordinates for every journey
df_group = trips_df.groupby(['cab', 'cab_trip_id'])
trip_points = df_group.apply(lambda x: ODFlowCounts.get_od_coordinates(x))
trip_points.reset_index(drop=True, inplace=True)

Die Idee besteht darin, den Datensatz so zu rekonstruieren, dass er die folgenden Informationen enthält: Herkunft, Ziel und Herkunftszeitstempel jeder Passagierreise. Diese Daten bilden die Grundlage für unser Ursprung-Ziel-Circulation-Rely-Modell (OD).

Mithilfe dieser Daten können wir zählen, wie viele Fahrten von Zelle A nach Zelle B gehen:

# getting the origin and vacation spot cell centroid
od_pairs = trip_points.apply(lambda x: ODFlowCounts.get_od_centroids(x, grid.centroid_df), axis=1)

Der Einfachheit halber erhalten wir die 50 besten OD-Rasterzellenpaare mit den meisten Fahrten. Die Teilnahme an dieser Teilmenge ist non-compulsory. Allerdings werden OD-Paare mit nur wenigen Fahrten im Laufe der Zeit eine geringe Nachfrage aufweisen, was schwer zu modellieren ist. Außerdem sind Fahrten mit geringer Nachfrage aus Sicht des Flottenmanagements möglicherweise nicht sinnvoll.

flow_count = od_pairs.value_counts().reset_index()
flow_count = flow_count.rename({0: 'rely'}, axis=1)

top_od_pairs = flow_count.head(50)

Zeitliche Diskretisierung

Nachdem wir die OD-Paare mit der höchsten Nachfrage ermittelt haben, diskretisieren wir diese im Zeitverlauf. Dazu wird gezählt, wie viele Fahrten in jeder Stunde für jedes gegebene Prime-Paar stattfinden. Dies kann wie folgt erfolgen:

# getting ready knowledge
trip_points = pd.concat([trip_points, od_pairs], axis=1)
trip_points = trip_points.sort_values('time_start')
trip_points.reset_index(drop=True, inplace=True)

# getting origin-destination cells for every journey, and origin begin time
trip_starts = []
for i, pair in top_od_pairs.iterrows():

origin_match = trip_points['origin'] == pair['origin']
dest_match = trip_points['destination'] == pair['destination']

od_trip_df = trip_points.loc[origin_match & dest_match, :]
od_trip_df.loc[:, 'pair'] = i

trip_starts.append(od_trip_df[['time_start', 'time_end', 'pair']])

trip_starts_df = pd.concat(trip_starts, axis=0).reset_index(drop=True)

# extra knowledge processing
od_count_series = {}
for pair, knowledge in trip_starts_df.groupby('pair'):

new_index = pd.date_range(
begin=knowledge.time_start.values[0],
finish=knowledge.time_end.values[-1],
freq='H',
tz='UTC'
)

od_trip_counts = pd.Collection(0, index=new_index)
for _, r in knowledge.iterrows():
dt = r['time_start'] - new_index
dt_secs = dt.total_seconds()

valid_idx = np.the place(dt_secs >= 0)[0]
idx = valid_idx[dt_secs[valid_idx].argmin()]

od_trip_counts[new_index[idx]] += 1

od_count_series[pair] = od_trip_counts.resample('H').imply()

od_df = pd.DataFrame(od_count_series)

Dies führt zu einer Reihe von Zeitreihen, eine für jedes Prime-OD-Paar. Hier ist das Zeitreihendiagramm für vier Beispielpaare:

Zeitreihe der Flusszählungen für vier beispielhafte Ursprungs-Ziel-Paare. Bild vom Autor.

Die Zeitreihen zeigen eine tägliche Saisonalität, die hauptsächlich durch die Hauptverkehrszeiten bedingt ist.

Prognose

Die aus der zeitlichen Diskretisierung resultierende Menge an Zeitreihen kann für die Prognose verwendet werden. Wir können ein Modell erstellen, um vorherzusagen, wie viele Passagiere die Reise im Verhältnis zu einem bestimmten OD-Paar machen möchten.

So kann dies für ein Beispiel-OD-Paar durchgeführt werden:

from pmdarima.arima import auto_arima

# getting the primary OD pair as instance
collection = od_df[0].dropna()

# becoming an ARIMA mannequin
mannequin = auto_arima(y=collection, m=24)

Oben haben wir ein Prognosemodell basierend auf ARIMA erstellt. Das Modell prognostiziert die Passagiernachfrage in der nächsten Stunde unter Berücksichtigung der jüngsten Nachfrage. Der Einfachheit halber verwenden wir eine ARIMA-Methode, aber auch andere Ansätze wie z tiefes Lernen kann verwendet werden.



Source link

HINTERLASSEN SIE EINE ANTWORT

Please enter your comment!
Please enter your name here