Datawhale AI夏令营——第三期siRNA药物预测(三)

数据的特征工程

得分不好的原因:数据特征简单,序列特征构造粗糙,数据量不足——把序列特征问题转化成表格问题的方法,在表格数据上做特征工程。

1、处理类别型变量

判断一个变量是类别型的方法——df处理看值分布或唯一值的个数(nunique/values_counts)

用get_dummie实现独热特征的构造(如果有40类,就会产生40列,若i行属于j类,那么[i][j]就是1,形成一个矩阵)

2、寻找时间特征构造

siRNA_duplex_id的格式的可能解释:AD-1810676.1。AD:某类;1810676:按照一定顺序的序列号;.1:版本号。

siRNA_duplex_id_values = df.siRNA_duplex_id.str.split("-|\.").str[1].astype("int")

先用split分割成三段,然后提取中间段转为int格式。

3、寻找潜在单词

Hepatocytes/cells等

4、根据序列模式提取特征

对碱基的模式进行特征构造

特征工程进阶

从生物学角度提取新特征

1、使用反义链与target gene序列的序列匹配结果作为特征来增强模型表现。我们的目标:mRNA的保留水平,siRNA反义链与target gene的匹配程度,以及匹配位置。

2、GC含量:siRNA 的GC含量,或者⽚段中特定位置的GC含量对其沉默效率至关重要。

3、修饰过的碱基序列。

代码解释

1

def siRNA_feat_builder3(s: pd.Series, anti: bool = False):
    #  siRNA_feat_builder3 是函数的名称。s 是一个 Pandas Series 对象,应该包含 siRNA 序列。anti 是一个布尔值,默认为 False。根据其值,选择命名特征列的前缀为 "anti" 或 "sense"。
    
    #  根据 anti 参数的值,选择前缀名称 "anti" 或 "sense"。将输入的 Series s 转换为 DataFrame df
    name = "anti" if anti else "sense"
df = s.to_frame()

	# 创建一个名为 feat_siRNA_{name}_len21 的新特征列,该列的值为布尔型,表示 siRNA 序列的长度是否为 21。
	df[f"feat_siRNA_{name}_len21"] = (s.str.len() == 21)
    
    # 计算 siRNA 序列中 G 和 C 的组成比例 GC_frac。创建一个名为 feat_siRNA_{name}_GC_in 的新特征列,其值为布尔型,表示 siRNA 序列的 GC 含量是否在 0.36 到 0.52 之间。
    GC_frac = (s.str.count("G") + str.count("C")) / s.str.len()
	df[f"feat_siRNA_{name}_GC_in"] = (GC_frac >= 0.36) & (GC_frac <= 0.52)
    
    #  计算 siRNA 序列中第 2 到第 7 个字符的子序列的 GC 含量比例 GC_frac1。创建一个名为 feat_siRNA_{name}_GC_in1 的新特征列,其值为局部 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:]

2

# 对siRNA特征构建函数siRNA_feat_builder3 的修改版
def siRNA_feat_builder3_mod(s: pd.Series, anti: bool = False):
    
	name = "anti" if anti else "sense"
    df = s.to_frame()
	
    # 通过循环处理修饰RNA序列的起始和终止位置。具体来说,对于序列的开头(pos=0)和结尾(pos=-1),以及次要修饰区域(pos=1和pos=-2),不太理解这里的voc_ls是啥。
	for pos in [0, -1]:
    	for c in voc_ls:
        	...
	for pos in [1, -2]:
    	for c in voc_ls:
        	...
    return df.iloc[:, 1:]

3

class GenomicTokenizer:
    def __init__(self, ngram=5, stride=2):
        self.ngram = ngram  # n-gram 的长度,默认为5
        self.stride = stride  # 步幅,默认为2
    # tokenize 方法接受一个参数 t,用于将输入的字符串或字符列表按照设定的 n-gram 长度和步幅进行分词操作。如果 n-gram 长度为 1,则直接将序列转换为字符列表;否则,按照设定的步幅生成 n-gram 分词结果。
    def tokenize(self, t):
        if isinstance(t, str):
            t = list(t)  # 将输入的字符串转换为字符列表
        
        if self.ngram == 1:
            toks = t  # 如果 n-gram 的长度为1,直接将序列转换为字符列表
        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]
            
            # 将分词结果转换为字符串
            toks = [''.join(x) for x in toks]
        
        return toks

4

class GenomicVocab:
    def __init__(self, itos):
        self.itos = itos  # 词汇表列表
        self.stoi = {v: k for k, v in enumerate(self.itos)}  # 创建从词汇到索引的映射
    
    @classmethod
    def create(cls, tokens, max_vocab, min_freq):
        freq = Counter(tokens)  # 统计每个 token 出现的频率
        itos = [o for o, c in freq.most_common(max_vocab - 1) if c >= min_freq]  # 选择出现频率大于等于 min_freq 的 token,并且最多保留 max_vocab 个 token
        
        return cls(itos)  # 返回包含词汇表的类实例

5

# 接受三个参数 se(序列数据)、name(特征名称前缀)和 patterns(模式列表)。创建一个空字典 features 来存储特征。对于每个模式 pattern,尝试计算序列数据 se 中模式出现的次数,并将结果存储在 features 字典中。最后将 features 字典转换为 Pandas DataFrame feature_df,并返回该 DataFrame。
def siRNA_feat_builder_substr(se, name, patterns):
    features = {}
    for pattern in patterns:
        try:
            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}")
    
    feature_df = pd.DataFrame(features)  # 将字典转换为 DataFrame
    return feature_df

6 处理序列特征

seq_features_df = pd.DataFrame()
tokenizer1 = GenomicTokenizer(ngram=1, stride=1)  # 初始化一个 n-gram 长度为 1 的分词器
tokenizer2 = GenomicTokenizer(ngram=2, stride=1)  # 初始化一个 n-gram 长度为 2 的分词器
tokenizer3 = GenomicTokenizer(ngram=3, stride=1)  # 初始化一个 n-gram 长度为 3 的分词器

7 处理未修饰序列的子串词频统计

cols_nomod = ["siRNA_sense_seq", "siRNA_antisense_seq"]
all_tokens_nomod = []

for col in cols_nomod:
    for seq in df[col]:
        # 如果序列数据为空(NaN),则跳过处理。
        if pd.isna(seq):
            continue
        ...
# 根据 all_tokens_nomod 列表创建词汇表 vocab_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:
    ...

8 用于处理修饰后的基因组序列数据

# 列定义和初始化
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:
    ...

9 siRNA序列与target序列对⽐

# 一脸懵逼呜呜呜
def get_feat_align(df, anti: bool = False):

感觉有点看不下去,一需要自己写代码就完全不会了。哎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值