import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
Simulation of geometric-temporal
Simulation
https://pytorch-geometric-temporal.readthedocs.io/en/latest/modules/dataset.html#module-torch_geometric_temporal.dataset.chickenpox
import
공식 홈페이지 예제
data
from torch_geometric_temporal.dataset import WikiMathsDatasetLoader
from torch_geometric_temporal.signal import temporal_signal_split
= WikiMathsDatasetLoader()
loader
= loader.get_dataset(lags=14)
dataset
= temporal_signal_split(dataset, train_ratio=0.5) train_dataset, test_dataset
RecurrentGCN
import torch
import torch.nn.functional as F
from torch_geometric_temporal.nn.recurrent import GConvGRU
class RecurrentGCN(torch.nn.Module):
def __init__(self, node_features, filters):
super(RecurrentGCN, self).__init__()
self.recurrent = GConvGRU(node_features, filters, 2)
self.linear = torch.nn.Linear(filters, 1)
def forward(self, x, edge_index, edge_weight):
= self.recurrent(x, edge_index, edge_weight)
h = F.relu(h)
h = self.linear(h)
h return h
Learn
from tqdm import tqdm
= RecurrentGCN(node_features=14, filters=32)
model
= torch.optim.Adam(model.parameters(), lr=0.01)
optimizer
model.train()
for epoch in tqdm(range(1)):
for time, snapshot in enumerate(train_dataset):
= model(snapshot.x, snapshot.edge_index, snapshot.edge_attr)
y_hat = torch.mean((y_hat-snapshot.y)**2)
cost
cost.backward()
optimizer.step() optimizer.zero_grad()
100%|██████████| 1/1 [00:11<00:00, 11.93s/it]
for time, snapshot in enumerate(train_dataset):
= snapshot.x
_x = snapshot.edge_index
_edge_index = snapshot.edge_attr
_edge_attr = snapshot.y
_y break
_x.shape
torch.Size([1068, 14])
snapshot.y.shape
torch.Size([1068])
- 1068개의 nodes
- 한 개의 node에 mapping된 차원의 수
_edge_index.shape
torch.Size([2, 27079])
_edge_attr.shape
torch.Size([27079])
_y.shape
torch.Size([1068])
우리 예제
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
= 100
T = 4 # number of Nodes
N = np.array([[0,1],[1,2],[2,3],[3,0]]).T
E = np.array([1,2,3,4])
V = np.array([3,2,1,2.2])
AMP = np.arange(0,T)
t = 1 node_features
= np.stack([a*np.sin(2*t**2/1000)+np.random.normal(loc=0,scale=0.2,size=T) for a in AMP],axis=1).reshape(T,N,node_features)
f = torch.tensor(f).float() f
f.shape
torch.Size([100, 4, 1])
= f[:99,:,:]
X = f[1:,:,:] y
0,0],label="v1")
plt.plot(y[:,1,0],label="v2")
plt.plot(y[:,2,0],label="v3")
plt.plot(y[:,3,0],label="v4")
plt.plot(y[:, plt.legend()
= torch.tensor(E)
edge_index = torch.tensor(np.array([1,1,1,1]),dtype=torch.float32) edge_attr
= enumerate(zip(X,y)) _ee
from tqdm import tqdm
= RecurrentGCN(node_features=1, filters=4)
model
= torch.optim.Adam(model.parameters(), lr=0.01)
optimizer
model.train()
for epoch in tqdm(range(50)):
for time, (xt,yt) in enumerate(zip(X,y)):
= model(xt, edge_index, edge_attr)
y_hat = torch.mean((y_hat-yt)**2)
cost
cost.backward()
optimizer.step() optimizer.zero_grad()
100%|██████████| 50/50 [00:16<00:00, 3.01it/s]
= torch.stack([model(xt, edge_index, edge_attr) for xt in X]).detach().numpy() yhat
0,0],label="y in V1")
plt.plot(y[:,0,0],label="yhat in V1")
plt.plot(yhat[:, plt.legend()
1,0],label="y in V2")
plt.plot(y[:,1,0],label="yhat in V2")
plt.plot(yhat[:, plt.legend()
2,0],label="y in V3")
plt.plot(y[:,2,0],label="yhat in V3")
plt.plot(yhat[:, plt.legend()
3,0],label="y in V4")
plt.plot(y[:,3,0],label="yhat in V4")
plt.plot(yhat[:, plt.legend()
GNAR
import rpy2
import rpy2.robjects as ro
from rpy2.robjects.vectors import FloatVector
from rpy2.robjects.packages import importr
%load_ext rpy2.ipython
%%R
library(GNAR) library(igraph)
R[write to console]: Loading required package: igraph
R[write to console]:
Attaching package: ‘igraph’
R[write to console]: The following objects are masked from ‘package:stats’:
decompose, spectrum
R[write to console]: The following object is masked from ‘package:base’:
union
R[write to console]: Loading required package: wordcloud
R[write to console]: Loading required package: RColorBrewer
%%R
summary(fiveNet)
GNARnet with 5 nodes and 10 edges
of equal length 1
%%R
<- as.matrix(fiveNet)
edges edges
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 1 1
[2,] 0 0 1 1 0
[3,] 0 1 0 1 0
[4,] 1 1 1 0 0
[5,] 1 0 0 0 0
%%R
print(fiveNet)
GNARnet with 5 nodes
edges:1--4 1--5 2--3 2--4 3--2 3--4 4--1 4--2 4--3 5--1
edges of each of length 1
%%R
"fiveNode")
data(<- GNARfit(vts = fiveVTS, net = fiveNet, alphaOrder = 2, betaOrder = c(1, 1))
answer answer
Model:
GNAR(2,[1,1])
Call:
lm(formula = yvec ~ dmat + 0)
Coefficients:
dmatalpha1 dmatbeta1.1 dmatalpha2 dmatbeta2.1
0.20624 0.50277 0.02124 -0.09523
%%R
1,2,3,4), 2, 2, byrow = TRUE))
layout(matrix(c(1], ylab = "Node A Time Series")
plot(fiveVTS[, 1], col = 2)
lines(fitted(answer)[, 2], ylab = "Node B Time Series")
plot(fiveVTS[, 2], col = 2)
lines(fitted(answer)[, 3], ylab = "Node C Time Series")
plot(fiveVTS[, 3], col = 2)
lines(fitted(answer)[, 4], ylab = "Node D Time Series")
plot(fiveVTS[, 4], col = 2) lines(fitted(answer)[,
%R -o fiveVTS
%R -o edges
- node: 5
- time 200
= torch.tensor(edges) edges_tensor
= edges_tensor.nonzero() nonzero_indices
= np.array(nonzero_indices).T
fiveNet_edge fiveNet_edge
array([[0, 0, 1, 1, 2, 2, 3, 3, 3, 4],
[3, 4, 2, 3, 1, 3, 0, 1, 2, 0]])
fiveVTS.shape
(200, 5)
= 200
T = 5 # number of Nodes
N = fiveNet_edge
E = np.array([1,2,3,4,5])
V = np.arange(0,T)
t = 1 node_features
= torch.tensor(fiveVTS).reshape(200,5,1).float() f
= f[:199,:,:]
X = f[1:,:,:] y
= torch.tensor(E)
edge_index = torch.tensor(np.array([1,1,1,1,1,1,1,1,1,1]),dtype=torch.float32) edge_attr
= enumerate(zip(X,y)) _ee
from tqdm import tqdm
= RecurrentGCN(node_features=1, filters=8)
model
= torch.optim.Adam(model.parameters(), lr=0.05)
optimizer
model.train()
for epoch in tqdm(range(50)):
for time, (xt,yt) in enumerate(zip(X,y)):
= model(xt, edge_index, edge_attr)
y_hat = torch.mean((y_hat-yt)**2)
cost
cost.backward()
optimizer.step() optimizer.zero_grad()
100%|█| 50/50 [00:34<00:00, 1.45it/
= torch.stack([model(xt, edge_index, edge_attr) for xt in X]).detach().numpy() yhat
yhat.shape
(199, 5, 1)
1])
plt.plot(y[:,1].data) plt.plot(yhat[:,
Wind network time series
the data suite vswind that contains a number of R objects pertaining to 721 wind speeds taken at each of 102 weather stations in England and Wales. The suite contains the vector time series vswindts, the associated network vswindnet, a character vector of the weather station location names in vswindnames and coordinates of the stations in the two column matrix vswindcoords. The data originate from the UK Met Office site http://wow.metoffice.gov.uk and full details can be found in the vswind help file in the GNAR package.
%%R
<- par(cex = 0.75)
oldpar
windnetplot() par(oldpar)
%%R
<- as.matrix(vswindnet) edges_wind
%R -o vswindts
%R -o edges_wind
- nodes : 102
- time step : 721
vswindts.shape
(721, 102)
edges_wind.shape
(102, 102)
= torch.tensor(edges_wind) edges_winds
= edges_winds.nonzero() nonzero_indices_wind
= np.array(nonzero_indices_wind).T
vswindnet_edge vswindnet_edge.shape
(2, 202)
= 721
T = 102 # number of Nodes
N = vswindnet_edge
E = np.array(range(101))
V = np.arange(0,T)
t = 1 node_features
= torch.tensor(vswindts).reshape(721,102,1).float() f
= f[:720,:,:]
X = f[1:,:,:] y
= torch.tensor(E)
edge_index = torch.tensor(np.array([1]*202),dtype=torch.float32) edge_attr
= enumerate(zip(X,y)) _ee
from tqdm import tqdm
= RecurrentGCN(node_features=1, filters=4)
model
= torch.optim.Adam(model.parameters(), lr=0.01)
optimizer
model.train()
for epoch in tqdm(range(50)):
for time, (xt,yt) in enumerate(zip(X,y)):
= model(xt, edge_index, edge_attr)
y_hat = torch.mean((y_hat-yt)**2)
cost
cost.backward()
optimizer.step() optimizer.zero_grad()
100%|██████████| 50/50 [02:16<00:00, 2.73s/it]
= torch.stack([model(xt, edge_index, edge_attr) for xt in X]).detach().numpy() yhat
yhat.shape
(720, 102, 1)
1])
plt.plot(y[:,1].data) plt.plot(yhat[:,
OECD GDP
해당예제는 GNAR 패키지에서 네트워크(엣지)를 맞추는 예제로서 나옴, 그렇기에 네트워크 존재하지 않아 연구 예제로서 사용하지 않을 예정
이 데이터는 네트워크를 추정하여 fit 및 predict함
GOP growth rate time series
35 countries from the OECD website
time series : 1961 - 2013
T = 52
Nodes = 35
In this data set 20.8% (379 out of 1820) of the observations were missing due to some nodes not being included from the start.
%%R
"fields") library(
%R -o gdpVTS
gdpVTS.shape
(52, 35)
1]) plt.plot(gdpVTS[:,