GCN+LSTM

 

背景

METR_LA analogue ressults

數據特性之比較(Graph components)

  • 圖形(節點、邊緣、加權等)為靜態、節點特徵值則為動態
  • 單一特徵
項目 METRO_LA 2019.nc_NO2 說明
  data source LA交通局數據 2019.nc CMAQ公版模式背景濃度模擬結果
節點 速度監測站點 島內各網格點 前者較少、後者較多
特徵值 交通速度 空氣污染濃度值 分部有顯著差異(詳下)
時間頻率特徵 每5分鐘一筆 每小時一筆  
邊緣加權 站點間的距離(作為邊緣的加權量) 網格點間距離-0.25  

parameters

項目 METRO_LA 2019.nc_NO2 說明
seq_len 10 72  
pre_len 12 24  
gc_layer_sizes [16, 10] [16, 72]  
gc_activations relu relu  
lstm_layer_sizes [20, 10] [20, 72]  
lstm_activations tanh tanh  
epochs 100 200  
batch_size 60 60  
MASE 0.698 0.650 同一數量級

Loss/MSE during training

METR_LA速度預報訓練 2019.nc_NO2

Distribution over segments

  • speed training and testing results
    • training及testing都是扁胖形分布、訓練組更胖一些。表示原始數據可以符合高斯分布,並沒有顯著的極端值。訓練組的符合度更好一些。
    • 測試組之模擬誤差略為偏低
METR_LA速度預報測試結果 2019.nc_NO2
  • NO2
    • 原始數據與高斯模式的符合度不高。訓練及測試組皆然。(空氣品質的分布特性為對數高斯分布。)
    • training及testing都有強烈的趨中性質
    • 二者的平均絕對誤差值還蠻接近的
    • 測試組之誤差略為偏低

all test result visualization

  • speed predictoins
METR_LA速度預報測試結果 2019.nc_NO2(部分值)
  • NO2 predictions
    • 可以抓到日變化的趨勢
    • 對高值毫無預測能力。還需借助於其他模型、如
      1. 預先分類再予訓練

程式設計重點說明

台灣島多邊形之讀取

  • 使用Voronoi作業過程中的半成品
import geopandas as gpd
root='/nas2/cmaqruns/2022fcst/fusion/Voronoi/'
boundary=gpd.read_file(root+'boundary_shape.shp')
boundary_shape = boundary.geometry[0]

島內格點的篩選

  • 此處使用shapely.geometry.Polygon.within函數
  • 先篩出符合的點的名稱標籤(name)
  • DataFrame.loc中設定boolean將原來資料表篩減,減省至少2/3。
x1d=[nc.XORIG+nc.XCELL*(i+0.5) for i in range(ncol)]
y1d=[nc.YORIG+nc.YCELL*(i+0.5) for i in range(nrow)]
X,Y=np.meshgrid(x1d,y1d)
X,Y=X.flatten(),Y.flatten()
lons, lats= pnyc(X,Y, inverse=True)
pnts=[Point(lon,lat) for lon,lat in zip(lons,lats)]
dfNod=pd.DataFrame({'geometry':pnts,'name':[str(i) for i in range(NM)]})

name_inside=dfNod.loc[dfNod.geometry.map(lambda p:p.within(boundary_shape)),'name']
...
s=set(name_inside)
n=len(s)
dfNod2=dfNod.loc[dfNod.name.map(lambda x:x in s)].reset_index(drop=True)"

網格點兩兩距離之計算

  • 這個問題如果用迴圈來設計,將會是一個災難。
    • 用shapely.geometry.Point.distance函數、完全沒有幫助
    • 即使計算對角線上(或下)一半,在映射到另一半,可以減省一半的計算時間,還是沒有太大的幫助。
  • 可以利用None維度的技巧,來重複2維矩陣中特定的一個部分。(參矩陣階層numpy.newaxis(None)的用法)
  • 下列程式段落中的n即為網格點個數,因為是計算兩兩距離(d),因此d的維度是2維,大小都是n。
    • 預先將網格點X、Y值處理成1維向量,其長度為n
    • X,Y=np.array(dfNod2.X),np.array(dfNod2.Y)
  • 設定終點為第0個維度、起點則為第1個(另一個)維度
  • 用矩陣標示法直接計算這個d[n,n]的方法,就是定義相對應的終點(X1,Y1)與起點(X2,Y2),進行差值計算、取平方、相加、再取根號。
    • d[:,:]=np.sqrt((X1-X2)**2+(Y1-Y2)**2)
    • 因此X1、X2、Y1、Y2的形狀,也必須完全與d相同
    • 先予以填充0值,預留記憶體(空的容器)。
  • 起點為第0個維度,因此X1、Y1第0個維度的內容必須完全與X,Y相同,另一個維度則複製即可。此處以None將向量複製擴張成矩陣。
  • 同理應用在終點(X2、Y2),維度設定與起點(X1、Y1)相反即可。
  • 交錯寫法,是因為複製、貼上、將X改成Y,是最快的編輯方式
d=np.zeros(shape=(n,n))
X1=np.zeros(shape=(n,n))
Y1=np.zeros(shape=(n,n))
X2=np.zeros(shape=(n,n))
Y2=np.zeros(shape=(n,n))
X,Y=np.array(dfNod2.X),np.array(dfNod2.Y)
X1[:,:],X2[:,:]=X[:,None],X[None,:]
Y1[:,:],Y2[:,:]=Y[:,None],Y[None,:]
d[:,:]=np.sqrt((X1-X2)**2+(Y1-Y2)**2) #dfNod2.geometry[j].distance(dfNod2.geometry[i])        
#for j in range(n):
#    for i in range(0,j):
#        d[j,i]=d[i,j]

加權的計算

  • 原範例是用交通速度測點間的距離來加權,距離越大的路段速度會越快,加權越重。通過2個測點的速度比較容易相近(車輛運動的慣性物理性質),越近的測點,車速會降低,加減速的敏感性就越高(作者認定的模型)。
  • 此處空氣品質則相反,距離越遠的點差異可能就越大,越相近的點差異會越小。因此使用距離的倒數來加權
  • 同一點的距離為0,倒數無意義,且不能參與取極值過程。因此取倒數後直接令其為1(足夠小的暫定值)。
  • 取極值之後,再將對角線值全都設為最大值,再除以此最大值,以使最大值為1。
  • 取0.25次方的用意是讓空間上的漸變過程趨緩一些
d=1/d*1000.
for j in range(n):
    d[j,j]=1.
dmax=d.max()   
for j in range(n):
    d[j,j]=dmax
d=np.sqrt(np.sqrt(d/dmax))