基于KG嵌入和卷积-LSTM网络的药物-药物相互作用预测——重现

本篇讲一下要是想重现应该从哪些方面去入手。

一、前言

首先来说,本文构建的网络是由CNN和LSTM复合而成的一个Conv-LSTM网络,而且涉及到了参数优化,网络构建,训练等一系列东西。要是你初学的话,真的不建议你直接上手这个。

要重现本文,我觉得有以下要点:

(1)单纯对于要构建的神经网络来说,在这之前你要充分理解CNN,RNN,LSTM和MLP的原理以及实现,注意是充分熟练的了解;

(2在熟练掌握上面的原理的基础上,大量实践,通过复现基础的东西,充分掌握如何构建,训练和实现那些单一的网络,才能考虑重现这个;

      ——此处可能涉及到很多问题,比如参数是怎么优化的,即Adam优化,RMSP优化一堆东西,梯度下降法的原理,再比如超参数优化,即网格搜索等等的超参数优化方法,总之就是要实现神经网络要用到的东西你都要会而且要会实现。

(3)除了神经网络,你还要对知识图谱和图嵌入有一定的了解。知识图谱简要学习一下就好,但嵌入有很多种方法,也有很多概念,你需要好好学习一下它们的概念,方法的原理和实现。因为经过嵌入才能得到试验输入的数据。

总的来说,要想复现本文,对神经网络的原理和实现,图嵌入和知识图谱要掌握。

二、关于本文的网络

重点来啦!!!!!!!!!!!!!!!!!

这篇文章的原文你可以在另一篇博客找到,那篇博客对文章内容和方法也做了简要的叙述,就像我的前两篇博客一样,但他也没有复现成功。虽然你也可以在github找到这篇文章的源码,但那个源码不能用的——完全一点都不能用,半毛钱参考价值都没有。而且那个源码还会误导你对于文章网络结构理解的判断。本人被这个坑苦了。

我总结出了那篇文章说的正确的网络结构,现在叙述如下。

1、卷积层

本文的CNN采用一维卷积Conv1D,是词卷积向量常用方法。注意这个词向量卷积是有点不同于一般的卷积的,体现在卷积核上。具体可以百度一下,易懂。

卷积层后都有最大池化层,以便将卷积层提取的特征进行压缩。卷积层层数为1,卷积核个数为100,卷积核尺寸为4,同时得出卷积核第二维尺寸为300,即100个4*300的卷积核对每一个DDI的100*300的特征矩阵进行压缩和特征提取。

卷积层将100*300的输入特征空间转化成100*100的表示。接下来经过一维最大池化层MaxPooling1D进一步向下采样(此处的池化方法是一维池化方法,不同于一般的池化,具体百度,易懂),该层的池大小嵌入维度为4,产生形状为100*25的输出,其中25个维度中的每一个都可以被认为是一个“提取的特征”。

接下来GlobalMaxPooling1D通过在每个时间步长维度中取最高值来平坦输出空间,从而产生一个包含药物特征的1*100载体(同上,一维全局池化,百度可得),其提炼了我们想要的药物特征数据,将作为LSTM网络的输入,进一步提取特征。

2、LSTM层

LSTM设置为两层,第一层神经元个数为128,第二层为64。以特征向量的维数作为LSTM的时间步长,(这句话很重要,意为time_step=100,每个时间步的输入是一个值,即这100个数字里面的一个)

每个步长输入一个特征值,将第一层LSTM的隐藏状态作为输入,进入第二层LSTM进行进一步的全局特征提取。(因为是两层嘛,不懂的可以去查多层LSTM的实现)

紧跟在LSTM层后面的是两个MLP全连接层。将LSTM的输出作为全连接层的输入,两个全连接层的神经元个数分别设置为128和64,同时分别在LSTM层加上dropout,分别设置为0.5和0.2,以规范学习避免过拟合。直观的说,可以迫使分类器不依赖于任何琐碎的单个药物特征,以及消除减弱了神经元节点之间的联合适应性,增强了泛化能力。经过两个全连接层后,结果被输入到一个softmax层,该层产生概率分布。

注:此处我插一嘴关于输入()很重要!!

你嵌入之后得到的每个DDI应该是1*100的向量,这是没问题的。但你得注意卷积层,卷积不可能卷一个一维的向量,所以你怎么把这个一维的1*300变成卷积层能够处理的二维呢?

其实方法有很多,把一维的向量在列上进行扩展,比如生成与之差不多的数字,扩展,噪音,这些都可以。重点是,你要把一个1*300扩展成100*300.

这里有人要问了:那把100个DDI拼一起不就行了?100个1*300的拼一起不就能卷积了。这个拼一起能卷,但你想想拼一起卷积了之后成什么了?你拼合而成的二维张量卷积出来的东西是没有意义的。你这个方法最终要是一个二分类,即你输入的东西肯定是一个DDI,最后输出的概率代表你这个DDI是否可以发生相互作用。

这里不能拼一起还有另一个原因,就是在LSTM层。

你卷积完之后,经过两个最大池化得到了一个1*100的向量,这个要作为LSTM的输入。问题又来了,LSTM的输入一般不是一个序列吗?你这个1*100应该是一个序列中的一个数据才对,你的时间步长为time_step,你应该有time_step个这样的1*100作为LSTM的输入才对啊?是不是应该再来别的几个DDI生成的1*100,共同凑成一个时序的LSTM的输入?

显然你这样又没意义了。还是那个原因,你这是一个二分类问题,只能是一个DDI,那怎么办呢?容易想到,那就这个1*100的每一个数作为一个时间步长的输入,每个时间步长输入一个数字,而不是一个序列,那么此时的time_step就等于这个向量的长度也就是100.

有人对这个表示怀疑:你这个1*100它里面有时序关系吗?LSTM不是处理序列数据的吗?

从两个方面来回答。首先LSTM的输入只能是我说的这样。因为它是一个二分类问题,只能是一个DDI去训练,同时我这样做也是满足圣经网络的输入要求的。其次,严格来说,我这个1*100是有时序关系的。因为我通过100个卷积核,将相同的数据都卷成了一个数字,这些数字实际上是有关系隐含在里面的,是可以提取出特征的,所以这样的输入没有问题。

总的来说,要理解网络结构,以及里面的参数情况。

三、关于嵌入

嵌入是得到本文的输入的,输入即1*300的向量,每个DDI被抽象成1*300的向量,准备作为分类器的输入。(尽管其实还要经过处理变成100*300才能输入)

嵌入方法有很多,本文提到了6种方法,在理解图嵌入的基础上,进一步理解一下这六种嵌入方法,它们都是各有特点的。它们的特点导致了不同的嵌入结果,进一步导致网络会有不同的效果。

(1)RDF2Vec通过从图中的每个实体开始均匀的执行随机游走来生成文本语料库[36]。然后,使用边缘标记的语料库C被用来作为输入,来学习基于skip-gram网络的RDF2Vec模型的每个节点的嵌入。从一个给定的药物序列,根据固定窗口大小的上下文c,skip-gram模型的目的是最大化平均对数概率。

 

(2)选用了TransE作为基于翻译的KG嵌入方法的代表。在TransE中,每个实体和关系都被作为一个低维向量进行嵌入,其中关系被表示为头实体到尾实体的翻译。

(3)还使用了CrossE嵌入法,它显式的模拟了交叉相互作用,分别为两个方面:首先是关系到实体的交互,即预测的关系也会影响实体的信息筛选;其次是实体到关系的交互,即实体所拥有的信息会影响关系的推理路径的选择。

(4)还采用了Simp1E嵌入法,该方法允许学习每个实体的两个嵌入。通过SimplE学习到的嵌入是可解释的,这有助于将药物相关的背景知识纳入嵌入中。除此之外,SimplE还有一个优点是它优于张量因式分解技术,特别是对于链路预测问题。

(5)KGloVe与RDF2Vec有相似之处,但是使用了一种不同的技术来识别创建向量空间嵌入的全局模式。首先,通过计算每个节点的PageRank值创建共现矩阵,(不懂得可以百度,我也只是了解)此处每个节点的PR值代表每个节点的重要程度。然后,对于两边都相反的图,重复这个过程,这些图的两个矩阵求和并进行归一化。最后,该矩阵作为KGloVe词嵌入算法的输入。

(6)最后一个模型,使用PyTorch-BigGraph(PBG)实现训练ComplEx,因为集成的知识图包含很多三元组,ComplEx是双线性模型的代表,从技术上讲,ComplEx只使用Hermitian点积创建嵌入。使用ComplEx的总体嵌入方法可以说更简单,但由于复杂嵌入的组成可以处理大量的二进制关系(其中包括对称关系和反对称关系),研究表明,复杂嵌入可以优于其他几种模型。

通过嵌入,我们得到了总共3,893,452组特征向量,其中正负实例比大概为2:1,这3,893,452条数据作为训练数据,作为下面分类器的输入。(你复现时有多少数据,就拿多少来用就可以)

:学习KG中的表示依赖于将正实例和负实例进行对比,虽然文章里提到的负实例采集方法是什么破坏正边缘采样,因为这个方法经过验证是最好的。

当然你要是可以学会这个破坏正边缘,你是可以这样负采样的,但要是你不会,那么就用最简单的,没有出现相互作用的就默认是负实例了(你懂的虽然没有并不代表没有只是目前还没有发现,但你也不会更高级的负采样啊),所以我们就以与正实例固定比例去采样,产生负实例,共同组成训练样本进行训练。

四、其他重要的点

还要几点,比如超参数优化,数据来源和基线模型等。

1、超参数优化

这个我了解了一下。超参数就是比如你LSTM的层数啊,你LSTM里面的隐藏节点个数啊,你全连接层的层数和节点个数啊,你的dropout的值设多少啊,这些都是超参数。超参数的优化有很多种方法,比如贝叶斯(我不会),随即搜索和网格搜索(这两个比较简单,百度就懂了)。你可以用我说的这三个方法去进行超参数优化,当然前提是你会的情况下。如果你不懂超参数优化,你可以直接去掉,直接按我说的这个网络结构来就可以。因为这个应该(我肯定也不知道啊)是原作者经过超参数优化之后得出的最优超参数了。

超参数和参数的区别都知道吧。超参数就是上面的,参数就是weight矩阵和bias矩阵的值,就是你的网络实现它的功能时都是一堆矩阵乘法和加系数实现功能的,你最终的网络训练目的就是得出这些矩阵和系数,这就是你的参数,它跟超参数不是一个东西。超参数的优化方法我已经说过了,参数的优化方法,从最开始的梯度下降法,到后面的Adam优化器,RMSP优化器,有很多,你可以去百度。

2、数据来源

原文比较牛,说是整合了四大数据库(哪四个你可以去我另两篇博客找),将其整合成一个很大的知识图谱,然后进行嵌入,得到训练数据。当然这是很牛的,但我估计能干的人少。对于想复现的兄弟而言,你只是想领略一下这个过程,想知道知识图谱和图嵌入是个啥,那你用一个数据库就行了,比如drugbank,直接用它就可以了。将其XML文件解析,然后balabala。

3、ML基线模型

作为对比,原文用了很多基线模型,你需要把这些基线模型的原来都熟悉一下。当然它们的实现是很简单的,直接调用就可以(虽然我没有去做),但这样也不麻烦,建议大家实现一下。我这里贴一下源码里边基线模型的部分。

# sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights=’uniform’)
KNN = KNeighborsClassifier(n_neighbors = 3)# 查询使用邻居数为3,其余默认值
NB = GaussianNB() # 计算条件概率
# sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto')
# 惩罚参数C默认1,kernel核函数,degree多项式函数的维度,默认3,gamma核系数
SVM = svm.SVC()
# sklearn.linear_model.LogisticRegression(penalty=’l2’,C=1.0)
# C为惩罚系数,为0.01
LR = linear_model.LogisticRegression(C = 0.01)
# n_estimators为随机森林中树的个数,即学习器的个数,n_jobs并行使用的进程数,-1则为总的核数
RF = ensemble.RandomForestClassifier(n_estimators = 5, n_jobs = -1)
# n_estimators为学习器的最大迭代次数,或者最大的学习器的个数;决策树最大深度,最大叶子节点数
GBT = ensemble.GradientBoostingClassifier(n_estimators = 5, max_leaf_nodes = 3, max_depth = 3)

因为不懂所以我做了函数说明,怎么样我是不是很敬业!!

是不是实现简单,大家可以去试一下的。

4、评价标准

原文用了AUPR,MCC和F1分数等评价标准,你需要懂这些都代表什么,为什么要用它们。

据我了解,主要是为了防止数据变化(正负实例分布)导致的一般的评价参数,比如一堆的正确率准确率召回率TC啊FC啊我不懂的东西,这些都会不妥当,所以用了这三个标准。

大家应该了解一下它们,还要ROC曲线,也要了解一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值