Über EDM in Vorheriger Artikel geht es um die Implementierung von Simplex Projection in Python, um die Reflexion von Lerninhalten und zeitlicher Extrapolation in Frage zu stellen. ..
In Bezug auf pyEDM, das im Labor des Antragstellers Sugihara et al. Implementiert wurde, werden wir es implementieren, da es keine Vorhersage außerhalb des eingegebenen DataFrame unterstützt. (Referenz).
Für diese Implementierung verweisen wir auf Blog von Professor Ushio von der Universität Kyoto.
Simplex Projection
Aus dem pyEDM-Beispieldatensatz [Tent Mapping](https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%B3%E3%83%88%E5%86%99%E5% 83% 8F) Daten werden verwendet.
!pip install pyEDM
import pyEDM
tentmap = pyEDM.sampleData['TentMap']
print(tentmap.head())
Time TentMap
0 1 -0.09920
1 2 -0.60130
2 3 0.79980
3 4 -0.79441
4 5 0.79800
Eine eigene Verzögerung für die Variable $ y_t
Dieses Mal setzen wir der Einfachheit halber eine Variable und $ E = 2, \ tau = 1 $. Tatsächlich handelt es sich um eine Variable, die stark von der Rekonstruktionsgenauigkeit der Dynamik abhängt. Daher ist es erforderlich, sie vorab anhand der vorliegenden Daten abzuschätzen.
Für pyEDM wird Embed ()
bereitgestellt ([doc](Embed ()
).
Implementiert
def time_delay_embedding(objective_df, target_var, E=2, tau=1):
return_df = pd.DataFrame(objective_df[target_var].values,
columns=[target_var+"(t-0)"],
index=objective_df.index)
for i in range(tau, E*tau-1, tau):
colname = target_var + "(t-" + str(i) + ")"
return_df[colname] = objective_df[[target_var]].shift(i)
return return_df.dropna()
emb_df = time_delay_embedding(tentmap, "TentMap", E=2, tau=1)
print(emb_df.head())
TentMap(t-0) TentMap(t-1)
1 -0.60130 -0.09920
2 0.79980 -0.60130
3 -0.79441 0.79980
4 0.79800 -0.79441
5 -0.81954 0.79800
In dieser Implementierung wird der neueste Wert der verfügbaren Daten nach 1 USD angestrebt und vorhergesagt.
target_pt = emb_df.iloc[-1,:].values #Der neueste Wert, der als Grundlage für die Vorhersage dient
diff = emb_df.values - target_pt #Unterschied zwischen allen verfügbaren Datenpunkten vom Referenzpunkt
l2_distance = np.linalg.norm(diff, ord=2, axis=1) #Berechnung der L2-Norm aus der Differenz
l2_distance = pd.Series(l2_distance, index=emb_df.index, name="l2") #Ich möchte so Pandas sortieren.In Serie konvertieren
nearest_sort = l2_distance.iloc[:-1].sort_values(ascending=True) #Ende(=Der neueste Wert, der der Standard ist)In aufsteigender Reihenfolge sortieren, außer
print(nearest_sort.head(3))
index distance
124 0.003371
177 0.018171
163 0.018347
Name: l2
Sei $ y_ {t} $ der Referenzpunkt für die Vorhersage und \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ } die extrahierten Nachbarschaftspunkte. Verwenden Sie \ {$ y_ {t_1 + 1}, y_ {t_2 + 1}, y_ {t_3 + 1} $ }, um den Punkt $ y_ {t + 1} $ zu berechnen, den Sie vorhersagen möchten. Da der im vorherigen Abschnitt erhaltene Index der Nachbarschaftspunkte \ {124, 177, 163 } ist, Sie verwenden die Punkte, die \ {125, 178, 164 } entsprechen.
Es gibt keine Begrenzung für die Anzahl benachbarter Punkte, auf die verwiesen werden kann, aber $ E + 1 $ wird für die eingebettete Dimension $ E $ verwendet.
knn = int(emb_df.shape[1] + 1)
nn_index = np.array(nearest_sort.iloc[:knn,:].index.tolist())
nn_future_index = nn_index + pt
print(nn_index, "-->", nn_future_index)
nn_future_points = lib_df.loc[nn_future_index].values
print(nn_future_points)
[124 177 163] --> [125 178 164]
[[0.16743 0.91591]
[0.15932 0.91998]
[0.1335 0.93295]]
\ {$ Y_ {t_1 + 1}, y_ {t_2 +, abhängig von der Entfernung zu den Referenzpunkten $ y_ {t} $ und \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ } Berechnen Sie die Gewichte \ {$ w_ {t_1 + 1}, w_ {t_2 + 1}, w_ {t_3 + 1} $ } für 1}, y_ {t_3 + 1} $ }.
nn_distances = nearest_sort.loc[nn_index].values #Vom Bezugspunkt yt1, yt2,Entfernung zu yt3
nn_weights = np.exp(-nn_distances/nn_distances[0]) #Gewicht berechnen
total_weight = np.sum(nn_weights)
print("nn_distances")
print("nn_weights")
print("total_weight")
[0.00337083 0.01817143 0.01834696]
[0.36787944 0.00455838 0.00432709]
0.376764916711149
Berechnen Sie den Vorhersagepunkt $ y_ {t + 1} $ anhand der Gewichte. Die Formel ist ein einfacher gewichteter Durchschnitt, $ y_{t+1} = \frac{w_{t_1+1} \times y_{t_1+1} + w_{t_2+1} \times y_{t_2+1} + w_{t_3+1} \times y_{t_3+1}}{w_{total}}$
forecast_point = list()
for yt in nn_future_points.T:
forecast_point.append(np.sum((yt * nn_weights) / total_weight))
print(forecast_point)
[0.16694219792961462, 0.9161549438807427]
Die richtige Antwort ist übrigens in diesem Fall
ground_truth: [0.16928 0.91498]
Daher ist ein Wert erforderlich, der ziemlich nahe liegt.
Schließlich habe ich den Stand der Berechnung aufgezeichnet.
Überblick
Erweiterung der Referenzpunkte $ y_ {t} $ und \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ }
Erweiterung des vorhergesagten Wertes und des wahren Wertes
Die gesamte Funktion, die 1. bis 4 kombiniert. 2.
def forecast_simplex_projection(input_df=None,
forecast_tp=1, knn=None
):
if input_df is None:
raise Exception("Invalid argument: is None: lib_df<pandas.DataFrame> is None")
if knn is None:
knn = int(input_df.shape[1] + 1) #Eingebettete Dimension+1
#Ruft den Variablennamen vom eingegebenen DataFrame ab
input_cols = input_df.columns.tolist()
#DeepCopy-Daten für die spätere rekursive Verarbeitung
lib_df = input_df.copy()
# forecast_Führen Sie rekursiv eine 1-Schritt-Vorhersage bis zu dem durch tp angegebenen Schritt aus
forecast_points = list()
for pt in range(1, forecast_tp+1):
#Entfernungsberechnung vom Referenzpunkt zu jedem Punkt in der Bibliothek
target_pt = lib_df.iloc[-1,:].values
lib_pt = lib_df.values
diff = lib_pt - target_pt
l2_distance = np.linalg.norm(diff, ord=2, axis=1)
l2_distance = pd.Series(l2_distance, index=lib_df.index, name="l2")
#Sortieren Sie die Entfernungen in aufsteigender Reihenfolge
nearest_sort = l2_distance.iloc[:-1].sort_values(ascending=True)
#Index benachbarter Punkte in Bezug auf den Referenzpunkt und t+Index von 1
nn_index = np.array(nearest_sort.iloc[:knn].index.tolist())
nn_future_index = nn_index + 1
#Berechnen Sie das Gewicht anhand des Abstands benachbarter Punkte
nn_distances = nearest_sort.loc[nn_index].values
nn_distances = nn_distances + 1.0e-6
nn_weights = np.exp(-nn_distances/nn_distances[0])
total_weight = np.sum(nn_weights)
#Berechnen Sie den vorhergesagten Wert für jede eingebettete Dimension
forecast_value = list()
for yt in nn_future_points.values.T:
forecast_value.append(np.sum((yt * nn_weights) / total_weight))
#Fügen Sie der Bibliothek Vorhersageergebnisse hinzu
forecast_points.append(forecast_value)
series_forecast = pd.Series(forecast_value, index=input_df.columns)
lib_df = lib_df.append(series_forecast, ignore_index=True)
forecast_points = np.array(forecast_points)
return forecast_points
Dieses Mal habe ich Simplex Projection, das einfachste EDM-Programm, in Python implementiert. Andere Methoden umfassen S-Map und Multiview Embedding. Es ist auch möglich, unterschiedliche Verzögerungen mit mehreren Variablen für die dynamische Rekonstruktion zu verwenden, was sich auf die Vorhersagegenauigkeit auswirkt. Ab dem nächsten Mal werde ich solche Inhalte herausfordern.
Recommended Posts