Ai for science

赛题背景:

不同于只提供了时间上的度量传统的日历年龄,基于甲基化数据的生物学年龄能更好的应用于药物研发,疾病预防与治疗。因此基于甲基化数据预测生物学年龄很重要。

本体是属于回归问题。是机器学习用来预测一个连续变量的数值的问题。

代码理解:

配置环境:

本次实践是基于阿里天池的云端环境。能提供快速的算力

导入模块:

NumPy库用于进行对数组的计算与操作,是基本的库。

数据探索:

start_mem = df.memory_usage().sum() / 1024**2    

计算初始内存以便于对内存优化分析。

 if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)  

首先根据数据的范围对其的数据类型进行转换,以减小内存。

path = 'ai4bio'

traindata = pd.read_csv(f'{path}/traindata.csv', nrows=20000)
trainmap = pd.read_csv(f'{path}/trainmap.csv')

testdata = pd.read_csv(f'{path}/ai4bio_testset_final/testdata.csv', nrows=20000)
testmap = pd.read_csv(f'{path}/ai4bio_testset_final/testmap.csv')

根据内存选取适量的数据。

traindata = traindata.set_index('cpgsite')
traindata = traindata.T
traindata = traindata.reset_index()
traindata = traindata.rename(columns={'index':'sample_id'})
traindata.columns = ['sample_id'] + [i for i in range(20000)]
traindata.to_pickle(f'{path}/traindata.pkl')

因为原本数据为每一列代表一个样本,需要转置调整为每一行为一个样本;同时将index改为sample_id,并将标上特征id

pickle文件:是一种用于序列化(将对象转换成字节流)和反序列化(将字节流转换回对象)Python对象的文件格式。pickle模块允许我们将Python对象保存到磁盘上,并在需要时重新加载它们,同时保留对象的结构和数据。pickle文件通常用于存储和传输数据,特别是在机器学习和深度学习领域中,它常用于保存训练好的模型。

traindata = traindata.merge(trainmap[['sample_id', 'age', 'gender', 'sample_type', 'disease']],on='sample_id',how='left')
testdata = testdata.merge(testmap[['sample_id', 'gender']],on='sample_id',how='left')

将data数据与map数据合并,并添加新的列。

算出数据缺失率,并算出特征的相关性分数。

数据清洗:

数据清洗是指在数据分析和数据挖掘过程中,对原始数据进行筛选、转换和整理的过程。它的目的是去除无效或冗余的数据、修复缺失或错误的数据,并对数据进行统一格式的调整,以确保数据的质量和一致性。数据清洗可以包括去除重复数据、处理缺失值、纠正错误数据、转换数据类型、处理异常值等操作,以便为后续的数据分析和建模提供准确、可靠的数据基础。

disease_mapping = {
    'control': 0,
    "Alzheimer's disease": 1,
    "Graves' disease": 2,
    "Huntington's disease": 3,
    "Parkinson's disease": 4,
    'rheumatoid arthritis': 5,
    'schizophrenia': 6,
    "Sjogren's syndrome": 7,
    'stroke': 8,
    'type 2 diabetes': 9
}
sample_type_mapping = {'control': 0, 'disease tissue': 1}
gender_mapping = {'F': 0, 'M': 1}

traindata['disease'] = traindata['disease'].map(disease_mapping)
traindata['sample_type'] = traindata['sample_type'].map(sample_type_mapping)
traindata['gender'] = traindata['gender'].map(gender_mapping)

testdata['gender'] = testdata['gender'].map(gender_mapping)

用字典将疾病名称映射为对应的数值,以用于编码训练模型。

特征工程:

其目的是获取更好的训练数据特征。

traindata['max'] = traindata[[i for i in range(60000)]].max(axis=1)
traindata['min'] = traindata[[i for i in range(60000)]].min(axis=1)
traindata['std'] = traindata[[i for i in range(60000)]].std(axis=1)
traindata['var'] = traindata[[i for i in range(60000)]].var(axis=1)
traindata['skew'] = traindata[[i for i in range(60000)]].skew(axis=1)
traindata['mean'] = traindata[[i for i in range(60000)]].mean(axis=1)
traindata['median'] = traindata[[i for i in range(60000)]].median(axis=1)

testdata['max'] = testdata[[i for i in range(60000)]].max(axis=1)
testdata['min'] = testdata[[i for i in range(60000)]].min(axis=1)
testdata['std'] = testdata[[i for i in range(60000)]].std(axis=1)
testdata['var'] = testdata[[i for i in range(60000)]].var(axis=1)
testdata['skew'] = testdata[[i for i in range(60000)]].skew(axis=1)
testdata['mean'] = testdata[[i for i in range(60000)]].mean(axis=1)
testdata['median'] = testdata[[i for i in range(60000)]].median(axis=1)

构建了一些统计特征。

cols = [i for i in range(60000)] + ['gender','max','min','std','var','skew','mean','median']

创建特征。

本数据原始字段特征以连续型数值为主,可以按行进行聚合统计操作,如构建max、min、mean、std、skew等常见的数值统计特征。观察数据集的特征和分布情况。

最后选出合适的特征。

训练验证:

验证方法:K折交叉验证方法。k-fold交叉验证方法是一种常用的模型评估技术。它将数据集分成k个相等的子集,称为folds。然后,我们使用k-1个fold作为训练集来训练模型,并使用剩下的1个fold作为验证集来评估模型的性能。这个过程会k次重复,每次选择不同的验证集。 最后,我们将k次评估的结果综合起来,得到模型在整个数据集上的性能评估指标,通常是平均值或中位数。这种方法有助于减少过拟合风险,可以更客观地评估模型的性能。

学习率,控制模型参数更新的速度。值越大,模型更新越快,但可能陷入局部最优解;值越小,模型更新越慢,但可能收敛到更好的解。

树的深度,即决策树的最大层数。树的深度越深,模型的复杂度越高,可能导致过拟合;树的深度越浅,模型的复杂度越低,可能导致欠拟合。

特征优化:

PCA主成分析降维:原理:依据原来的特征分布图,得出最优拟合线,算出每个特征的差异值,差异值为每一个特征下每个样本距离中心的垂直距离,距离的平方和除上n-1,得出差异值最大的几个特征,将该特征下样本距离中心的垂直距离作为新的特征值。

LDA降维:主要思想:LDA算法的思想是将数据投影到低维空间之后,使得同一类数据尽可能的紧凑,不同类的数据尽可能分散。且使用于原始数据根据样本均值进行分类以及 不同类的数据拥有相同的协方差矩阵。特点:降维之后的维数最多为类别数-1。所以当数据维度很高,但是类别数少的时候,算法并不适用。

    if testdata[col].nunique()==1: # 属性值唯一
        drop_cols.append(col)

如果属性值唯一,那么对模型无用。

    if testdata[col].isnull().sum() / test_df.shape[0] > 0.95: # 缺失率大于0.95
        drop_cols.append(col)

如果缺失率大于0.95,那么删去该属性。

def correlation(data, threshold):
    col_corr = []
    corr_matrix = data.corr()
    for i in range(len(corr_matrix)):
        for j in range(i):
            if abs(corr_matrix.iloc[i,j]) > threshold: # 相关性大于0.98
                colname = corr_matrix.columns[i]
                col_corr.append(colname)
    return list(set(col_corr))

如果相关性大于0.98那么去掉其中一个属性。

模型创建:

def catboost_model(train_x, train_y, test_x, seed = 2023):
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    oof = np.zeros(train_x.shape[0])
    test_predict = np.zeros(test_x.shape[0])
    cv_scores = []
    
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
        
        params = {'learning_rate': 0.3, 'depth': 5, 'bootstrap_type':'Bernoulli','random_seed':2023,
                  'od_type': 'Iter', 'od_wait': 100, 'random_seed': 11, 'allow_writing_files': False}

        model = CatBoostRegressor(iterations=2000, **params)
        model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                  metric_period=500,
                  use_best_model=True, 
                  cat_features=[],
                  verbose=1)

        val_pred  = model.predict(val_x)
        test_pred = model.predict(test_x)
        
        oof[valid_index] = val_pred
        test_predict += test_pred / kf.n_splits
        
        score = mean_absolute_error(val_y, val_pred)
        cv_scores.append(score)
        print(cv_scores)
        
        # 获取特征重要性打分,便于评估特征
        if i == 0:
            fea_ = model.feature_importances_
            fea_name = model.feature_names_
            fea_score = pd.DataFrame({'fea_name':fea_name, 'score':fea_})
            fea_score = fea_score.sort_values('score', ascending=False)
            fea_score.to_csv('feature_importances.csv', index=False)
        
    return oof, test_predict

将数据集划分为5个折叠,然后创建KFold对象,用于交叉验证,然后创建一个大小与训练集样本数相同的零数组,用于保存交叉验证中的预测结果。创建一个大小与测试集样本数相同的零数组,用于保存最终预测结果。创建一个空列表,用于保存每个交叉验证折叠的得分。

计算机科学的写作是指以计算机科学为主题的写作领域。计算机科学是一个广泛的学科,涵盖了各种主题和议题,包括算法,数据结构,编程语言,人工智能,网络技术等等。在计算机科学领域进行写作可以帮助人们更好地理解和传达关于技术的知识和概念。 计算机科学的写作可以分为两个主要方面:学术写作和技术写作。 在学术写作方面,计算机科学的学术论文是最常见的形式。这些论文通常包括研究报告,实验结果,算法设计和分析等。学术写作要求准确和清晰地描述研究的背景,目的,方法和结果。此外,学术论文还需要引用和参考其他学术资源,以支持研究和结论。学术写作在学术界推广和扩展知识,促进科学研究发展具有重要作用。 技术写作则侧重于向非专业读者传达技术知识。这种写作形式主要用于软件文档,编程指南,操作手册等。技术写作要求使用简明的语言和清晰的结构,以便用户容易理解和应用。此外,技术写作还需要具备解决问题和提供解决方案的能力。 无论是学术写作还是技术写作,计算机科学的写作都需要具备良好的逻辑思维和清晰的表达能力。写作者需要了解读者的背景和知识水平,并以适当的方式发布信息。此外,对于计算机科学的写作,精确性和准确性也是非常重要的因素,以避免误导和错误信息的传播。 总之,计算机科学的写作是一个复杂而多样化的领域,可通过学术和技术写作形式来传播和分享计算机科学的知识和理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值