[PYTHON] Prédiction des données de séries chronologiques par projection simplex

introduction

A propos d'EDM posté dans Article précédent, c'est une histoire d'implémentation de Simplex Projection en Python afin de contester la réflexion des contenus d'apprentissage et de l'extrapolation temporelle. ..

Concernant pyEDM implémenté dans le laboratoire du proposant Sugihara et al., Nous allons l'implémenter car il ne prend pas en charge la prédiction en dehors du DataFrame d'entrée. (Référence).

Pour cette implémentation, nous nous référons au Blog du professeur Ushio de l'Université de Kyoto.

Simplex Projection

0. Préparation des données

À partir de l'exemple de jeu de données pyEDM [Tent Mapping](https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%B3%E3%83%88%E5%86%99%E5% 83% 8F) sont utilisées.

!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

download.png

  1. Time-delay Embedding

Son propre décalage pour la variable $ y_t , comme \ { {y_ {t}, y_ {t- \ tau}, ..., y_ {t- (E-1) \ tau}} $ } Utilisez pour reconstruire la dynamique d'origine. En fait, vous pouvez utiliser d'autres variables associées en plus de la variable cible. Cette fois, par souci de simplicité, définissons une variable et $ E = 2, \ tau = 1 $. En fait, c'est une variable qui dépend grandement de la précision de reconstruction de la dynamique, il est donc nécessaire de l'estimer à partir des données disponibles à l'avance.

Dans le cas de pyEDM, ʻEmbed () est préparé ([doc]([ʻEmbed ()](https://sugiharalab.github.io/EDM_Documentation/edm_functions/#embed))).

Mis en œuvre

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

2. Rechercher le voisin le plus proche

Dans cette implémentation, la dernière valeur des données disponibles est ciblée et prédite après 1 $ de temps.

target_pt = emb_df.iloc[-1,:].values #La dernière valeur qui sert de base à la prédiction

diff = emb_df.values - target_pt #Différence entre tous les points de données disponibles à partir du point de référence
l2_distance = np.linalg.norm(diff, ord=2, axis=1) #Calcul de la norme L2 à partir de la différence
l2_distance = pd.Series(l2_distance, index=emb_df.index, name="l2") #Je veux trier les pandas.Convertir en série

nearest_sort = l2_distance.iloc[:-1].sort_values(ascending=True) #fin(=La dernière valeur qui est la norme)Trier par ordre croissant sauf

print(nearest_sort.head(3))
index    distance
  124    0.003371
  177    0.018171
  163    0.018347
Name: l2

3. Mouvement du voisin le plus proche

Soit $ y_ {t} $ le point de référence pour la prédiction, et \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ } les points de voisinage extraits. Utilisez \ {$ y_ {t_1 + 1}, y_ {t_2 + 1}, y_ {t_3 + 1} $ } pour calculer le point $ y_ {t + 1} $ que vous souhaitez prédire. Puisque l'indice des points de voisinage obtenu dans la section précédente est \ {124, 177, 163 }, Vous utiliserez les points qui correspondent à \ {125, 178, 164 }.

Il n'y a pas de limite au nombre de points voisins qui peuvent être référencés, mais $ E + 1 $ est utilisé pour la dimension incorporée $ E $.

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]]

4. Calcul des points de prédiction

\ {$ Y_ {t_1 + 1}, y_ {t_2 +, selon la distance aux points de référence $ y_ {t} $ et \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ } Calculez les poids \ {$ w_ {t_1 + 1}, w_ {t_2 + 1}, w_ {t_3 + 1} $ } pour 1}, y_ {t_3 + 1} $ }.

nn_distances = nearest_sort.loc[nn_index].values #À partir du point de référence yt1, yt2,Distance à yt3
nn_weights = np.exp(-nn_distances/nn_distances[0]) #Calculer le poids
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

Calculez le point de prédiction $ y_ {t + 1} $ en utilisant les poids. La formule est une moyenne pondérée simple, $ 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]

À propos, la bonne réponse dans ce cas est ground_truth: [0.16928 0.91498] Par conséquent, une valeur assez proche est requise.

Enfin, j'ai tracé l'état du calcul.

Vue d'ensemble TentMap_SP.png

Expansion des points de référence $ y_ {t} $ et \ {$ y_ {t_1}, y_ {t_2}, y_ {t_3} $ } TentMap_SP_targetnn.png

Expansion de la valeur prédite et de la valeur réelle TentMap_SP_forecastnn.png

La fonction entière qui combine 1. à 4. 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) #Dimension intégrée+1
    
        #Obtenir le nom de la variable à partir du DataFrame d'entrée
        input_cols = input_df.columns.tolist()

        #Données DeepCopy pour un traitement récursif ultérieur
        lib_df = input_df.copy()
    
        # forecast_Exécuter de manière récursive la prédiction en 1 étape jusqu'à l'étape spécifiée par tp
        forecast_points = list()
        for pt in range(1, forecast_tp+1):
            #Calcul de la distance du point de référence à chaque point de la bibliothèque
            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")

            #Trier les distances par ordre croissant
            nearest_sort = l2_distance.iloc[:-1].sort_values(ascending=True)

            #Indice des points voisins par rapport au point de référence et t+Index de 1
            nn_index = np.array(nearest_sort.iloc[:knn].index.tolist())
            nn_future_index = nn_index + 1
    
            #Calculer le poids en fonction de la distance des points voisins
            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)
        
            #Calculer la valeur prévue pour chaque dimension incorporée
            forecast_value = list()
            for yt in nn_future_points.values.T:
                forecast_value.append(np.sum((yt * nn_weights) / total_weight))
        
            #Ajouter les résultats de prédiction à la bibliothèque
            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

À la fin

Cette fois, j'ai implémenté Simplex Projection, qui est le plus simple d'EDM, en Python. Les autres méthodes incluent S-Map et Multiview Embedding. Il est également possible d'utiliser différents décalages avec plusieurs variables pour la reconstruction dynamique, ce qui affecte la précision de la prédiction. Dès la prochaine fois, nous contesterons ces contenus.

Recommended Posts

Prédiction des données de séries chronologiques par projection simplex
Prédire les données de séries chronologiques avec un réseau neuronal
Voir les détails des données de séries chronologiques dans Remotte
[Python] Tracer des données de séries chronologiques
Prédiction de séries chronologiques facile avec Prophet
Python: analyse des séries chronologiques: prétraitement des données des séries chronologiques
À propos des données de séries chronologiques et du surentraînement
Différenciation des données de séries chronologiques (discrètes)
Statistiques de mouvement pour la prédiction de séries chronologiques
Analyse des séries chronologiques 3 Prétraitement des données des séries chronologiques
LSTM (1) pour la prédiction de séries chronologiques (pour les débutants)
Comment extraire des fonctionnalités de données de séries chronologiques avec les bases de PySpark
Détection d'anomalies de données chronologiques pour les débutants
Comment gérer les données de séries chronologiques (mise en œuvre)
Lecture des données de séries chronologiques OpenFOAM et des ensembles de données
Puissance des méthodes de prédiction dans l'analyse de données chronologiques Semi-optimisation (SARIMA) [Memo]
Tracer CSV de données de séries temporelles avec une valeur unixtime en Python (matplotlib)
Agrégation pratique de séries chronologiques avec TimeGrouper de pandas
Formater et afficher des données de séries chronologiques avec différentes échelles et unités avec Python ou Matplotlib
Obtenez des données de séries chronologiques de k-db.com avec Python
Résumé de la méthode Kaggle's Kernel [Table time series data]
Décomposition des séries temporelles
Acquisition de données chronologiques (quotidiennes) des cours des actions
Lissage des séries temporelles et des données de forme d'onde 3 méthodes (lissage)
Comment lire les données de séries chronologiques dans PyTorch
Implémentation de la méthode de clustering k-shape pour les données de séries chronologiques [Apprentissage non supervisé avec python Chapitre 13]
"Obtenir des données de séries chronologiques de stock à partir de k-db.com avec Python" Mémo de création d'environnement de programme
Visualisez plus clairement les prédictions de séries chronologiques de Prophet avec Plotly
Quantité d'entités pouvant être extraite des données de séries chronologiques
Détection d'anomalies des données de séries chronologiques par LSTM (Keras)
Prédiction de données chronologiques par AutoML (apprentissage automatique automatique)
[Série chronologique avec plotly] Visualisation dynamique avec plotly [python, cours boursier]
Analyse de données avec python 2
Python: analyse des séries chronologiques
Lecture de données avec TensorFlow
"Analyse des séries chronologiques de mesure des données économiques et financières" Résolution du problème de fin de chapitre avec Python
Question sur la série chronologique Python
Analyse des séries chronologiques RNN_LSTM1
Analyse des séries chronologiques 1 Principes de base
Visualisation des données avec les pandas
Manipulation des données avec les Pandas!
Mélangez les données avec les pandas
Augmentation des données avec openCV
Normariser les données avec Scipy
Analyse de données avec Python
Afficher les séries chronologiques TOPIX
Diagramme de séries chronologiques / Matplotlib
CHARGER DES DONNÉES avec PyMysql
J'ai créé un package pour filtrer les séries chronologiques avec python
Reformatez l'axe des temps du graphique de la série chronologique des pandas avec matplotlib
Bibliothèque tsfresh qui extrait automatiquement les caractéristiques des données de séries chronologiques
Graphique des données de séries chronologiques en Python à l'aide de pandas et matplotlib
Une histoire de regroupement de données de séries chronologiques d'échange