使用 Python 编写 DNN 神经网络预测患者患病状态 - 基于基因表达量数据
由于数据量较小,基因表达量的值也相对较小,我们选择使用较小的神经网络来进行训练。同时,由于数据没有测试集,我们需要使用交叉验证的方式来测试模型的性能。/n/n首先,我们需要读取 Excel 表格中的数据。可以使用 pandas 库来读取 Excel 文件。/n/npython/nimport pandas as pd/n/ndata = pd.read_excel('C://Users//lenovo//Desktop//HIV//DNN神经网络测试//data1.xlsx')/n/n/n接着,我们需要将数据分成输入和输出两个部分。其中,第一列为输出,其余列为输入。/n/npython/nimport numpy as np/n/nX = data.values[:, 1:].astype(np.float32)/ny = data.values[:, 0].astype(np.int64)/n/n/n由于我们需要使用交叉验证,我们可以使用 sklearn 库中的 StratifiedKFold 来进行分割数据集。/n/npython/nfrom sklearn.model_selection import StratifiedKFold/n/nkfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)/n/n/n接下来,我们需要定义神经网络模型。我们选择使用 PyTorch 框架来定义模型。/n/npython/nimport torch/nimport torch.nn as nn/nimport torch.nn.functional as F/n/nclass DNN(nn.Module):/n def __init__(self, n_input, n_hidden, n_output):/n super(DNN, self).__init__()/n self.fc1 = nn.Linear(n_input, n_hidden)/n self.fc2 = nn.Linear(n_hidden, n_hidden)/n self.fc3 = nn.Linear(n_hidden, n_hidden)/n self.fc4 = nn.Linear(n_hidden, n_output)/n self.attention = nn.Linear(n_hidden, 1)/n/n def forward(self, x):/n x = F.relu(self.fc1(x))/n x = F.relu(self.fc2(x))/n x = F.relu(self.fc3(x))/n a = F.softmax(self.attention(x), dim=0)/n x = x * a/n x = self.fc4(x)/n return x/n/n/n我们定义了一个具有三个隐藏层的神经网络模型,其中每个隐藏层的输出都使用 ReLU 函数进行激活,最后一层输出使用 sigmoid 函数进行激活。同时,我们加入了注意力机制,即使用一个线性层来计算每个神经元的注意力,然后将注意力作为权重来计算每个神经元输出的加权和。/n/n接下来,我们需要使用贝叶斯优化来确定最优参数。我们可以使用 skopt 库来实现贝叶斯优化。/n/npython/nfrom skopt import gp_minimize/nfrom skopt.space import Real, Integer/nfrom skopt.utils import use_named_args/nfrom skopt.callbacks import CheckpointSaver, VerboseCallback/n/n# 定义参数空间/nspace = [Real(1e-5, 1e-1, name='lr'),/n Integer(32, 128, name='n_hidden'),/n Real(0.0, 0.9, name='dropout'),/n Real(1e-5, 1e-1, name='weight_decay')]/n/n# 定义模型训练函数/ndef train_model(params):/n lr, n_hidden, dropout, weight_decay = params/n/n accs = []/n losses = []/n/n for train_idx, valid_idx in kfold.split(X, y):/n # 将数据分成训练集和验证集/n X_train, y_train = X[train_idx], y[train_idx]/n X_valid, y_valid = X[valid_idx], y[valid_idx]/n/n # 将数据转换成 Tensor/n X_train = torch.from_numpy(X_train)/n y_train = torch.from_numpy(y_train)/n X_valid = torch.from_numpy(X_valid)/n y_valid = torch.from_numpy(y_valid)/n/n # 定义模型/n model = DNN(n_input=X.shape[1], n_hidden=n_hidden, n_output=2)/n/n # 定义损失函数和优化器/n criterion = nn.CrossEntropyLoss()/n optimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)/n/n # 训练模型/n for epoch in range(100):/n # 训练模型/n model.train()/n optimizer.zero_grad()/n y_pred = model(X_train)/n loss = criterion(y_pred, y_train)/n loss.backward()/n optimizer.step()/n/n # 计算准确率和损失值/n model.eval()/n y_pred = model(X_valid)/n acc = (y_pred.argmax(dim=1) == y_valid).float().mean()/n accs.append(acc)/n losses.append(loss.item())/n/n return -np.mean(accs)/n/n# 进行贝叶斯优化/ncheckpoint_saver = CheckpointSaver(/'./checkpoint.pkl/')/nresult = gp_minimize(train_model, space, n_calls=50, callback=[checkpoint_saver, VerboseCallback()])/nprint(/'Best params:/', result.x)/nprint(/'Best accuracy:/', -result.fun)/n/n/n我们定义了一个 train_model 函数,用于训练模型并返回准确率的负平均值。然后,我们使用 gp_minimize 函数进行贝叶斯优化,其中 n_calls 指定了优化的次数。我们还可以使用 CheckpointSaver 和 VerboseCallback 来保存训练过程中的数据和输出结果。/n/n接下来,我们可以绘制最优参数的准确率变化的图和损失变化的图。/n/npython/nimport matplotlib.pyplot as plt/n/nplt.plot(losses)/nplt.title(/'Loss/')/nplt.xlabel(/'Iteration/')/nplt.ylabel(/'Loss/')/nplt.show()/n/nplt.plot(accs)/nplt.title(/'Accuracy/')/nplt.xlabel(/'Iteration/')/nplt.ylabel(/'Accuracy/')/nplt.show()/n/n/n最后,我们可以使用最优参数训练模型,并绘制 ROC 图。/n/npython/nfrom sklearn.metrics import roc_curve, auc/nfrom scipy import interp/n/nlr, n_hidden, dropout, weight_decay = result.x/n/nfpr = []/ntpr = []/nroc_auc = []/nmean_fpr = np.linspace(0, 1, 100)/n/nfor train_idx, valid_idx in kfold.split(X, y):/n # 将数据分成训练集和验证集/n X_train, y_train = X[train_idx], y[train_idx]/n X_valid, y_valid = X[valid_idx], y[valid_idx]/n/n # 将数据转换成 Tensor/n X_train = torch.from_numpy(X_train)/n y_train = torch.from_numpy(y_train)/n X_valid = torch.from_numpy(X_valid)/n y_valid = torch.from_numpy(y_valid)/n/n # 定义模型/n model = DNN(n_input=X.shape[1], n_hidden=n_hidden, n_output=2)/n/n # 定义损失函数和优化器/n criterion = nn.CrossEntropyLoss()/n optimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)/n/n # 训练模型/n for epoch in range(100):/n # 训练模型/n model.train()/n optimizer.zero_grad()/n y_pred = model(X_train)/n loss = criterion(y_pred, y_train)/n loss.backward()/n optimizer.step()/n/n # 计算准确率和损失值/n model.eval()/n y_pred = model(X_valid)/n acc = (y_pred.argmax(dim=1) == y_valid).float().mean()/n/n # 计算 ROC 曲线/n fpr_, tpr_, _ = roc_curve(y_valid.numpy(), y_pred[:, 1].detach().numpy())/n fpr.append(interp(mean_fpr, fpr_, tpr_))/n tpr.append(tpr_)/n roc_auc.append(auc(fpr_, tpr_))/n/n# 绘制 ROC 曲线/nmean_tpr = np.mean(tpr, axis=0)/nmean_auc = auc(mean_fpr, mean_tpr)/nstd_auc = np.std(roc_auc)/nplt.plot(mean_fpr, mean_tpr, color='b', label=r'Mean ROC (AUC = %0.2f $/pm$ %0.2f)' % (mean_auc, std_auc), lw=2, alpha=.8)/nplt.fill_between(mean_fpr, mean_tpr - std_auc, mean_tpr + std_auc, color='gray', alpha=.2)/nplt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r', alpha=.8)/nplt.xlim([-0.05, 1.05])/nplt.ylim([-0.05, 1.05])/nplt.xlabel('False Positive Rate')/nplt.ylabel('True Positive Rate')/nplt.title('Receiver operating characteristic')/nplt.legend(loc=/'lower right/')/nplt.show()/n
原文地址: https://www.cveoy.top/t/topic/ndgt 著作权归作者所有。请勿转载和采集!