-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathgenerate_adj.py
104 lines (82 loc) · 3.26 KB
/
generate_adj.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import numpy as np
import pandas as pd
import torch
import scipy.sparse as sp
from sklearn.metrics.pairwise import haversine_distances
def geographical_distance(x=None, to_rad=True):
_AVG_EARTH_RADIUS_KM = 6371.0088
# Extract values of X if it is a DataFrame, else assume it is 2-dim array of lat-lon pairs
latlon_pairs = x.values if isinstance(x, pd.DataFrame) else x
# If the input values are in degrees, convert them in radians
if to_rad:
latlon_pairs = np.vectorize(np.radians)(latlon_pairs)
distances = haversine_distances(latlon_pairs) * _AVG_EARTH_RADIUS_KM
# Cast response
if isinstance(x, pd.DataFrame):
res = pd.DataFrame(distances, x.index, x.index)
else:
res = distances
return res
def thresholded_gaussian_kernel(x, theta=None, threshold=None, threshold_on_input=False):
if theta is None:
theta = np.std(x)
weights = np.exp(-np.square(x / theta))
if threshold is not None:
mask = x > threshold if threshold_on_input else weights < threshold
weights[mask] = 0.
return weights
def get_similarity_AQI(dist, thr=0.1, include_self=False, force_symmetric=False, sparse=False):
theta = np.std(dist[:36, :36]) # use same theta for both air and air36
adj = thresholded_gaussian_kernel(dist, theta=theta, threshold=thr)
if not include_self:
adj[np.diag_indices_from(adj)] = 0.
if force_symmetric:
adj = np.maximum.reduce([adj, adj.T])
if sparse:
import scipy.sparse as sps
adj = sps.coo_matrix(adj)
return adj
def get_adj_AQI36():
df = pd.read_csv("./data/pm25/SampleData/pm25_latlng.txt")
df = df[['latitude', 'longitude']]
res = geographical_distance(df, to_rad=False).values
adj = get_similarity_AQI(res)
return adj
def get_similarity_metrla(thr=0.1, force_symmetric=False, sparse=False):
dist = np.load('./data/metr_la/metr_la_dist.npy')
finite_dist = dist.reshape(-1)
finite_dist = finite_dist[~np.isinf(finite_dist)]
sigma = finite_dist.std()
adj = np.exp(-np.square(dist / sigma))
adj[adj < thr] = 0.
if force_symmetric:
adj = np.maximum.reduce([adj, adj.T])
if sparse:
import scipy.sparse as sps
adj = sps.coo_matrix(adj)
return adj
def get_similarity_pemsbay(thr=0.1, force_symmetric=False, sparse=False):
dist = np.load('./data/pems_bay/pems_bay_dist.npy')
finite_dist = dist.reshape(-1)
finite_dist = finite_dist[~np.isinf(finite_dist)]
sigma = finite_dist.std()
adj = np.exp(-np.square(dist / sigma))
adj[adj < thr] = 0.
if force_symmetric:
adj = np.maximum.reduce([adj, adj.T])
if sparse:
import scipy.sparse as sps
adj = sps.coo_matrix(adj)
return adj
# in Graph-wavenet
def asym_adj(adj):
adj = sp.coo_matrix(adj)
rowsum = np.array(adj.sum(1)).flatten()
d_inv = np.power(rowsum, -1).flatten()
d_inv[np.isinf(d_inv)] = 0.
d_mat= sp.diags(d_inv)
return d_mat.dot(adj).astype(np.float32).todense()
def compute_support_gwn(adj, device=None):
adj_mx = [asym_adj(adj), asym_adj(np.transpose(adj))]
support = [torch.tensor(i).to(device) for i in adj_mx]
return support