实现人工神经网络ANN对医疗数据分类

本文介绍了使用人工神经网络(ANN)对医疗数据进行分类的方法。通过构建三层神经网络,解决医疗数据线性不可分的问题,以提高诊断准确性。讨论了逻辑回归的局限性,并展示了ANN模型的建立过程,包括数据准备、模型构建、参数学习和Python实现。同时,分析了隐层节点数对模型性能的影响,指出过度拟合的风险,并提出通过调整隐层数量以找到最佳模型。
摘要由CSDN通过智能技术生成

2.3 使用ANN对医疗数据分类

IBM在2015年5月宣布推出Watson Health服务,收集健康数据交给Watson超级计算机进行分析。目前IBM Waston Health最主要的应用便是在癌症的诊疗上,通过对医学影像的分析和学习,帮助医生做出对癌症患者的精准诊断。另外一方面,在每一个国家的医疗资源都是十分稀缺的,如何提高基层医生的诊疗水平显得至关重要。我们并不需要智能诊疗会取代医生,因为医疗也并不是简单的诊断,医生更重要的价值还在于对诊断结果的解释、说明和信用背书,但让智能诊疗系统辅助医生诊断,则无疑会大大提高普通医生的诊断水平和诊断效率,降低误诊率。

因此,人工智能对于辅助医生的工作来说,越显得非常重要。例如:医生可以根据人工智能给出女性最佳生育期的建议,不再仅仅基于她们的年龄,而是基于一系列相关的个人身体指标。

以现代医疗检测报告为例,很多时候我们去医院抽血、检查细胞病变等检查之后,检查室开出一张看不懂的表格如图2.3.1,上面有白细胞、链球菌、血小板的参数,医生通过检查这些参数值得大小和变化,可以预测判断该病人是否患有某种病原体。

下面我们将把类似的医疗数据作为背景:首先给出对的医疗检测数据进行数学模型的转换,然后通过构建一个三层的人工神经网络ANN对已有的医疗数据进行训练, 得到该医疗数据的分类模型,然后对新的数据进行预测其所属分类,因为人工神经网络的隐层对数据的分类存在较大影响,因此最后探讨隐层的神经元节点数对实际的数据有如何的影响。

这里写图片描述

2.3.1 准备数据:从医疗数据到数学模型

假设本次血液检测项目只有链球菌x1和葡萄球菌x2两种,对于不同的球菌组合,会出现不同的病原体(不同的病症)。假设有两个分类,分别是病原体I和病原体II,病原体I、病原体II分别用用蓝色、红色表达;x轴表示链球菌的值,y轴表示葡萄球菌的值。在本例程这里的数据已经归一化处理过后,因此数据的分布集中在[-2, 2]之间(想要了解更多关于归一化操作请参考机器学习实践[1])。

我们的目标是通过训练一个三层的人工神经网络ANN模型,对给出不同血液检测项目(x1、x2)的数据进行分类。值得注意的是,因为很多时候医疗数据是线性不可分的,因此我们并不能够简单地使用一条直线对数据进行划分。这意味着不能够用线性分类器来分类,例如Logistic分类器、贝叶斯分类器等,否则分类的数据精度和回召率过低,会对真实的医疗诊断结果造成巨大的影响。

使用神经网络的好处就是不需要去担心特征工程问题,隐层会自动地去寻找特征。

from sklearn import linear_model
from sklearn import datasets
import sklearn
import numpy as np
import matplotlib.pyplot as plt
# 在notebook内显示plt图
%matplotlib inline
def plot_decision_boundary(pred_func, data, labels):
    '''绘制分类边界图'''
    # 设置最大值和最小值并增加0.5的边界(0.5 padding)
    x_min, x_max = data[:, 0].min() - 0.5, data[:, 0].max() + 0.5
    y_min, y_max = data[:, 1].min() - 0.5, data[:, 1].max() + 0.5
    h = 0.01

    # 生成一个点阵网格,点阵间距离为h
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    # 预测整个网格当中的函数值
    z = pred_func(np.c_[xx.ravel(), yy.ravel()])
    z = z.reshape(xx.shape)

    # 绘制轮廓和训练样本
    plt.contourf(xx, yy, z, cmap=plt.cm.Spectral)
    plt.scatter(data[:, 0], data[:, 1], s=40, c=labels, cmap=plt.cm.Spectral)
np.random.seed(0)
X, y = datasets.make_moons(300, noise=0.25)  # 300个数据点,噪声设定0.3
plt.scatter(X[:,0], X[:,1], s = 50,  c = y, cmap=plt.cm.Spectral, edgecolors="Black")
plt.title('Data Example')
plt.show()

这里写图片描述

逻辑回归结果

下图显示了我们逻辑回归分类器的分类结果,逻辑回归算法直接用直线将数据分隔开两类,明显这样的分类结果是远远不能满足真实情况的。

# 使用scikit-learn的线性回归分类器
clf = sklearn.linear_model.LogisticRegressionCV() 
clf.fit(X, y)

# 显示分类结果
plot_decision_boundary(lambda x: clf.predict(x), X, y)
plt.title("Logistic Regression")
<matplotlib.text.Text at 0x10d0de190>

这里写图片描述

2.3.2 建立人工神经网络模型

为了解决现实情况更多线性不可分的数据,我们需要建立一个三层神经网络,输入层、隐层、输出层。

其中输入层(第一层)中的神经节点数目由输入数据的维数决定,例子有链球菌x1和葡萄球菌x2,因此数据维度是2,输入有两个神经元节点。同理,输出层(第三层)中的节点数目由我们的分类数决定,例子里为病原体I(0)和病原体II(1),因此输出层有两个神经元。该神经网络如图2.3.4所示。

这里写图片描述

根据实际情况我们可以增加隐层数和每一隐层的节点数,当隐层越多、隐层节点越多,能够处理更加复杂数据模型,但是伴随着是更大的开销:

1.更多隐层意味着我们的网络模型越大,引入更多的权值参数,占用更多GPU显存;

2.参数数量越多,数据过度拟合的可能性就越大,网络就有可能不稳定,预测效果反而下降;

那么如何选择适当的隐层数呢?每层隐藏层的神经元数应该设置多少呢?这是一个工程问题,不同的数据会有不一样的结果,所以作者觉得神经网络的设计是一种工程艺术,我们需要去尝试、训练、预测、评估,才能最终决定整个网络模型的形态,感受深度学习的魅力所在。

在隐层我们需要一个激活函数,激活函数把输出层转换成为下一层的输入层。非线性的激活函数能够让我们去处理非线性的问题。常用的有tanh函数、sigmoid函数或者ReLUs函数。例子里我们选择使用tanh函数,你也可以尝试把tanh函数换成其他函数查看输出。

最后通过softmax分类器把激活函数的输出分数转换成为概率。

Softmax分类器

预测网络

人工神经网络的预测使用向前反馈操作,我们可以理解为激活函数和矩阵乘法的操作。假设输入x是二维,我们可以根据计算公式得到输出分类结果 ŷ 

z1=xW1+b1

a1=tanh(Z1)

z2=a1W2+b2

a2=ŷ =so

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值