论文复现笔记

获取到数据集中的每一个ID

首先是测试集:testset.csv
这里测试集是这个样子的:
在这里插入图片描述
我需要根据每一个病毒的accsssion的ID去下载对应的基因文件,首先需要读取到每一个ID号

import os
import pandas as pd
from Bio import Entrez, SeqIO
from urllib.error import HTTPError

#这个函数获取到所有的NCBI id列表
def GetAccssions(CSV_path):
  '''CSV_path:是csv文件的路径
  '''
  df = pd.read_csv(CSV_path)

  #数据集中的accession列的数据转为列表
  accs = df.accession.to_list()

  #存放每一个ID的列表,每一个ID作为一个单独的列表元素
  Accseesions = []

  #accs是包含每一行的列表,不是每一个ID号的列表,进一步处理获取每个ID号的列表
  for acc in accs:
    #acc可以是多个ID号的字符串,中间使用分号;隔开的字符串
    acc_list = acc.split(';')
    #acc_list是每一行数据分割后的列表,再次遍历,去掉左右空格,
    for id in acc_list:
      id = id.strip()
      Accseesions.append(id)
  
  return Accseesions

调用结果:
在这里插入图片描述

根据ID下载gb文件

拿到每一个ID后,需要下载gb文件

from posixpath import exists
def downGb_fromID(Accessions,filePath):
  '''Accessions:是一个一个的id构成的列表,
    filePath:文件的下载路径
  '''
  if not os.path.exists(filePath):
    #执行到这里,目录基本不可能存在
    os.makedirs(filePath)
    #如果exist_ok为False(默认值),则在目标目录已存在的情况下触发FileExistsError异常;如果exist_ok为True,则在目标目录已存在的情况下不会触发FileExistsError异常。
  
  assert os.path.exists(filePath)
  os.chdir(filePath)#切换到下载目录的路径下

  Entrez.tool = "ZoonosisPredictor pipeline - DownloadSequences.py"
  Entrez.email = "xxjxuejian@gmail.com"

    #拿到每一个NC的 ID号
  for ID in Accessions:
    #保存的文件名格式
      FileName = "{}.gb".format(ID)
      #如果文件不存在,刚开始肯定是不存在的,所以会下载
      if not os.path.isfile(FileName):
          try:
            #这是在下载
              QueryHandle = Entrez.efetch(db="nucleotide",id=ID,rettype="gb",retmode="text")
          except HTTPError as Error:
              if Error.code == 400:  # Bad request
                  raise ValueError("Accession number not found: {}".format(Accessions(ID)))
              else:
                  raise
          
          #写入文件
          with open(FileName, 'w') as WriteHandle:
              WriteHandle.write(QueryHandle.read())
          
      else:
          print("{} exists, not updated".format(FileName))

到这里,就完成了所有accession的下载。

这里可以检查下路径下的所有的文件的数量,是不是和Accessions列表的长度一样,确保每一个都进行了下载。

返回每一个ID对应的碱基序列

由于我们需要的是基因的序列,AGCT这样的序列,下面需要根据每一个gb文件获取到序列信息。

这个函数是根据每一个gb文件返回对应的序列,这个序列是经过编码后的序列,之后再解码就行。

from genericpath import isfile
def gb_to_seqStr(gbPath):
  '''gbPath:这个参数是每一个gb文件的路径
  '''

  #拿到路径直接操作
  SeqRec = SeqIO.read(gbPath, format = "genbank")
  # seqStr = SeqRec.seq.encode('ascii')这个方法废弃了
  seqStr = bytes(SeqRec.seq)#默认是UTF-8编码
  #SeqRec.id, SeqRec.name , SeqRec.description 

  return seqStr
  #或者考虑把id,name,seq,构造成一个字典一起返回出去

测试:
在这里插入图片描述
解码:
在这里插入图片描述

构建一个包含序列id,序列字符串等的字典
针对训练集的字典
data_train = pd.read_csv('/content/drive/MyDrive/zoonotic/trainset.csv')
data_test = pd.read_csv('/content/drive/MyDrive/zoonotic/testset.csv')

def trainset_to_dict(datas):
	'''datas参数是读取到的csv对象
	'''
  data_dict = {}
  for row in datas.iterrows():
    series = row[1]
    label = 1

    #首先看是属于哪个类别
    if series['observed_infection_class'] == 'No known human infections':
      label = 0

    accessions = series['accession'].split(';')
    for index,value in enumerate(accessions):
      value = value.strip()
      accessions[index] = value

    #如果大于1,说明有多个id,对每一个id都要构造一个字典
    if len(accessions) == 1:
      #长度就是1 的
      single = {
          'id':accessions[0],
          'species':series['species'],
          'family':series['family'],
          'label':label
      }
      data_dict[accessions[0]] = single
    else:
      #长度大于1的
      for index in range(len(accessions)):
        single = {
            'id':accessions[index],
            'species':series['species'],
            'family':series['family'],
            'label':label
        }
        data_dict[accessions[index]] = single
  return data_dict
针对测试集的字典
def testset_to_dict(datas):
  data_dict = {}
  for row in datas.iterrows():
    series = row[1]

    accessions = series['accession'].split(';')
    #去掉空白符
    for index,value in enumerate(accessions):
      value = value.strip()
      accessions[index] = value

    # print(accessions)
    # print(len(accessions))
    #如果大于1,说明有多个id,对每一个id都要构造一个字典
    if len(accessions) == 1:
      #长度就是1 的
      single = {
          'id':accessions[0],
          'species':series['species'],
          'family':series['family'],
      }
      data_dict[accessions[0]] = single
    else:
      #长度大于1的
      for index in range(len(accessions)):
        single = {
            'id':accessions[index],
            'species':series['species'],
            'family':series['family'],
        }
        data_dict[accessions[index]] = single

  return data_dict
这个字典是这样的:

在这里插入图片描述

字典持久化存储

使用pickle模块把这个字典持久化的存储下来

import pickle
train_path = '/content/drive/MyDrive/zoonotic/Final_trainset.pkl'
with open(train_path,'wb') as f:
  pickle.dump(train_dict,f)
构造tensorflow的输入数据格式

要把碱基序列转为one-hot矩阵,还要把标签也转为one-hot形式,还要注意数据的类型,设计好example

序列转矩阵的函数
import numpy as np
import random
import tensorflow as tf
import inspect
from typing import Any, Callable, Dict, Optional, Text, Union, Iterable
import os
from tensorflow.core.example.feature_pb2 import BytesList
# import sonnet as snt
from tqdm import tqdm
from IPython.display import clear_output
import numpy as np
import pandas as pd
import time
import pickle

#DNA序列转为one-hot编码,可以直接拿来用
def one_hot_encode(sequence: str,
                   alphabet: str = 'ACGT',
                   neutral_alphabet: str = 'N',
                   neutral_value: Any = 0,
                   dtype=np.float32) -> np.ndarray:
  """One-hot encode sequence."""

  def to_uint8(string):
    return np.frombuffer(string.encode('ascii'), dtype=np.uint8)

  hash_table = np.zeros((np.iinfo(np.uint8).max, len(alphabet)), dtype=dtype)
  hash_table[to_uint8(alphabet)] = np.eye(len(alphabet), dtype=dtype)
  hash_table[to_uint8(neutral_alphabet)] = neutral_value
  hash_table = hash_table.astype(dtype)
  return hash_table[to_uint8(sequence)]
长度填充函数
MaxLength = 241087
def pad_to_maxLen(arr):
  '''
  arr:需要填充的ndarray数组
  '''
  length = MaxLength-arr.shape[0]
  arr = np.pad(arr,((0,length),(0,0)),'constant',constant_values=(0))
  return arr
写入tfr文件
#tfr文件的路径
path = '/content/drive/MyDrive/zoonotic/Trainset.tfr'

#train_dict需要提前读取到
with tf.io.TFRecordWriter(path) as writer:
  for k,v in train_dict.items():
    id = bytes(k,encoding='utf-8')
    seq = v['seq'].decode('utf-8')

    #label内的元素类型也转为float32类型
    label = v['label'].astype(np.float32)
    label = label.tobytes()#label也是一个矩阵,需要转为字节

    #字符序列转矩阵
    matrix = one_hot_encode(seq)
    #填充
    matrix = pad_to_maxLen(matrix)

    #转为字节类型
    matrix = matrix.tobytes()
    #写入tfr文件

    feature = {
      #序列使用的是tf.train.BytesList类型
        'id':tf.train.Feature(bytes_list=tf.train.BytesList(value=[id])),
        'sequence':tf.train.Feature(bytes_list=tf.train.BytesList(value=[matrix])),
        #'label':tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))#标签单是一个数字的时候用这个
        'label':tf.train.Feature(bytes_list=tf.train.BytesList(value=[label])),
    }

    example = tf.train.Example(features=tf.train.Features(feature=feature))
    writer.write(example.SerializeToString())
读取tfr文件
#这个相当于是填充用的,占位
feature_description = {
    'id':tf.io.FixedLenFeature((),tf.string),
    "sequence": tf.io.FixedLenFeature((), tf.string),
    "label": tf.io.FixedLenFeature((), tf.string)
}

#将 TFRecord 文件中的每一个序列化的 tf.train.Example 解码
def parse_example(example_string):
  #解析之后得到的example
  example = tf.io.parse_single_example(example_string,feature_description)

  # id = tf.io.decode_raw(example['id'],tf.string)
  id = tf.cast(example['id'],tf.string)

  #example['sequence']还是字节流的形式,重新转为数字向量
  sequence = tf.io.decode_raw(example['sequence'], tf.float32)
  sequence = tf.reshape(sequence,(MaxLength,4))  #形状需要重塑,不然就是一个长向量

  # label = tf.cast(example['label'],tf.int64)  #标签对应的类型转换
  label = tf.io.decode_raw(example['label'], tf.float32)
  label = tf.reshape(label,(1,2))
  
  #把整个字典返回
  return {
      'id':id,
      'sequence':sequence,
      'label': label
  }
dataset = tf.data.TFRecordDataset(path)
dataset = dataset.map(parse_example)
it = iter(dataset)
example = next(it)
example

在这里插入图片描述

数据集的长度

由于需要设计模型的输入长度,还需要知道每一条序列的长度,也就是有多少个碱基。获取每一条序列的长度,然后比较获得最大的序列长度,根据这个长度设计模型的输入长度。

可以把每一条序列的长度都记录下来,然后使用可视化工具,或者画一个箱型图,查看数据的分布情况,设计一个合理的序列长度。

函数gb_to_seqStr()可以返回病毒的序列字符串
返回的是所有序列的长度的列表

def get_lengths(gbfiles):
  '''gbfiles:参数是每一个gb文件的路径
  '''
  #存储每一个序列长度的列表
  lengths = []
  for gb in gbfiles:
    gbStr = gb_to_seqStr(gb)
    length = len(gbStr)
    lengths.append(length)
  
  return lengths

关于箱型图的代码:

import matplotlib.pyplot as plt
import numpy as np
x = lengths
sorted(x)
a = np.quantile(x, 0.75)  # 上四分之一数
b = np.quantile(x, 0.25)  # 下四分之一数
print("平均数:", np.mean(x))  # 打印均值
print("中位数:", np.median(x))  # 打印中位数
print("上四分之一数:", a)  # 打印上四分之一数
print("下四分之一数:", b)  # 打印下四分之一数
up = a + 1.5 * (a - b)  # 异常值判断标准
down = b - 1.5 * (a - b)  # 异常值判断标准
x = np.sort(x)  # 对原始数据排序
shangjie = x[x < up][-1]  # 除了异常值外的最大值
xiajie = x[x > down][0]  # 除了异常值外的最小值
print("上界:", shangjie)  # 打印上界
print("up:", up)
print("down:", down)
print("下界:", xiajie)  # 打印下界
plt.grid(True)  # 显示网格
y = plt.boxplot(x, meanline=True, showmeans=True,
                flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 15})  # 绘制箱形图,设置异常点大小、样式等
plt.show()  # 显示图
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI语言模型,我无法直接为您复现SCI论文,但我可以提供以下有关电力负荷预测的SCI论文及其实现的参考: 1. Li, X., Yang, L., & Zhang, Q. (2017). Short-term load forecasting using extreme learning machine and a hybrid approach. Electric Power Systems Research, 142, 11-20. 该论文采用极限学习机和混合方法进行短期负载预测。极限学习机是一种基于单个隐含层前向反馈神经网络的快速学习算法。混合方法结合了时序分解和回归方法,通过分析负载数据的季节性和趋势性变化来预测负载。 2. Wang, J., Wang, Q., Lu, X., Huang, Z., & Wu, Y. (2016). A new short-term load forecasting method based on extreme learning machine and multi-objective optimization algorithm. Energy, 114, 1141-1149. 该论文提出了一种基于极限学习机和多目标优化算法的新型短期负载预测方法。该方法使用多目标优化算法对模型进行调优,并采用交叉验证和残差分析来验证模型的预测性能。 3. Chen, J., Hong, T., & Pinson, P. (2018). Probabilistic load forecasting using deep learning feed-forward neural networks. IEEE Transactions on Smart Grid, 9(2), 770-779. 该论文采用深度学习前馈神经网络技术进行随机负载预测。该方法将负载数据看作是随机变量,通过训练神经网络来学习每个随机变量的概率分布,从而实现概率负载预测。 4. Akter, M., & Mahmud, M. A. (2019). Electrical load forecasting using artificial neural network and particle swarm optimization: A comparative study. Alexandria Engineering Journal, 58(3), 997-1006. 该论文对比了采用人工神经网络和粒子群优化的电力负载预测方法。研究表明,采用粒子群优化的方法可以提高预测精度,并降低误差率。 以上是一些常见的电力负荷预测SCI论文及其方法介绍,您可以结合自己的研究方向和需求进行选择和参考。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值