当前位置:   article > 正文

从医疗数据到数学模型_医疗行为数字模型

医疗行为数字模型

本次血液检测项目只有链球菌x1和葡萄球菌x2两种,身体血液中对于不同的球菌组合会呈现不同的病原体(不同的病症)。现在假设有两个分类,分别是病原体I和病原体2,x轴表示链球菌的值,y轴表示葡萄球菌的值、在对本例中的数据归一化处理后,数据的分布集中在【-2,2】之间。
我们的目标是通过训练一个3层的人工神经网络ANN模型(输入层、隐层、输出层),对给出不同血液检测项目(x1,x2)的数据进行分类判别该血液检测结果是属于病原体1还是2.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from joblib.numpy_pickle_utils import xrange
from sklearn import linear_model
from sklearn import datasets
import sklearn
import numpy as np
import matplotlib.pyplot as plt

# plt.scatter(data[:, 0], data[:, 1], s=50, c=labels,
#             cmap=plt.cm.Spectral, edgecolors="#313131")


class Config:
    input_dim = 2  # 输入的维度
    output_dim = 2  # 输出的分类数

    epsilon = 0.01  # 梯度下降学习速度
    reg_lambda = 0.01  # 正则化强度


def generate_data():
    np.random.seed(0)
    X, y = datasets.make_moons(200, noise=0.20)  # 300个数据点,噪声设定0.3
    return X, y


def display_model(model):
    print("W1 {}: \n{}\n".format(model['W1'].shape, model['W1']))
    print("b1 {}: \n{}\n".format(model['b1'].shape, model['b1']))
    print("W2 {}: \n{}\n".format(model['W2'].shape, model['W2']))
    print("b1 {}: \n{}\n".format(model['b2'].shape, model['b2']))


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)
    plt.show()


def calculate_loss(model, X, y):
    '''
    损失函数
    '''
    num_examples = len(X)  # 训练集大小
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # 正向传播计算预测值
    z1 = X.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    # 计算损失值
    corect_logprobs = -np.log(probs[range(num_examples), y])
    data_loss = np.sum(corect_logprobs)
    # 对损失值进行归一化(可以不加)
    data_loss += Config.reg_lambda / 2 * \
        (np.sum(np.square(W1)) + np.sum(np.square(W2)))
    return 1. / num_examples * data_loss


def predict(model, x):
    '''
    预测函数
    '''
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # 向前传播
    z1 = x.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    return np.argmax(probs, axis=1)


def ANN_model(X, y, nn_hdim, num_passes=20000, print_loss=False):
    '''
    网络学习函数,并返回网络
    - nn_hdim: 隐层的神经元节点(隐层的数目)
    - num_passes: 梯度下降迭代次数
    - print_loss: 是否显示损失函数值
    '''
    num_examples = len(X)  # 训练的数据集
    model = {}  # 模型存储定义

    # 随机初始化参数
    np.random.seed(0)
    W1 = np.random.randn(Config.input_dim, nn_hdim) / np.sqrt(Config.input_dim)
    b1 = np.zeros((1, nn_hdim))
    W2 = np.random.randn(nn_hdim, Config.output_dim) / np.sqrt(nn_hdim)
    b2 = np.zeros((1, Config.output_dim))
    # display_model({'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2})

    # 批量梯度下降
    for i in xrange(0, num_passes + 1):
        # 向前传播
        z1 = X.dot(W1) + b1  # M_200*2 .* M_2*3 --> M_200*3
        a1 = np.tanh(z1)
        z2 = a1.dot(W2) + b2  # M_200*3 .* M_3*2 --> M_200*2
        exp_scores = np.exp(z2)
        probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)

        # 向后传播
        delta3 = probs  # 得到的预测值
        delta3[range(num_examples), y] -= 1  # 预测值减去实际值
        delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
        dW2 = (a1.T).dot(delta3)  # W2的导数
        db2 = np.sum(delta3, axis=0, keepdims=True)  # b2的导数
        dW1 = np.dot(X.T, delta2)  # W1的导数
        db1 = np.sum(delta2, axis=0)  # b1的导数

        # 添加正则化项
        dW1 += Config.reg_lambda * W1
        dW2 += Config.reg_lambda * W2

        # 根据梯度下降值更新权重
        W1 += -Config.epsilon * dW1
        b1 += -Config.epsilon * db1
        W2 += -Config.epsilon * dW2
        b2 += -Config.epsilon * db2

        # 把新的参数加入模型当中
        model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}

        if print_loss and i % 1000 == 0:
            print("Loss after iteration %i: %f" %
                  (i, calculate_loss(model, X, y)))

    return model


def main():
    X, y = generate_data()
    model = ANN_model(X, y, 3, print_loss=True)  # 建立三个神经元的隐层
    print(display_model(model))

    plot_decision_boundary(lambda x: predict(model, x), X, y)
    plt.title("Logistic Regression")

if __name__ == '__main__':
    main()
  • 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
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

在这里插入图片描述
结果如上图所示

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号