基于PyG搭建GCN-LSTM时空犯罪预测

基于PyG搭建GCN-LSTM时空犯罪预测

1.前言

最近针对犯罪时空预测、犯罪分布可视化开展研究,图神经网络是必不可少的研究工具之一,为了记录学习PyG的过程,本文通过结合官网案例(非常晦涩难懂)以及网上各位大佬的学习过程,撰写此文章,以此记录学习过程,以防后面遗忘,如有错误请嘴下留情。

2. PyG安装过程以及需要的包

此处省略安装过程

3.数据描述

本文采用的是美国纽约州的犯罪数据,具体可视化如图所示:
犯罪可视化过程
在这里插入图片描述

数据被分为训练集、验证集、测试集,数据形状为四维数据:[16, 16, 608, 4],其中分别代表划分成16*16的区域,每个区域上608个时间段,4种犯罪类型。输入是过去n天的犯罪矩阵,输出是n+1天的犯罪矩阵。

4.数据处理

用图神经网络的重要一步就是构建图,如何构建图呢?PyG还是比较人性的,在对数据进行转换后,通过KNN算法,筛选出邻近节点,然后构建边,这里也需要注意,数据的输入维度需要按照PyG指定的格式才行。

edge_index = knn(torch.from_numpy(train.reshape(256,-1)),
             torch.from_numpy(train.reshape(256,-1)),3)
graph = Data(x=TempTrain,edge_index=edge_index)

将数据处理成图结构后,需要对数据进行封装,熟悉torch的小伙伴也应该也一看就懂,PyG的封装格式与torch相似,这里介绍下将自己的数据处理成PyG格式的方法,借鉴了@Cyril_KI大佬的代码格式,自己进行修改:

  def process(dataset, batch_size, step_size, shuffle):
       nodes, timeLength = dataset.shape[0], dataset.shape[1]
       # print(nodes,timeLength)
       dataset = dataset.tolist()

       graphs = []
       for i in tqdm(range(0, timeLength - seq_len - pred_step_size, step_size)):

           train_seq = []
           for j in range(i, i + seq_len):
               x = []
               for c in range(nodes):            ##存储过去时间段的二维图矩阵
                   x.append(dataset[c][j])

               temp = functools.reduce(operator.concat, x)
               # print(temp)
               train_seq.append(temp)
           # 下几个时刻的所有变量
           train_labels = []
           for k in range(i + seq_len, i+seq_len+step_size):
               train_label = []
               for j in range(nodes):
                   train_label.append(dataset[j][k])
               # print(train_label)
               temp1 = functools.reduce(operator.concat, train_label)
               # print(temp1)
               train_labels.append(temp1)

           # tensor
           # print(np.ndarray(train_seq).shape, np.ndarray(train_labels).shape)
           train_seq = torch.FloatTensor(train_seq)
           train_labels = torch.FloatTensor(train_labels)
           # print(train_seq.shape, train_labels.shape)  # 24 13, 13 1
           temp = Data(x=train_seq.T, edge_index=graph.edge_index, y=train_labels)
           # print(temp)
           graphs.append(temp)

       loader = torch_geometric.loader.DataLoader(graphs, batch_size=batch_size,
                                                  shuffle=shuffle, drop_last=True)

       return loader,graphs

   Dtr,Dtrgraphs = process(train, B, step_size=1, shuffle=True)
   Val,Valgraphs = process(val, B, step_size=1, shuffle=True)
   Dte,Dtegraphs = process(test, B, step_size=pred_step_size, shuffle=True)

5.模型构建

此处构建一个GCN+LSTM模型,简单的来说,核心是有batchsize那么多个图,拼成一个大的,然后你分别用网络处理,处理后呢,再返回成batchsize那么多个图

class GCN(torch.nn.Module):
    def __init__(self, in_feats, h_feats, out_feats,batchsize):
        super(GCN, self).__init__()
        self.conv1 = GCNConv(in_feats, h_feats)
        self.conv2 = GCNConv(h_feats, out_feats)
        self.fc = nn.Sequential(
            nn.Linear(128, out_feats),
            nn.ReLU(),
            nn.Linear(out_feats, 1),
        )
        self.batch = batchsize
        self.lstm = nn.LSTM(out_feats, 128, batch_first=True, dropout=0.5)
    def forward(self, data):
        x, edge_index, batch = data.x, data.edge_index, data.batch
        x = x.float()
        x = F.elu(self.conv1(x, edge_index))
        x = self.conv2(x, edge_index))
        x = x.view(len(x),1,-1)
        x,_ = self.lstm(x)
        out = self.fc(x)
        out = torch.reshape(out,(self.batch,-1))
        return out

6.训练和测试

此处代码可参照大佬@Cyril_KI之前写的模板,此处不再叙述

7.结果分析

由于实验不多,仅仅用了传统CNN算法、GCN算法、和GCN-LSTM算法进行分析,在Mape上指标差异巨大,GCN算法提升效果很高,感兴趣的可以自己试试,相对GCN呢,引入LSTM处理时序数据,在一定程度上可以提高点数。

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值