Analyse des Séries Temporelles Financières
Analyse des Séries Temporelles Financières
February 3, 2025
1
1.4 4. Prétraitement des Données
• Convertir la colonne Séance en DatetimeIndex pour l’analyse des séries temporelles.
• Supprimer les colonnes non pertinentes : Instrument, Ticker.
• Gérer les données manquantes ou incohérentes :
– Imputation ou suppression des lignes avec des valeurs manquantes.
• Renommer les colonnes pour une meilleure clarté (par exemple, Dernier Cours → Close).
2
1.10 10. Visualisation
• Créer des graphiques pour communiquer efficacement les résultats :
– Graphique en ligne pour les tendances des prix (Close, Cours ajusté).
– Volatilité et moyennes mobiles dans le temps.
– Histogramme des rendements quotidiens.
– Diagrammes de dispersion pour visualiser les corrélations (par exemple, volume vs prix).
3
import seaborn as sns
import warnings
[Link]("ignore")
Analyse de séries temporelles - Modèle Auto-régressif Mobile (ARIMA) Données Explorer les don-
nées collectées sur Bourse Casablanca. Période : Janvier 2022 à 2025. Environ 3 anées Source du
DataFrame Python : Bourse Casablanca avec les variables/colonnes suivantes : Date : Représente
la date des données financières. Open : Indique le prix d’ouverture de l’action. High : Désigne le
prix le plus élevé atteint pendant la période de négociation. Low : Représente le prix le plus bas
atteint pendant la période de négociation. Close : Indique le prix de clôture de l’action. Adj Close
: Reflète le prix de clôture ajusté, tenant compte des actions corporatives. Volume : Représente le
volume de négociation (nombre d’actions échangées) à la date donnée
file_path = '/content/drive/MyDrive/FinancialTS/[Link]'
df = pd.read_excel(file_path)
# Drop the 'Instrument' and 'Ticker' columns
[Link](columns=['Instrument', 'Ticker'], inplace=True)
save_df = df
data = [Link]()
# Display the first few rows to confirm changes
print([Link]())
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[9], line 1
----> 1 from [Link] import drive
2 [Link]('/content/drive')
4
4 file_path = '/content/drive/MyDrive/FinancialTS/[Link]'
file_path = r'C:\Users\user\OneDrive\Documents\C\[Link]'
5
Contracts Market Capitalization Adj Close
0 240 1.605654e+10 1134.0
1 185 1.605654e+10 1134.0
2 125 1.619813e+10 1144.0
3 188 1.628309e+10 1150.0
4 199 1.628309e+10 1150.0
La moyenne des prix ajustés de clôture est d’environ 605.53 Dh , indiquant un niveau de prix
moyen. Cependant, l’écart-type élevé de 277.31 Dh suggère une variabilité importante, indiquant
des fluctuations notables autour de la moyenne. Le prix de clôture minimum dans le jeu de données
est d’environ 270.5 Dh, et le maximum est de 1163 Dh, reflétant la plage observée. Ces informations
sont cruciales pour les investisseurs, soulignant à la fois la performance moyenne et le potentiel de
mouvements de prix substantiels.
6
[13]: print(f"Downloaded {len(df)} rows of data.")
[Link]()
[13]: Date Open Close High Low Shares Traded Trading Volume \
0 22/01/2025 1122.0 1134.0 1134.0 1095.0 11790.0 13099580.0
1 21/01/2025 1140.0 1134.0 1144.0 1125.0 14523.0 16513287.0
2 20/01/2025 1151.0 1144.0 1166.0 1143.0 5012.0 5757666.0
3 17/01/2025 1165.0 1150.0 1165.0 1150.0 18533.0 21403345.0
4 16/01/2025 1164.0 1150.0 1170.0 1150.0 6658.0 7703536.0
[14]: Open 0
Close 0
High 0
Low 0
Shares Traded 0
Trading Volume 0
Contracts 0
Market Capitalization 0
Adj Close 0
dtype: int64
7
min_periods=1
):
"""
Args:
df ([Link]): Input DataFrame with DatetimeIndex
target_cols (str/list): Column name(s) to process (e.g., 'Open' or␣
,→['Open', 'Close'])
Returns:
[Link]: DataFrame with zeros replaced by moving averages
"""
# Validate index type
if not isinstance([Link], [Link]):
raise ValueError("Index must be a DatetimeIndex")
# Identify zeros
zero_mask = df[col] == 0
return df
8
[17]: df_cleaned = fill_zero_with_ma(
df,
target_cols=['Open', 'High', 'Low', 'Close'], # List of columns
window='7D' # Optional: 7-day moving average
)
[18]: df_cleaned.head()
Methode 6σ
[20]: rtn
Date
2025-01-22 NaN
2025-01-21 0.000000
2025-01-20 0.008818
2025-01-17 0.005245
9
2025-01-16 0.000000
std
Date
2025-01-10 0.008967
2025-01-09 0.011377
10
2025-01-08 0.011199
2025-01-07 0.017562
2025-01-06 0.017562
[23]: N_SIGMAS = 3
df2["upper"] = df2["mean"] + N_SIGMAS * df2["std"]
df2["lower"] = df2["mean"] - N_SIGMAS * df2["std"]
#Mask
df2["outlier"] = (
(df2["rtn"] > df2["upper"]) | (df2["rtn"] < df2["lower"])
)
output_22_0.png
11
[26]: # Valeurs manquantes
nouvel_indicateur_valeurs_manquantes = [Link]().astype(int)
12
[27]: # De nouvelle valeurs puevent etre crées par exemple
df_cleaned["simple_rtn"] = df_cleaned["Adj Close"].pct_change()
df_cleaned["log_rtn"] = [Link](df_cleaned["Adj Close"]/df_cleaned["Adj Close"].
,→shift(1))
13
df = df_cleaned.copy()
df_rv = (
[Link]([Link](freq="ME"))
.apply(realized_volatility)
.rename(columns={"log_rtn": "rv"})
)
df_rv.rv = df_rv["rv"] * [Link](12)
fig, ax = [Link](2, 1, sharex=True)
ax[0].plot(df)
ax[0].set_title("Rendements logarithmiques d'AKDITAL (2022-2025)")
ax[1].plot(df_rv)
ax[1].set_title("Volatilité annualisée")
[Link]()
output_26_0.png
1.13.1 Remarque :
Nous pouvons constater que les pics de la volatilité réalisée coïncident avec certains rende
output_28_0.png
hampel_detector = HampelFilter(window_length=10,
14
return_bool=True)
df["outlier"] = hampel_detector.fit_transform(df["Adj Close"])
df["rtn"] = df["Adj Close"].pct_change()
output_30_1.png
df2["outlier_rtn"] = hampel_detector.fit_transform(df2["rtn"])
fig, ax = [Link]()
df2[["rtn"]].plot(ax=ax)
[Link]([Link][df2["outlier_rtn"]].index,
[Link][df2["outlier_rtn"], "rtn"],
color="black", label="outlier")
ax.set_title("AKDITAL's stock returns")
[Link](loc="center left", bbox_to_anchor=(1, 0.5))
[Link]()
output_31_0.png
15
1.13.2 Exploring Financial Time Series Data
output_33_0.png
16
ax_copy.set_ylabel('Price')
ax_copy.patch.set_edgecolor('black')
[Link]('fivethirtyeight')
[Link](prop={'size': 12})
[Link]('fivethirtyeight')
# ejustement de la disposition des sous graphiques
fig_copy.tight_layout(pad=3.0)
# affichage de la figure
[Link]()
plot_data(df)
17
[35]: def dessiner_graphique_personnalise(df, x_col, y_col=None, titre="", xlabel="",␣
,→ylabel="", hue_col=None, palette="viridis", style="whitegrid", figsize=(12,␣
,→6)):
# Affichage du graphique
[Link]()
Initial Exploration:
<class '[Link]'>
DatetimeIndex: 522 entries, 2022-12-14 to 2025-01-22
Data columns (total 13 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Open 522 non-null float64
1 Close 522 non-null float64
2 High 522 non-null float64
3 Low 522 non-null float64
4 Shares Traded 522 non-null float64
5 Trading Volume 522 non-null float64
6 Contracts 522 non-null int64
18
7 Market Capitalization 522 non-null float64
8 Adj Close 522 non-null float64
9 simple_rtn 521 non-null float64
10 log_rtn 521 non-null float64
11 outlier 522 non-null bool
12 rtn 521 non-null float64
dtypes: bool(1), float64(11), int64(1)
memory usage: 53.5 KB
None
Summary Statistics:
Open Close High Low Shares Traded \
count 515.000000 515.000000 515.000000 515.000000 515.00000
mean 597.681748 598.176019 603.930777 592.317961 15000.04466
std 272.539860 271.844992 275.748980 269.253440 19403.64617
min 270.000000 270.500000 275.000000 270.000000 7.00000
25% 320.000000 321.025000 323.475000 318.525000 3026.00000
50% 505.100000 505.000000 509.000000 499.000000 7779.00000
75% 756.500000 770.500000 775.500000 749.050000 18732.00000
max 1181.000000 1161.000000 1199.000000 1161.000000 166323.00000
19
dessiner_graphique_personnalise(df, x_col='log_rtn', y_col='Trading Volume',␣
,→titre='Nuage de points', xlabel='Rendements logarithmiques', ylabel='Volume',␣
,→palette='Set2')
output_37_0.png
output_37_1.png
20
[39]: (
interval_df[["Adj Close", "simple_rtn"]]
.plot(subplots=True, sharex=True, # sharex=True : pour garantir que les␣
,→sous-graphes partagent le même axe x..
output_40_0.png
21
[41]: corr_matrix = df[['Adj Close', 'Trading Volume', 'simple_rtn', 'Open', 'Trading␣
,→Volume', 'Contracts', 'Market Capitalization']].corr(method='pearson')
22
title="AKDITAL's stock prices in ",
yaxis_title="Prix (Dh)"
)
[Link]()
1.14 Introduction :
La modélisation des séries chronologiques financières est essentielle pour analyser l’évolution des
prix des actions de la Banque CIH et pour effectuer des prévisions. Chaque étape dans ce processus
permet d’améliorer la qualité des prévisions et de mieux comprendre les dynamiques du marché.
1.14.2 Modélisation des séries chronologiques avec des méthodes de lissage exponen-
tiel
1. Objectif: Modéliser la tendance et la saisonnalité dans la série chronologique.
2. Méthode: Utilisation de méthodes de lissage exponentiel.
3. Formule: Prédiction = Tendance + Saisonnalité
1.14.3 Modélisation des séries chronologiques avec des modèles de classe ARIMA
1. Objectif: Modéliser une série temporelle stationnaire.
2. Méthode: Utilisation de modèles ARIMA(p, d, q).
3. Formule: Y(t) = C + 1 * Y(t-1) + . . . + p * Y(t-p) + ε(t) - θ1 * ε(t-1) - . . . - θq * ε(t-q)
23
3. Formule: Sélection automatique des paramètres p, d, q pour minimiser un critère
d’ajustement.
[43]: WINDOW_SIZE = 30
output_44_2.png
[44]: df = df_cleaned
df = [Link]([Link])
[Link]
24
df['Adj Close'] = df['Adj Close'].interpolate(method='linear')
output_47_1.png
25
1.14.5 Test de stationnarité dans les séries chronologiques
def adf_test(x):
return results
26
[49]: x = df2["Adj Close"]
adf_test(x= x)
Statistique de Test (0.888898) : Cette valeur est la statistique de test calculée pendant le test ADF.
Plus elle est négative, plus les preuves contre l’hypothèse nulle (H0) sont fortes. Cependant, ici, la
statistique n’est pas inférieure aux valeurs critiques à des niveaux de significativité usuels.
Valeur p (0.992944) : La probabilité d’observer cette statistique de test si l’hypothèse nulle est vraie.
Une valeur p supérieure à 0.05 indique qu’il n’y a pas assez de preuves pour rejeter H0.
Nombre de Retards Utilisés (2) : Ce chiffre représente le nombre de retards pris en compte pour
ajuster le modèle dans le test ADF, souvent déterminé par des critères comme AIC ou BIC.
Nombre d’Observations Utilisées (512) : Cela correspond au nombre total d’observations incluses
dans le calcul après avoir pris en compte les retards.
Valeurs Critiques : Ce sont des seuils de comparaison pour la statistique de test afin d’évaluer la
stationnarité à différents niveaux de significativité statistique.
• Valeur Critique (1%) : -3.443187
• Valeur Critique (5%) : -2.867202
• Valeur Critique (10%) : -2.569785
Interprétation : - Hypothèse Nulle (H0) : La série chronologique n’est pas stationnaire. - Hypothèse
Alternative (H1) : La série chronologique est stationnaire.
Conclusion : Avec une valeur p de 0.992944, qui est supérieure au seuil typique de 0.05, il n’y a pas
suffisamment de preuves pour rejeter l’hypothèse nulle.
Par conséquent, selon le test ADF, la série chronologique peut être considérée comme non station-
naire.
def adf_test(x):
indices = ["Test Statistic", "p-value",
"# of Lags Used", "# of Observations Used"]
27
adf_test = adfuller(x, autolag="AIC")
results = [Link](adf_test[0:4], index=indices)
return results
# Call adf_test and assign the result to a variable
x = df2["Adj Close"]
adf_results = adf_test(x=x) # Call the function and store the result
[53]: N_LAGS = 40
SIGNIFICANCE_LEVEL = 0.05
28
title='Autocorrelation (ACF)')
plt.tight_layout()
[Link]()
output_56_0.png
# Log-transformed price
df["Adj Close_log"] = [Link](df["Adj Close"])
# Plotting
df[selected_columns].plot(title="AKDITAL Adjusted Close Price (logged + rolling␣
,→mean/std)", subplots=False, color= colors)
[Link]()
29
[55]: from [Link] import ndiffs, nsdiffs
print(f"Suggested # of differences (ADF): {ndiffs(df['Adj Close'], test='adf')}")
print(f"Suggested # of differences (KPSS): {ndiffs(df['Adj Close'],␣
,→test='kpss')}")
1.15 Conclusion
Dans l'interprétation de ces résultats, l'hypothèse nulle (H0) stipule que la série n'est pas st
2 ARIMA
[57]: df = df_cleaned
[Link] , [Link]
TEST_LENGTH = 6
df_train = [Link][:-TEST_LENGTH]
df_test = [Link][-TEST_LENGTH:]
[58]: [Link]()
30
Contracts Market Capitalization Adj Close simple_rtn log_rtn
Date
2022-12-15 190 3.838001e+09 303.0 0.003311 0.003306
2022-12-16 315 3.800001e+09 300.0 -0.009901 -0.009950
2022-12-19 313 3.817734e+09 301.4 0.004667 0.004656
2022-12-20 210 3.800001e+09 300.0 -0.004645 -0.004656
2022-12-21 145 3.673334e+09 290.0 -0.033333 -0.033902
... ... ... ... ... ...
2025-01-16 199 1.628309e+10 1150.0 -0.011178 -0.011241
2025-01-17 188 1.628309e+10 1150.0 0.000000 0.000000
2025-01-20 125 1.619813e+10 1144.0 -0.005217 -0.005231
2025-01-21 185 1.605654e+10 1134.0 -0.008741 -0.008780
2025-01-22 240 1.605654e+10 1134.0 0.000000 0.000000
output_65_1.png
31
Dep. Variable: Adj_Close_log No. Observations: 516
Model: ARIMA(1, 1, 1) Log Likelihood 1426.336
Date: Mon, 03 Feb 2025 AIC -2846.672
Time: 20:34:02 BIC -2833.939
Sample: 0 HQIC -2841.682
- 516
Covariance Type: opg
coef std err z P> |z| [0.025 0.975]
ar.L1 0.2228 0.248 0.899 0.369 -0.263 0.709
ma.L1 -0.0542 0.256 -0.212 0.832 -0.556 0.448
sigma2 0.0002 7.93e-06 28.980 0.000 0.000 0.000
Ljung-Box (L1) (Q): 0.23 Jarque-Bera (JB): 581.82
Prob(Q): 0.63 Prob(JB): 0.00
Heteroskedasticity (H): 1.74 Skew: 0.38
Prob(H) (two-sided): 0.00 Kurtosis: 8.15
Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).
Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).
32
[63]: df["pred_111_log"] = [Link]([arima_111.fittedvalues, arima_111.
,→forecast(TEST_LENGTH)])
df["pred_111"] = [Link](df["pred_111_log"])
df["pred_212_log"] = [Link]([arima_212.fittedvalues, arima_212.
,→forecast(TEST_LENGTH)])
df["pred_212"] = [Link](df["pred_212_log"])
df
33
2025-01-21 NaN NaN NaN NaN
2025-01-22 NaN NaN NaN NaN
[64]: arima_111.forecast(TEST_LENGTH)
[65]: # df = [Link]([Link])
# Previous code
df["pred_111_log"] = [Link]([arima_111.fittedvalues, arima_111.
,→predict(start=len(df_train), end=len(df_train) + TEST_LENGTH -1,␣
34
2022-12-20 210 3.800001e+09 300.0 -0.004645 -0.004656
... ... ... ... ... ...
2025-01-16 199 1.628309e+10 1150.0 -0.011178 -0.011241
2025-01-17 188 1.628309e+10 1150.0 0.000000 0.000000
2025-01-20 125 1.619813e+10 1144.0 -0.005217 -0.005231
2025-01-21 185 1.605654e+10 1134.0 -0.008741 -0.008780
2025-01-22 240 1.605654e+10 1134.0 0.000000 0.000000
35
2023-01-09 270.50 271.629203 271.650708
2023-01-10 270.60 270.194770 270.165497
2023-01-12 271.00 270.600303 270.586669
output_72_0.png
cpu
3 APPROACH/MAJOR INNOVATIONS
We have used several approaches and experimented on them in order to find the best approach
and architecture to produce accurate results. ### 1) Implementing a simple LSTM: The initial
approach involved implementing a simple model of LSTM on the time series data which showed
decent fitting of data but failed near some of the troughs and was not very smooth
36
h0 = Variable([Link]([Link], [Link](0), self.hidden_size)).
to(device)
,→
def train_test_split(X,Y,percent):
per = percent/100
sz = len(X)
xtrain = [Link](X[:int(sz*per)])
ytrain = [Link](Y[:int(sz*per)])
xtest = [Link](X[int(sz*per):])
ytest = [Link](Y[int(sz*per):])
return xtrain,ytrain,xtest,ytest
class DataPrep(Dataset):
def __init__(self, inputs, targets):
[Link] = inputs
[Link] = targets
def __len__(self):
return len([Link])
[71]: df = df_cleaned.copy()
scaler = StandardScaler()
values = scaler.fit_transform(df['Close'].[Link](-1,1))
[72]: seq_len = 40
data_inp,data_tar = prepare_dataset(values,seq_len)
xtrain,ytrain,xtest,ytest = train_test_split(data_inp,data_tar,80)
37
[73]: traindata = DataPrep(xtrain,ytrain)
testdata = DataPrep(xtest,ytest)
batch_size = 32
trainset = DataLoader(traindata,batch_size = batch_size,shuffle = True)
testset = DataLoader(testdata,batch_size = batch_size,shuffle = True)
for xbatch,ybatch in trainset:
print([Link],[Link])
break
[111]: train_losses = []
test_losses = []
input_sz = 1
hidden_sz = 200
output_sz = 1
layers = 2
model = LstmNet(input_sz,hidden_sz,layers,output_sz).to(device)
criterion = [Link]()
optimizer = [Link]([Link](), lr=0.00001)
for epoch in range(500):
batch_loss = 0
# correct = 0
for xbatch,ybatch in trainset:
xbatch,ybatch = [Link](device),[Link](device)
out = model(xbatch)
# print([Link],[Link])
loss = criterion(out, [Link](1))
[Link]()
[Link]()
batch_loss += [Link]()
# break
train_loss = batch_loss/len(trainset)
batch_loss = 0
with torch.no_grad():
for xbatch,ybatch in testset:
xbatch,ybatch = [Link](device),[Link](device)
out = model(xbatch)
loss = criterion(out, [Link](1))
batch_loss += [Link]()
test_loss = batch_loss/len(testset)
train_losses.append(train_loss)
test_losses.append(test_loss)
if(epoch%10==9):
print("Epoch: ", epoch+1, "|", "Train Loss : ", "{:.6f}".
,→format(train_loss), "|", "Test Loss : ", "{:.6f}".format(test_loss))
38
Cell In[111], line 36
ˆ
SyntaxError: incomplete input
pred = [Link]((train_pred,test_pred))
# pred = scaler.inverse_transform(pred)
actual = [Link]((train_actual,test_actual)).squeeze()
# actual = scaler.inverse_transform(pred)
print([Link])
print([Link])
(481,)
(481,)
datas = [trace1,trace2]
[Link]()
output_82_0.png
39
3.0.1 2) GADF Image Representations and CNN-based Prediction:
The approach involved generating GADF images from the time series data and training a CNN model
to predict the ‘close price’ of the stock directly. However, this method did not yield satisfactory
results, as CNNs alone were unable to capture the sequential properties of time series data effectively.
for i in range(len(values[0])-data_size-33):
gaf = GramianAngularField(image_size=image_size, method=method,␣
,→sample_range=sample_range)
gadf_image = gaf.fit_transform(values[:,i:i+32])
[Link](gadf_image)
[Link](values[:,i+32+1])
images = [Link](images).astype(np.float32)
labels = [Link](labels)
# scaler= MinMaxScaler()
scaler = StandardScaler()
# labels = scaler.fit_transform(labels).reshape(-1,).astype(np.float32)
fig, ax = [Link](figsize =(10, 7))
[Link](labels, bins = 20)
[Link]()
output_84_0.png
[78]: [Link](images[40].transpose(1,2,0),cmap='hot')
40
output_85_1.png
num_samples = len(dataset)
num_test_samples = int(test_size * num_samples)
num_train_samples = num_samples - num_test_samples
indices = [Link](num_samples)
train_indices = indices[:num_train_samples]
#print(train_indices)
test_indices = indices[num_train_samples:]
train_sampler = [Link](train_indices)
test_sampler = [Link](test_indices)
train_loader = [Link](dataset, batch_size=batch_size,␣
,→sampler=train_sampler)
def prepare_dataset(input,labels,length):
x = []
y = []
for i in range(len(input)-length-1):
[Link](input[i:i+length])
[Link](labels[i+length])
return [Link](x),[Link](y)
41
def prepare_dataset_fromone(input,length):
x = []
y = []
for i in range(len(input)-length-1):
[Link](input[i:i+length])
[Link](input[i+length])
return [Link](x),[Link](y)
for i in range(len(values[0])-data_size-1):
gaf = GramianAngularField(image_size=image_size, method=method,␣
,→sample_range=sample_range)
gadf_image = gaf.fit_transform(values[:,i:i+data_size])
[Link](gadf_image)
[Link](values[:,i+data_size+1])
images = [Link](images).astype(np.float32)
labels = [Link](labels)
scaler = StandardScaler()
labels = scaler.fit_transform(labels).reshape(-1,).astype(np.float32)
dataset = DataPrep(images,labels)
train_loader,test_loader = split_prepare_data(dataset)
42
def forward(self, x):
x = [Link]()(self.conv1(x))
x = [Link](x)
# x = [Link](-1, 32 * 8 * 8)
x = [Link](x)
x = self.fc3(x)
return x
test_loss = 0.0
with torch.no_grad():
for xbatch,ybatch in test_loader:
xbatch, ybatch = [Link](device),[Link](device)
# Check if batch size is 1 and if so, skip batch normalization
if [Link][0] == 1:
# You can skip batch normalization by either:
# 1. Setting the ResNet model to eval mode:
[Link]()
# 2. (More complex) Replacing BatchNorm layers with Identity␣
,→layers.
# If you set the model to eval mode, set it back to train mode
if [Link][0] == 1:
[Link]()
loss = criterion(output,ybatch)
43
test_loss += [Link]()
test_loss /= len(test_loader)
pred = model([Link](images).to(device)).cpu().[Link]().squeeze()
44
Epoch 14/50 - Training Loss: 0.9512 - Testing Loss: 1.1930
0%| | 0/13 [00:00<?, ?it/s]
Epoch 15/50 - Training Loss: 1.1568 - Testing Loss: 1.7327
0%| | 0/13 [00:00<?, ?it/s]
Epoch 16/50 - Training Loss: 0.9861 - Testing Loss: 1.0624
0%| | 0/13 [00:00<?, ?it/s]
Epoch 17/50 - Training Loss: 0.7993 - Testing Loss: 1.5425
0%| | 0/13 [00:00<?, ?it/s]
Epoch 18/50 - Training Loss: 0.8442 - Testing Loss: 1.3914
0%| | 0/13 [00:00<?, ?it/s]
Epoch 19/50 - Training Loss: 0.8000 - Testing Loss: 1.2805
0%| | 0/13 [00:00<?, ?it/s]
Epoch 20/50 - Training Loss: 0.8243 - Testing Loss: 1.6544
0%| | 0/13 [00:00<?, ?it/s]
Epoch 21/50 - Training Loss: 0.8905 - Testing Loss: 1.2739
0%| | 0/13 [00:00<?, ?it/s]
Epoch 22/50 - Training Loss: 0.8291 - Testing Loss: 1.8790
0%| | 0/13 [00:00<?, ?it/s]
Epoch 23/50 - Training Loss: 0.8030 - Testing Loss: 1.0327
0%| | 0/13 [00:00<?, ?it/s]
Epoch 24/50 - Training Loss: 0.8086 - Testing Loss: 1.1489
0%| | 0/13 [00:00<?, ?it/s]
Epoch 25/50 - Training Loss: 0.7938 - Testing Loss: 1.3265
0%| | 0/13 [00:00<?, ?it/s]
Epoch 26/50 - Training Loss: 0.8582 - Testing Loss: 1.0780
0%| | 0/13 [00:00<?, ?it/s]
Epoch 27/50 - Training Loss: 0.8349 - Testing Loss: 0.9739
0%| | 0/13 [00:00<?, ?it/s]
Epoch 28/50 - Training Loss: 0.7596 - Testing Loss: 1.1610
0%| | 0/13 [00:00<?, ?it/s]
Epoch 29/50 - Training Loss: 0.7884 - Testing Loss: 0.8929
0%| | 0/13 [00:00<?, ?it/s]
45
Epoch 30/50 - Training Loss: 0.7301 - Testing Loss: 1.0581
0%| | 0/13 [00:00<?, ?it/s]
Epoch 31/50 - Training Loss: 0.7616 - Testing Loss: 1.2029
0%| | 0/13 [00:00<?, ?it/s]
Epoch 32/50 - Training Loss: 0.7506 - Testing Loss: 1.1102
0%| | 0/13 [00:00<?, ?it/s]
Epoch 33/50 - Training Loss: 0.7777 - Testing Loss: 1.3477
0%| | 0/13 [00:00<?, ?it/s]
Epoch 34/50 - Training Loss: 0.7132 - Testing Loss: 1.6120
0%| | 0/13 [00:00<?, ?it/s]
Epoch 35/50 - Training Loss: 0.7149 - Testing Loss: 1.3423
0%| | 0/13 [00:00<?, ?it/s]
Epoch 36/50 - Training Loss: 0.7707 - Testing Loss: 1.1672
0%| | 0/13 [00:00<?, ?it/s]
Epoch 37/50 - Training Loss: 0.7074 - Testing Loss: 1.0439
0%| | 0/13 [00:00<?, ?it/s]
Epoch 38/50 - Training Loss: 0.8274 - Testing Loss: 1.0528
0%| | 0/13 [00:00<?, ?it/s]
Epoch 39/50 - Training Loss: 0.7319 - Testing Loss: 1.1594
0%| | 0/13 [00:00<?, ?it/s]
Epoch 40/50 - Training Loss: 0.7606 - Testing Loss: 1.2484
0%| | 0/13 [00:00<?, ?it/s]
Epoch 41/50 - Training Loss: 0.7745 - Testing Loss: 1.3121
0%| | 0/13 [00:00<?, ?it/s]
Epoch 42/50 - Training Loss: 0.7108 - Testing Loss: 1.6118
0%| | 0/13 [00:00<?, ?it/s]
Epoch 43/50 - Training Loss: 0.7283 - Testing Loss: 1.2961
0%| | 0/13 [00:00<?, ?it/s]
Epoch 44/50 - Training Loss: 0.7126 - Testing Loss: 0.8583
0%| | 0/13 [00:00<?, ?it/s]
Epoch 45/50 - Training Loss: 0.6765 - Testing Loss: 1.1658
0%| | 0/13 [00:00<?, ?it/s]
46
Epoch 46/50 - Training Loss: 0.7275 - Testing Loss: 0.8611
0%| | 0/13 [00:00<?, ?it/s]
Epoch 47/50 - Training Loss: 0.7853 - Testing Loss: 0.9544
0%| | 0/13 [00:00<?, ?it/s]
Epoch 48/50 - Training Loss: 0.7740 - Testing Loss: 1.1624
0%| | 0/13 [00:00<?, ?it/s]
Epoch 49/50 - Training Loss: 0.7244 - Testing Loss: 1.3710
0%| | 0/13 [00:00<?, ?it/s]
Epoch 50/50 - Training Loss: 0.6863 - Testing Loss: 1.1623
(489,)
(489,)
plot_data = [trace1,trace2]
[Link]()
not yield satisfactory results, as CNNs alone were unable to capture the sequential properties of time
series data effectively
47
image_size = 32
data_size = 32
# method = 'difference'
method = 'summation'
sample_range = (0, 1)
for i in range(len(values[0])-data_size-1):
gaf = GramianAngularField(image_size=image_size, method=method,␣
,→sample_range=sample_range)
gadf_image = gaf.fit_transform(values[:,i:i+data_size])
[Link](gadf_image)
[Link](values[:,i+data_size+1])
images = [Link](images).astype(np.float32).reshape(-1,image_size*image_size)
output_95_1.png
[87]: print([Link],[Link])
print(dataset[0][0].shape)
(40, 1024)
48
[91]: class ImageLSTMNet([Link]):
def __init__(self,input_size,hidden_size,layers,output_size):
super(ImageLSTMNet,self).__init__()
[Link] = layers
self.hidden_size = hidden_size
[Link] = [Link](input_size=input_size, hidden_size=hidden_size,␣
,→num_layers=layers, batch_first=True)
def forward(self,x):
# print([Link])
h0 = Variable([Link]([Link], [Link](0), self.hidden_size)).
,→to(device)
[92]: train_losses = []
test_losses = []
input_sz = 32*32
hidden_sz = 2048
output_sz = 1
layers = 1
LSTMmodel = ImageLSTMNet(input_sz,hidden_sz,layers,output_sz).to(device)
criterion = [Link]()
optimizer = [Link]([Link](), lr=0.0001)
num_epochs = 50
for epoch in range(num_epochs):
train_loss = 0.0
pbar = tqdm(total = len(train_loader))
for xbatch,ybatch in train_loader:
optimizer.zero_grad()
xbatch, ybatch = [Link](device),[Link](device)
output = LSTMmodel(xbatch)
loss = criterion(output,ybatch)
[Link]()
[Link]()
train_loss += [Link]()
[Link](1)
train_loss /= len(train_loader)
[Link]()
49
test_loss = 0.0
with torch.no_grad():
for xbatch,ybatch in test_loader:
xbatch, ybatch = [Link](device),[Link](device)
output = LSTMmodel(xbatch)
loss = criterion(output,ybatch)
test_loss += [Link]()
test_loss /= len(test_loader)
pred = LSTMmodel([Link](seq_images).to(device)).cpu().[Link]().
,→squeeze()
50
Epoch 11/50 - Training Loss: 0.0832 - Testing Loss: 0.0641
0%| | 0/12 [00:00<?, ?it/s]
Epoch 12/50 - Training Loss: 0.0501 - Testing Loss: 0.0591
0%| | 0/12 [00:00<?, ?it/s]
Epoch 13/50 - Training Loss: 0.0373 - Testing Loss: 0.0416
0%| | 0/12 [00:00<?, ?it/s]
Epoch 14/50 - Training Loss: 0.0220 - Testing Loss: 0.0424
0%| | 0/12 [00:00<?, ?it/s]
Epoch 15/50 - Training Loss: 0.0235 - Testing Loss: 0.0317
0%| | 0/12 [00:00<?, ?it/s]
Epoch 16/50 - Training Loss: 0.0205 - Testing Loss: 0.0285
0%| | 0/12 [00:00<?, ?it/s]
Epoch 17/50 - Training Loss: 0.0144 - Testing Loss: 0.0247
0%| | 0/12 [00:00<?, ?it/s]
Epoch 18/50 - Training Loss: 0.0118 - Testing Loss: 0.0225
0%| | 0/12 [00:00<?, ?it/s]
Epoch 19/50 - Training Loss: 0.0121 - Testing Loss: 0.0301
0%| | 0/12 [00:00<?, ?it/s]
Epoch 20/50 - Training Loss: 0.0108 - Testing Loss: 0.0227
0%| | 0/12 [00:00<?, ?it/s]
Epoch 21/50 - Training Loss: 0.0083 - Testing Loss: 0.0187
0%| | 0/12 [00:00<?, ?it/s]
Epoch 22/50 - Training Loss: 0.0077 - Testing Loss: 0.0182
0%| | 0/12 [00:00<?, ?it/s]
Epoch 23/50 - Training Loss: 0.0070 - Testing Loss: 0.0161
0%| | 0/12 [00:00<?, ?it/s]
Epoch 24/50 - Training Loss: 0.0074 - Testing Loss: 0.0152
0%| | 0/12 [00:00<?, ?it/s]
Epoch 25/50 - Training Loss: 0.0059 - Testing Loss: 0.0145
0%| | 0/12 [00:00<?, ?it/s]
Epoch 26/50 - Training Loss: 0.0056 - Testing Loss: 0.0138
0%| | 0/12 [00:00<?, ?it/s]
51
Epoch 27/50 - Training Loss: 0.0040 - Testing Loss: 0.0126
0%| | 0/12 [00:00<?, ?it/s]
Epoch 28/50 - Training Loss: 0.0038 - Testing Loss: 0.0110
0%| | 0/12 [00:00<?, ?it/s]
Epoch 29/50 - Training Loss: 0.0038 - Testing Loss: 0.0102
0%| | 0/12 [00:00<?, ?it/s]
Epoch 30/50 - Training Loss: 0.0040 - Testing Loss: 0.0110
0%| | 0/12 [00:00<?, ?it/s]
Epoch 31/50 - Training Loss: 0.0053 - Testing Loss: 0.0120
0%| | 0/12 [00:00<?, ?it/s]
Epoch 32/50 - Training Loss: 0.0052 - Testing Loss: 0.0148
0%| | 0/12 [00:00<?, ?it/s]
Epoch 33/50 - Training Loss: 0.0046 - Testing Loss: 0.0091
0%| | 0/12 [00:00<?, ?it/s]
Epoch 34/50 - Training Loss: 0.0029 - Testing Loss: 0.0078
0%| | 0/12 [00:00<?, ?it/s]
Epoch 35/50 - Training Loss: 0.0021 - Testing Loss: 0.0065
0%| | 0/12 [00:00<?, ?it/s]
Epoch 36/50 - Training Loss: 0.0024 - Testing Loss: 0.0063
0%| | 0/12 [00:00<?, ?it/s]
Epoch 37/50 - Training Loss: 0.0021 - Testing Loss: 0.0075
0%| | 0/12 [00:00<?, ?it/s]
Epoch 38/50 - Training Loss: 0.0019 - Testing Loss: 0.0058
0%| | 0/12 [00:00<?, ?it/s]
Epoch 39/50 - Training Loss: 0.0023 - Testing Loss: 0.0063
0%| | 0/12 [00:00<?, ?it/s]
Epoch 40/50 - Training Loss: 0.0023 - Testing Loss: 0.0074
0%| | 0/12 [00:00<?, ?it/s]
Epoch 41/50 - Training Loss: 0.0034 - Testing Loss: 0.0082
0%| | 0/12 [00:00<?, ?it/s]
Epoch 42/50 - Training Loss: 0.0034 - Testing Loss: 0.0055
0%| | 0/12 [00:00<?, ?it/s]
52
Epoch 43/50 - Training Loss: 0.0025 - Testing Loss: 0.0054
0%| | 0/12 [00:00<?, ?it/s]
Epoch 44/50 - Training Loss: 0.0019 - Testing Loss: 0.0048
0%| | 0/12 [00:00<?, ?it/s]
Epoch 45/50 - Training Loss: 0.0018 - Testing Loss: 0.0059
0%| | 0/12 [00:00<?, ?it/s]
Epoch 46/50 - Training Loss: 0.0017 - Testing Loss: 0.0056
0%| | 0/12 [00:00<?, ?it/s]
Epoch 47/50 - Training Loss: 0.0015 - Testing Loss: 0.0043
0%| | 0/12 [00:00<?, ?it/s]
Epoch 48/50 - Training Loss: 0.0012 - Testing Loss: 0.0047
0%| | 0/12 [00:00<?, ?it/s]
Epoch 49/50 - Training Loss: 0.0012 - Testing Loss: 0.0039
0%| | 0/12 [00:00<?, ?it/s]
Epoch 50/50 - Training Loss: 0.0012 - Testing Loss: 0.0039
(448,)
(448,)
plot_data = [trace1,trace2]
[Link]()
53
output_103_0.png
demonstrating more promising results, as LSTMs are well-suited for modeling sequential data, and
the GADF images provided a suitable representation of the temporal patterns present in the time
series.
gadf_image = gaf.fit_transform(values[:,i:i+data_size])
gadf_image = [Link]([Link](gadf_image, 3, axis=0), (1, 2, 0))
# print(gadf_image.shape)
image = preprocess(gadf_image).unsqueeze(0)
with torch.no_grad():
encoding = resnet([Link]()).squeeze().numpy()
54
[Link](encoding)
[Link](values[:,i+data_size+1])
images = [Link](images)
print([Link])
(489, 1000)
labels = scaler.fit_transform(labels).reshape(-1,).astype(np.float32)
55
[103]: train_losses = []
test_losses = []
# input_sz = 32*32
input_sz = LATENT_SIZE
hidden_sz = 2048
output_sz = 1
layers = 1
LSTMmodel = ImageLSTMNet(input_sz,hidden_sz,layers,output_sz).to(device)
criterion = [Link]()
optimizer = [Link]([Link](), lr=0.0001)
num_epochs = 50
for epoch in range(num_epochs):
train_loss = 0.0
pbar = tqdm(total = len(train_loader))
for xbatch,ybatch in train_loader:
optimizer.zero_grad()
xbatch, ybatch = [Link](device),[Link](device)
output = LSTMmodel(xbatch)
loss = criterion(output,ybatch)
[Link]()
[Link]()
train_loss += [Link]()
[Link](1)
train_loss /= len(train_loader)
[Link]()
test_loss = 0.0
with torch.no_grad():
for xbatch,ybatch in test_loader:
xbatch, ybatch = [Link](device),[Link](device)
output = LSTMmodel(xbatch)
loss = criterion(output,ybatch)
test_loss += [Link]()
test_loss /= len(test_loader)
pred = LSTMmodel([Link](seq_images).to(device)).cpu().[Link]().
,→squeeze()
56
0%| | 0/12 [00:00<?, ?it/s]
Epoch 3/50 - Training Loss: 0.4675 - Testing Loss: 0.2247
0%| | 0/12 [00:00<?, ?it/s]
Epoch 4/50 - Training Loss: 0.1759 - Testing Loss: 0.1003
0%| | 0/12 [00:00<?, ?it/s]
Epoch 5/50 - Training Loss: 0.0603 - Testing Loss: 0.0421
0%| | 0/12 [00:00<?, ?it/s]
Epoch 6/50 - Training Loss: 0.0335 - Testing Loss: 0.0273
0%| | 0/12 [00:00<?, ?it/s]
Epoch 7/50 - Training Loss: 0.0159 - Testing Loss: 0.0199
0%| | 0/12 [00:00<?, ?it/s]
Epoch 8/50 - Training Loss: 0.0088 - Testing Loss: 0.0160
0%| | 0/12 [00:00<?, ?it/s]
Epoch 9/50 - Training Loss: 0.0063 - Testing Loss: 0.0134
0%| | 0/12 [00:00<?, ?it/s]
Epoch 10/50 - Training Loss: 0.0075 - Testing Loss: 0.0101
0%| | 0/12 [00:00<?, ?it/s]
Epoch 11/50 - Training Loss: 0.0043 - Testing Loss: 0.0091
0%| | 0/12 [00:00<?, ?it/s]
Epoch 12/50 - Training Loss: 0.0032 - Testing Loss: 0.0067
0%| | 0/12 [00:00<?, ?it/s]
Epoch 13/50 - Training Loss: 0.0037 - Testing Loss: 0.0073
0%| | 0/12 [00:00<?, ?it/s]
Epoch 14/50 - Training Loss: 0.0034 - Testing Loss: 0.0064
0%| | 0/12 [00:00<?, ?it/s]
Epoch 15/50 - Training Loss: 0.0031 - Testing Loss: 0.0076
0%| | 0/12 [00:00<?, ?it/s]
Epoch 16/50 - Training Loss: 0.0045 - Testing Loss: 0.0063
0%| | 0/12 [00:00<?, ?it/s]
Epoch 17/50 - Training Loss: 0.0041 - Testing Loss: 0.0061
0%| | 0/12 [00:00<?, ?it/s]
Epoch 18/50 - Training Loss: 0.0035 - Testing Loss: 0.0048
57
0%| | 0/12 [00:00<?, ?it/s]
Epoch 19/50 - Training Loss: 0.0025 - Testing Loss: 0.0050
0%| | 0/12 [00:00<?, ?it/s]
Epoch 20/50 - Training Loss: 0.0021 - Testing Loss: 0.0042
0%| | 0/12 [00:00<?, ?it/s]
Epoch 21/50 - Training Loss: 0.0019 - Testing Loss: 0.0056
0%| | 0/12 [00:00<?, ?it/s]
Epoch 22/50 - Training Loss: 0.0016 - Testing Loss: 0.0054
0%| | 0/12 [00:00<?, ?it/s]
Epoch 23/50 - Training Loss: 0.0017 - Testing Loss: 0.0037
0%| | 0/12 [00:00<?, ?it/s]
Epoch 24/50 - Training Loss: 0.0018 - Testing Loss: 0.0042
0%| | 0/12 [00:00<?, ?it/s]
Epoch 25/50 - Training Loss: 0.0018 - Testing Loss: 0.0055
0%| | 0/12 [00:00<?, ?it/s]
Epoch 26/50 - Training Loss: 0.0020 - Testing Loss: 0.0038
0%| | 0/12 [00:00<?, ?it/s]
Epoch 27/50 - Training Loss: 0.0017 - Testing Loss: 0.0037
0%| | 0/12 [00:00<?, ?it/s]
Epoch 28/50 - Training Loss: 0.0024 - Testing Loss: 0.0037
0%| | 0/12 [00:00<?, ?it/s]
Epoch 29/50 - Training Loss: 0.0025 - Testing Loss: 0.0046
0%| | 0/12 [00:00<?, ?it/s]
Epoch 30/50 - Training Loss: 0.0026 - Testing Loss: 0.0080
0%| | 0/12 [00:00<?, ?it/s]
Epoch 31/50 - Training Loss: 0.0027 - Testing Loss: 0.0053
0%| | 0/12 [00:00<?, ?it/s]
Epoch 32/50 - Training Loss: 0.0022 - Testing Loss: 0.0071
0%| | 0/12 [00:00<?, ?it/s]
Epoch 33/50 - Training Loss: 0.0019 - Testing Loss: 0.0033
0%| | 0/12 [00:00<?, ?it/s]
Epoch 34/50 - Training Loss: 0.0014 - Testing Loss: 0.0037
58
0%| | 0/12 [00:00<?, ?it/s]
Epoch 35/50 - Training Loss: 0.0014 - Testing Loss: 0.0047
0%| | 0/12 [00:00<?, ?it/s]
Epoch 36/50 - Training Loss: 0.0012 - Testing Loss: 0.0039
0%| | 0/12 [00:00<?, ?it/s]
Epoch 37/50 - Training Loss: 0.0013 - Testing Loss: 0.0051
0%| | 0/12 [00:00<?, ?it/s]
Epoch 38/50 - Training Loss: 0.0015 - Testing Loss: 0.0066
0%| | 0/12 [00:00<?, ?it/s]
Epoch 39/50 - Training Loss: 0.0015 - Testing Loss: 0.0032
0%| | 0/12 [00:00<?, ?it/s]
Epoch 40/50 - Training Loss: 0.0009 - Testing Loss: 0.0037
0%| | 0/12 [00:00<?, ?it/s]
Epoch 41/50 - Training Loss: 0.0008 - Testing Loss: 0.0036
0%| | 0/12 [00:00<?, ?it/s]
Epoch 42/50 - Training Loss: 0.0009 - Testing Loss: 0.0049
0%| | 0/12 [00:00<?, ?it/s]
Epoch 43/50 - Training Loss: 0.0010 - Testing Loss: 0.0034
0%| | 0/12 [00:00<?, ?it/s]
Epoch 44/50 - Training Loss: 0.0008 - Testing Loss: 0.0029
0%| | 0/12 [00:00<?, ?it/s]
Epoch 45/50 - Training Loss: 0.0009 - Testing Loss: 0.0030
0%| | 0/12 [00:00<?, ?it/s]
Epoch 46/50 - Training Loss: 0.0010 - Testing Loss: 0.0033
0%| | 0/12 [00:00<?, ?it/s]
Epoch 47/50 - Training Loss: 0.0013 - Testing Loss: 0.0039
0%| | 0/12 [00:00<?, ?it/s]
Epoch 48/50 - Training Loss: 0.0015 - Testing Loss: 0.0052
0%| | 0/12 [00:00<?, ?it/s]
Epoch 49/50 - Training Loss: 0.0015 - Testing Loss: 0.0036
0%| | 0/12 [00:00<?, ?it/s]
Epoch 50/50 - Training Loss: 0.0013 - Testing Loss: 0.0039
59
[104]: actual = labels[41:]
print([Link])
print([Link])
(448,)
(448,)
plot_data = [trace1,trace2]
[Link]()
output_116_0.png
[ ]:
60