生物学角度来源
1.siRNA与mRNA的互补方式不同,因此沉默机制不同
siRNA的反义链与target gene的匹配程度与匹配位置,是影响因素
2.GC氢键与AU氢键能量不同,因此GC含量决定了特异性结合的难易,片段中特定位置的GC含量是影响因素
3.碱基修饰
编码链在化学性质上产生差异,对于siRNA的精确修饰可以提高沉默效率、特异性和稳定性,并且可以减少毒性和免疫原性
代码刻画
引入长度、GC含量
def siRNA_feat_builder3(s: pd.Series, anti: bool = False):
name = "anti" if anti else "sense"
df = s.to_frame()
# 长度分组
df[f"feat_siRNA_{name}_len21"] = (s.str.len() == 21)
# 省略号标识以此类推构造特征
...
# GC含量
GC_frac = (s.str.count("G") + s.str.count("C"))/s.str.len()
df[f"feat_siRNA_{name}_GC_in"] = (GC_frac >= 0.36) & (GC_frac <= 0.52)
# 局部GC含量
GC_frac1 = (s.str[1:7].str.count("G") + s.str[1:7].str.count("C"))/s.str[1:7].str.len()
...
df[f"feat_siRNA_{name}_GC_in1"] = GC_frac1
...
return df.iloc[:, 1:]
引入化学修饰的构建
def siRNA_feat_builder3_mod(s: pd.Series, anti: bool = False):
name = "anti" if anti else "sense"
df = s.to_frame()
# 修饰RNA的起始、终止位置单元类别
for pos in [0, -1]:
for c in voc_ls:
...
for pos in [1, -2]:
for c in voc_ls:
...
return df.iloc[:, 1:]
并进行n-gram的词频统计
class GenomicTokenizer:
def __init__(self, ngram=5, stride=2):
# 初始化分词器,设置n-gram长度和步幅
self.ngram = ngram
self.stride = stride
def tokenize(self, t):
# 字符串变list
if isinstance(t, str):
t = list(t)
if self.ngram == 1:
# 如果n-gram长度为1,直接将序列转换为字符列表
toks = t
else:
# 否则,按照步幅对序列进行n-gram分词
toks = [t[i:i+self.ngram] for i in range(0, len(t), self.stride) if len(t[i:i+self.ngram]) == self.ngram]
# 如果最后一个分词长度小于n-gram,移除最后一个分词
if len(toks[-1]) < self.ngram:
toks = toks[:-1]
# sub list to str
toks = [''.join(x) for x in toks]
# 返回分词结果
return toks
class GenomicVocab:
def __init__(self, itos):
# 初始化词汇表,itos是一个词汇表列表
self.itos = itos
# 创建从词汇到索引的映射
self.stoi = {v: k for k, v in enumerate(self.itos)}
@classmethod
def create(cls, tokens, max_vocab, min_freq):
# 创建词汇表类方法
# 统计每个token出现的频率
freq = Counter(tokens)
# 选择出现频率大于等于min_freq的token,并且最多保留max_vocab个token
# itos = ['<pad>'] + [o for o, c in freq.most_common(max_vocab - 1) if c >= min_freq]
itos = [o for o, c in freq.most_common(max_vocab - 1) if c >= min_freq]
# 返回包含词汇表的类实例
return cls(itos)
def siRNA_feat_builder_substr(se, name, patterns):
# 创建一个空字典来存储特征
features = {}
for pattern in patterns:
try:
# escaped_pattern = re.escape(pattern) # 转义模式中的特殊字符
escaped_pattern = pattern
features[f"feat_{name}_seq_pattern_{escaped_pattern}"] = se.str.count(escaped_pattern)
except re.error as e:
print(f"Error in pattern {pattern}: {e}")
# 将字典转换为DataFrame
feature_df = pd.DataFrame(features)
return feature_df
# 处理序列特征
seq_features_df = pd.DataFrame()
tokenizer1 = GenomicTokenizer(ngram=1, stride=1) # 1gram
tokenizer2 = GenomicTokenizer(ngram=2, stride=1) # 2gram
tokenizer3 = GenomicTokenizer(ngram=3, stride=1) # 3gram
# 子串词频统计,未修饰序列
cols_nomod = ["siRNA_sense_seq", "siRNA_antisense_seq"]
all_tokens_nomod = []
for col in cols_nomod:
for seq in df[col]:
if pd.isna(seq):
continue
...
print('#all_tokens_nomod: ', len(all_tokens_nomod))
vocab_nomod = GenomicVocab.create(all_tokens_nomod, max_vocab=100000, min_freq=1)
print('#vocab_nomod: ', len(vocab_nomod.itos))
for col in cols_nomod:
...
# 子串词频统计,修饰序列
cols_mod = ["modified_siRNA_sense_seq", "modified_siRNA_antisense_seq"]
cols_mod_ls = ["modified_siRNA_sense_seq_list", "modified_siRNA_antisense_seq_list"]
all_tokens_mod = []
for col in cols_mod_ls:
for seq_ls in df[col]:
if pd.isna(seq_ls):
continue
...
print('#all_tokens_mod: ', len(all_tokens_mod))
vocab_mod = GenomicVocab.create(all_tokens_mod, max_vocab=100000, min_freq=1)
print('#vocab_mod: ', len(vocab_mod.itos))
for col in cols_mod:
...
同时,可以使用siRNA与target序列的结合能力进行对比评分
def get_feat_align(df, anti: bool = False):
# 提示:https://biopython.org/docs/1.76/api/Bio.pairwise2.html
# 使用pairwise2.align.localxx
...
思路
当前模型继续优化
改进损失函数
自适应学习率
多折交叉训练
贝叶斯优化
随机搜索
网格搜索
集成学习
混合学习
新模型构建
代码来源:Datawhale AI夏令营 模型训练的代码脚本文件