Python 生物信息学秘籍第三版(四)

Python领域生物信息学的Python实践 本文的主要目的是为生物信息学领域的初学者和有一定基础的开发者提供全面的Python实践指导。涵盖了生物信息学中常见的任务,如DNA和蛋白质序列分析、基因组学数据处理、蛋白质结构预测等。通过具体的代码示例和详细的解释,帮助读者掌握使用Python解决生物信息学问题的方法和技巧。核心概念与联系:介绍生物信息学中的核心概念和它们之间的联系,并通过示意图和流程图进行直观展示。核心算法原理 & 具体操作步骤:详细讲解生物信息学中常用的算法原理,并使用Python代码实现具体的操作步骤。 阅读详情

原文:annas-archive.org/md5/9694cf42f7d741c69225ff1cf52b0efe

译者:飞龙

协议:CC BY-NC-SA 4.0

第十一章:生物信息学中的机器学习

机器学习在许多不同的领域中都有应用,计算生物学也不例外。机器学习在该领域有着无数的应用,最古老且最为人熟知的应用之一就是使用主成分分析(PCA)通过基因组学研究种群结构。随着该领域的蓬勃发展,还有许多其他潜在的应用。在本章中,我们将从生物信息学的角度介绍机器学习的概念。

鉴于机器学习是一个非常复杂的主题,足以填满一本书,在这里我们打算采用直观的方法,让你大致了解一些机器学习技术如何帮助解决生物学问题。如果你发现这些技术有用,你将理解基本概念,并可以进一步阅读更详细的文献。

如果你使用的是 Docker,由于本章中的所有库对于数据分析都是基础库,它们都可以在 Docker 镜像tiagoantao/bioinformatics_ml中找到。

在本章中,我们将覆盖以下配方:

  • 用 PCA 示例介绍 scikit-learn

  • 使用 PCA 聚类来分类样本

  • 使用决策树探索乳腺癌特征

  • 使用随机森林预测乳腺癌结果

用 PCA 示例介绍 scikit-learn

PCA 是一种统计方法,用于将多个变量的维度降低到一个较小的、线性无关的子集。在第六章中,我们已经看过基于使用外部应用程序的 PCA 实现。在这个配方中,我们将为种群遗传学实现相同的 PCA,但将使用scikit-learn库。Scikit-learn 是 Python 中用于机器学习的基础库之一,本配方是对该库的介绍。PCA 是一种无监督的机器学习方法——我们不提供样本的类别信息。我们将在本章的其他配方中讨论有监督的技术。

提醒一下,我们将计算来自 HapMap 项目的 11 个人类种群的 PCA。

准备工作

你需要运行第六章中的第一个配方,以生成hapmap10_auto_noofs_ld_12 PLINK 文件(等位基因记录为 1 和 2)。从种群遗传学的角度来看,我们需要 LD 修剪标记来生成可靠的 PCA。我们这里不使用后代样本,因为它可能会导致结果偏差。我们的配方将需要pygenomics库,可以使用以下命令进行安装:

pip install pygenomics

代码位于Chapter10/PCA.py笔记本中。

如何实现…

看一下以下步骤:

  1. 我们首先加载样本的元数据。在我们的案例中,我们将加载每个样本所属的人类种群:

    import os
    from sklearn.decomposition import PCA
    import numpy as np
    from genomics.popgen.pca import plot
    f = open('../Chapter06/relationships_w_pops_041510.txt')
    ind_pop = {}
    f.readline()  # header
    for l in f:
        toks = l.rstrip().split('\t')
        fam_id = toks[0]
        ind_id = toks[1]
        pop = toks[-1]
        ind_pop['/'.join([fam_id, ind_id])] = pop
    f.close()
    
  2. 我们现在获得了个体的顺序以及我们将要处理的 SNP 数量:

    f = open('../Chapter06/hapmap10_auto_noofs_ld_12.ped')
    ninds = 0
    ind_order = []
    for line in f:
        ninds += 1
        toks = line[:100].replace(' ', '\t').split('\t')
        fam_id = toks[0]
        ind_id = toks[1]
        ind_order.append('%s/%s' % (fam_id, ind_id))
    nsnps = (len(line.replace(' ', '\t').split('\t')) - 6) // 2
    f.close()
    
  3. 我们创建将要输入 PCA 的数组:

    pca_array = np.empty((ninds, nsnps), dtype=int)
    print(pca_array.shape)
    f = open('../Chapter06/hapmap10_auto_noofs_ld_12.ped')
    for ind, line in enumerate(f):
        snps = line.replace(' ', '\t').split('\t')[6:]
        for pos in range(len(snps) // 2):
            a1 = int(snps[2 * pos])
            a2 = int(snps[2 * pos])
            my_code = a1 + a2 - 2
            pca_array[ind, pos] = my_code
    f.close()
    
  4. 最后,我们计算包含最多八个成分的 PCA。然后,使用transform方法获取所有样本的 8 维坐标。

    my_pca = PCA(n_components=8)
    my_pca.fit(pca_array)
    trans = my_pca.transform(pca_array)
    
  5. 最后,我们绘制 PCA 图:

    sc_ind_comp = {}
    for i, ind_pca in enumerate(trans):
        sc_ind_comp[ind_order[i]] = ind_pca
    plot.render_pca_eight(sc_ind_comp, cluster=ind_pop)
    

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_10_01.jpg

图 10.1 - 由 scikit-learn 生成的我们数据集的 PC1 到 PC8

还有更多…

对于科学期刊中的发布,我建议使用第六章中的食谱,因为它基于一个已发布的、广受好评的方法。也就是说,这段代码的结果在定性上是相似的,并且以非常类似的方式对数据进行了聚类(如果你与第六章中的图进行比较,垂直轴方向的反转对于解读 PCA 图表而言是无关紧要的)。

使用 PCA 进行聚类来对样本进行分类

基因组学中的 PCA 可以让我们看到样本如何聚类。在许多情况下,同一群体的个体会聚集在图表的同一区域。但我们希望进一步预测新个体在群体中的位置。为此,我们将从 PCA 数据开始,因为它进行了降维处理—使得处理数据更为简便—然后应用 K-Means 聚类算法来预测新样本的位置。我们将使用与上述食谱相同的数据集。我们将使用除了一个样本外的所有样本来训练算法,然后预测剩下的样本位置。

K-Means 聚类可以是监督算法的一个例子。在这类算法中,我们需要一个训练数据集,以便算法能够学习。训练算法之后,它将能够对新样本预测某个结果。在我们的案例中,我们希望能够预测群体。

警告

当前的食谱旨在作为对监督算法及其背后概念的温和介绍。我们训练算法的方式远非最佳。关于如何正确训练一个监督算法的问题将在本章最后一个食谱中提到。

准备工作

我们将使用与之前食谱中相同的数据。此食谱的代码可以在Chapter10/Clustering.py中找到。

如何操作…

让我们来看一下:

  1. 我们首先加载群体信息——这与我们在之前的食谱中所做的相似:

    import os
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    from sklearn.decomposition import PCA
    import numpy as np
    from genomics.popgen.pca import plot
    f = open('../Chapter06/relationships_w_pops_041510.txt')
    ind_pop = {}
    f.readline()  # header
    for l in f:
        toks = l.rstrip().split('\t')
        fam_id = toks[0]
        ind_id = toks[1]
        pop = toks[-1]
        ind_pop['/'.join([fam_id, ind_id])] = pop
    f.close()
    
    f = open('../Chapter06/hapmap10_auto_noofs_ld_12.ped')
    ninds = 0
    ind_order = []
    for line in f:
        ninds += 1
        toks = line[:100].replace(' ', '\t').split('\t') #  for speed
        fam_id = toks[0]
        ind_id = toks[1]
        ind_order.append('%s/%s' % (fam_id, ind_id))
    nsnps = (len(line.replace(' ', '\t').split('\t')) - 6) // 2
    print (nsnps)
    f.close()
    
  2. 现在,我们将所有样本数据(SNPs)加载到一个 NumPy 数组中:

    all_array = np.empty((ninds, nsnps), dtype=int)
    f = open('../Chapter06/hapmap10_auto_noofs_ld_12.ped')
    for ind, line in enumerate(f):
        snps = line.replace(' ', '\t').split('\t')[6:]
        for pos in range(len(snps) // 2):
            a1 = int(snps[2 * pos])
            a2 = int(snps[2 * pos])
            my_code = a1 + a2 - 2
            all_array[ind, pos] = my_code
    f.close()
    
  3. 我们将数组分成两个数据集,即包含所有个体(除一个外)作为训练集,和单个个体用于测试的案例:

    predict_case = all_array[-1, :]
    pca_array = all_array[:-1,:]
    
    last_ind = ind_order[-1]
    last_ind, ind_pop[last_ind]
    

我们的测试案例是个体 Y076/NA19124,我们知道他属于约鲁巴族群体。

  1. 现在,我们计算用于 K-Means 聚类的训练集的 PCA:

    my_pca = PCA(n_components=2)
    my_pca.fit(pca_array)
    trans = my_pca.transform(pca_array)
    
    sc_ind_comp = {}
    for i, ind_pca in enumerate(trans):
        sc_ind_comp[ind_order[i]] = ind_pca
    plot.render_pca(sc_ind_comp, cluster=ind_pop)
    

这是输出结果,将有助于检查聚类结果:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_10_02.jpg

图 10.2 - PC1 和 PC2 与按种群编码的颜色

  1. 在我们开始计算 K 均值聚类之前,先写一个函数来绘制运行算法后的聚类面:

    def plot_kmeans_pca(trans, kmeans):
        x_min, x_max = trans[:, 0].min() - 1, trans[:, 0].max() + 1
        y_min, y_max = trans[:, 1].min() - 1, trans[:, 1].max() + 1
        mesh_x, mesh_y = np.meshgrid(np.arange(x_min, x_max, 0.5), np.arange(y_min, y_max, 0.5))
    
        k_surface = kmeans.predict(np.c_[mesh_x.ravel(), mesh_y.ravel()]).reshape(mesh_x.shape)
        fig, ax = plt.subplots(1,1, dpi=300)
        ax.imshow(
            k_surface, origin="lower", cmap=plt.cm.Pastel1,
            extent=(mesh_x.min(), mesh_x.max(), mesh_y.min(), mesh_y.max()),
        )
        ax.plot(trans[:, 0], trans[:, 1], "k.", markersize=2)
        ax.set_title("KMeans clustering of PCA data")
        ax.set_xlim(x_min, x_max)
        ax.set_ylim(y_min, y_max)
        ax.set_xticks(())
        ax.set_yticks(())
        return ax
    
  2. 现在让我们用我们的样本来拟合算法。因为我们有 11 个人群,我们将训练 11 个簇:

    kmeans11 = KMeans(n_clusters=11).fit(trans)
    plot_kmeans_pca(trans, kmeans11)
    

这里是输出结果:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_10_03.jpg

图 10.3 - 11 个簇的簇面

如果你与这里的图进行比较,你会直观地看到这个聚类没有多大意义:它并没有很好地映射到已知的人群上。有人可能会认为,使用 11 个簇的聚类算法并不是很有用。

提示

scikit-learn 中实现了许多其他聚类算法,在多种情况下,它们的表现可能优于 K 均值聚类。你可以在scikit-learn.org/stable/modules/clustering.xhtml找到它们。值得怀疑的是,在这个特定的案例中,任何替代方法都不太可能在 11 个簇的情况下表现得更好。

  1. 尽管看起来 K 均值聚类无法解决 11 个人群的划分,但如果我们使用不同数量的簇,或许它仍然可以提供一些预测。仅通过查看图表,我们可以看到四个独立的块。如果我们使用四个簇,会得到什么结果呢?

    kmeans4 = KMeans(n_clusters=4).fit(trans)
    plot_kmeans_pca(trans, kmeans4)
    

这里是输出结果:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_10_04.jpg

图 10.4 - 四个簇的簇面

四个群体现在大致清晰了。但它们直观上有意义吗?如果有,那么我们可以利用这种聚类方法。事实上,它们确实有意义。左侧的簇由非洲人口组成,顶部的簇由欧洲人组成,底部的簇由东亚人组成。中间的簇最为难以理解,因为它包含了古吉拉特人和墨西哥后裔,但这种混合最初来自于主成分分析(PCA),而非聚类本身所致。

  1. 让我们看看我们漏掉的那个单独个案的预测结果:

    pca_predict = my_pca.transform([predict_case])
    kmeans4.predict(pca_predict)
    

我们的样本被预测为属于簇 1。现在我们需要进一步挖掘一下。

  1. 让我们来看看簇 1 代表什么。我们取训练集中的最后一个个体,他也是一名约鲁巴人,看看他被分配到了哪个簇:

    last_train = ind_order[-2]
    last_train, ind_pop[last_train]
    kmeans4.predict(trans)[0]
    

确实是簇 1,因此预测是正确的。

还有更多…

值得重申的是,我们正在努力实现对机器学习的直观理解。在这个阶段,你应该对监督学习能够带来什么有所了解,并且已经掌握了一个聚类算法的使用示例。关于训练机器学习算法的过程,还有很多内容值得探讨,我们将在最后的食谱中部分揭示。

使用决策树探索乳腺癌特征

当我们接收到一个数据集时,第一个问题之一就是决定从哪里开始分析。一开始,往往会有一种迷茫的感觉,不知道该先做什么。这里,我们将展示基于决策树的探索性方法。决策树的最大优点是,它们会给我们提供构建决策树的规则,让我们初步了解数据的情况。

在这个示例中,我们将使用一个包含乳腺癌患者特征观察的数据集。该数据集包含 699 条数据,包含如肿块厚度、细胞大小的均匀性或染色质类型等信息。结果是良性或恶性肿瘤。特征值被编码为 0 到 10 之间的值。关于该项目的更多信息可以在archive.ics.uci.edu/ml/datasets/breast+cancer+wisconsin+%28diagnostic%29中找到。

准备工作

我们将下载数据及其文档:

wget http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data
wget http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.names

数据文件的格式为 CSV 文件。关于内容的信息可以在第二个下载的文件中找到。

这个代码可以在Chapter10/Decision_Tree.py中找到。

如何操作…

按照以下步骤操作:

  1. 我们做的第一件事是移除一小部分数据不完整的个体:

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    from sklearn import tree
    f = open('breast-cancer-wisconsin.data')
    w = open('clean.data', 'w')
    for line in f:
        if line.find('?') > -1:
            continue
        w.write(line)
    f.close()
    w.close()
    

提示

移除数据不完整的个体在这种情况下是合适的,因为它们只是数据集的一小部分,而且我们只是进行探索性分析。如果数据缺失很多,或者我们需要做更严格的分析,你需要使用处理缺失数据的方法,但我们这里不会进行探讨。

  1. 现在我们将读取数据,为所有列命名:

    column_names = [
        'sample_id', 'clump_thickness', 'uniformity_cell_size',
        'uniformity_cell shape', 'marginal_adhesion',
        'single_epithelial_cell_size', 'bare_nuclei',
        'bland_chromatin', 'normal_nucleoli', 'mitoses',
        'class'
    ]
    samples = pd.read_csv('clean.data', header=None, names=column_names, index_col=0)
    
  2. 现在我们将特征与结果分离,并使用 0 和 1 重新编码结果:

    training_input = samples.iloc[:,:-1]
    target = samples.iloc[:,-1].apply(lambda x: 0 if x == 2 else 1)
    
  3. 现在让我们基于这些数据创建一个最大深度为 3 的决策树:

    clf = tree.DecisionTreeClassifier(max_depth=3)
    clf.fit(training_input, target)
    
  4. 让我们先看看哪些特征最重要:

    importances = pd.Series(
        clf.feature_importances_ * 100,
        index=training_input.columns).sort_values(ascending=False)
    importances
    

以下是按重要性排名的特征:

uniformity_cell_size           83.972870
uniformity_cell shape           7.592903
bare_nuclei                     4.310045
clump_thickness                 4.124183
marginal_adhesion               0.000000
single_epithelial_cell_size     0.000000
bland_chromatin                 0.000000
normal_nucleoli                 0.000000
mitoses                         0.000000

记住,这只是探索性分析。在下一个配方中,我们将尝试生成更可靠的排名。底部特征为零的原因是我们要求最大深度为 3,在这种情况下,可能并非所有特征都会被使用。

  1. 我们可以对实现的准确性进行一些原生分析:

    100 * clf.score(training_input, target)
    

我们得到的性能为 96%。我们不应该用训练集测试算法,因为这会导致结果较为循环。我们将在下一个配方中重新审视这一点。

  1. 最后,让我们绘制决策树:

    fig, ax = plt.subplots(1, dpi=300)
    tree.plot_tree(clf,ax=ax, feature_names=training_input.columns, class_names=['Benign', 'Malignant'])
    

这会产生以下输出:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_10_05.jpg

图 10.5 - 乳腺癌数据集的决策树

让我们从根节点开始看:它的标准是uniformity_cell_size < 2.5,分类为良性。分裂树的主要特征是细胞大小的一致性。根节点的良性分类仅仅是因为数据集中的大多数样本都是良性的。现在看一下根节点右侧的节点:它有 265 个样本,其中大部分是恶性的,并且标准为uniformity_cell_shape < 2.5。

这些规则帮助你初步理解可能驱动数据集的因素。决策树的精确度不是很高,所以将这些视为你的初步步骤。

使用随机森林预测乳腺癌结果

现在我们将使用随机森林预测一些患者的结果。随机森林是一种集成方法(它将使用多个机器学习算法的实例),通过多个决策树得出关于数据的稳健结论。我们将使用与前一个例子相同的例子:乳腺癌特征和结果。

这个例子有两个主要目标:介绍随机森林及机器学习算法训练中的问题。

准备开始

这个例子的代码可以在Chapter10/Random_Forest.py找到。

如何操作…

看一下代码:

  1. 我们像前一个例子一样,首先去除缺失信息的样本:

    import pandas as pd
    import numpy as np
    import pandas as pd
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.tree import export_graphviz
    f = open('breast-cancer-wisconsin.data')
    w = open('clean.data', 'w')
    for line in f:
        if line.find('?') > -1:
            continue
        w.write(line)
    f.close()
    w.close()
    
  2. 现在我们加载清理过的数据:

    column_names = [
        'sample_id', 'clump_thickness', 'uniformity_cell_size',
        'uniformity_cell shape', 'marginal_adhesion',
        'single_epithelial_cell_size', 'bare_nuclei',
        'bland_chromatin', 'normal_nucleoli', 'mitoses',
        'class'
    ]
    samples = pd.read_csv('clean.data', header=None, names=column_names, index_col=0)
    samples
    
    
  3. 我们将数据分为特征和结果:

    training_input = samples.iloc[:, :-1]
    target = samples.iloc[:, -1]
    
  4. 我们创建一个分类器并将数据拟合到它:

    clf = RandomForestClassifier(max_depth=3, n_estimators=200)
    clf.fit(training_input, target)
    

这里最重要的参数是n_estimators:我们要求构建一个由 200 棵树组成的森林。

  1. 现在我们按重要性对特征进行排序:

    importances = pd.Series(
        clf.feature_importances_ * 100,
        index=training_input.columns).sort_values(ascending=False)
    importances
    

以下是输出:

uniformity_cell_size           30.422515
uniformity_cell shape          21.522259
bare_nuclei                    18.410346
single_epithelial_cell_size    10.959655
bland_chromatin                 9.600714
clump_thickness                 3.619585
normal_nucleoli                 3.549669
marginal_adhesion               1.721133
mitoses                         0.194124

结果是非确定性的,意味着你可能会得到不同的结果。另外,请注意,随机森林与前一个例子中的决策树有很大的不同。这是预期之中的,因为决策树是一个单一的估计器,而随机森林权衡了 200 棵树,因此更加可靠。

  1. 我们可以对这个案例进行评分:

    clf.score(training_input, target)
    

我得到的结果是 97.95%。你可能会得到稍微不同的值,因为算法是随机的。正如我们在前一个例子中所说,从训练集获取得分是一个循环过程,远非最佳实践。

  1. 为了更真实地了解算法的准确性,我们需要将数据分为两部分——训练集和测试集:

    for test_size in [0.01, 0.1, 0.2, 0.5, 0.8, 0.9, 0.99]:
        X_train, X_test, y_train, y_test = train_test_split(
            trainning_input, target, test_size=test_size)
        tclf = RandomForestClassifier(max_depth=3)
        tclf.fit(X_train, y_train)
        score = tclf.score(X_test, y_test)
        print(f'{1 - test_size:.1%} {score:.2%}')
    

输出结果如下(记住你会得到不同的值):

99.0% 71.43%
90.0% 94.20%
80.0% 97.81%
50.0% 97.66%
20.0% 96.89%
10.0% 94.80%
1.0% 92.02%

如果你仅用 1%的数据进行训练,你的准确率只有 71%,而如果你使用更多的数据,准确率会超过 90%。注意,准确率并不随着训练集的大小单调增加。决定训练集的大小是一个复杂的问题,涉及许多因素,可能会导致意想不到的副作用。

还有更多…

我们仅仅触及了训练和测试机器学习算法的表面。例如,监督数据集通常会被分成 3 部分,而不是 2 部分(训练、测试和交叉验证)。在训练算法时,你需要考虑许多其他问题,还有更多种类的算法。在本章中,我们试图培养理解机器学习的基本直觉,但如果你打算继续这条路线,这只是你的起点。

第十二章:使用 Dask 和 Zarr 进行并行处理

生物信息学数据集正在以指数速度增长。基于标准工具(如 Pandas)的数据分析策略假设数据集能够装入内存(尽管会有一些外部存储分析的处理),或者假设单台机器能够高效地处理所有数据。不幸的是,这对于许多现代数据集来说并不现实。

在本章中,我们将介绍两种能够处理非常大数据集和昂贵计算的库:

  • Dask 是一个支持并行计算的库,可以扩展到从单台计算机到非常大的云环境和集群环境。Dask 提供了与 Pandas 和 NumPy 类似的接口,同时允许你处理分布在多台计算机上的大数据集。

  • Zarr 是一个存储压缩和分块多维数组的库。正如我们将看到的,这些数组专为处理在大型计算机集群中处理的大数据集而设计,同时在需要时也能在单台计算机上处理数据。

我们的食谱将使用蚊子基因组学的数据介绍这些高级库。你应该将这段代码作为起点,帮助你走上处理大数据集的道路。大数据集的并行处理是一个复杂的话题,而这只是你旅程的开始——而非结束。

因为所有这些库对于数据分析都至关重要,如果你正在使用 Docker,它们都可以在 tiagoantao/bioinformatics_dask Docker 镜像中找到。

在本章中,我们将介绍以下食谱:

  • 使用 Zarr 读取基因组学数据

  • 使用 Python 多进程进行数据并行处理

  • 使用 Dask 基于 NumPy 数组处理基因组数据

  • 使用 dask.distributed 调度任务

使用 Zarr 读取基因组学数据

Zarr (zarr.readthedocs.io/en/stable/) 将基于数组的数据(如 NumPy)存储在磁盘和云存储的层次结构中。Zarr 用来表示数组的数据结构不仅非常紧凑,而且还支持并行读取和写入,这一点我们将在接下来的食谱中看到。在本食谱中,我们将读取并处理来自按蚊基因组 1000 基因组计划的数据(malariagen.github.io/vector-data/ag3/download.xhtml)。在这里,我们将仅进行顺序处理,以便引入 Zarr;在接下来的食谱中,我们将进行并行处理。我们的项目将计算单一染色体上所有基因位置的缺失数据。

准备工作

按照 cloud.google.com/storage/docs/gsutil_install 上提供的指导,从 gsutil 中获取按蚊 1000 基因组数据。在安装了 gsutil 后,使用以下代码行下载数据(约 2 千兆字节 (GB)):

mkdir -p data/AG1000G-AO/
gsutil -m rsync -r \
         -x '.*/calldata/(AD|GQ|MQ)/.*' \
         gs://vo_agam_release/v3/snp_genotypes/all/AG1000G-AO/ \
         data/AG1000G-AO/ > /dev/null

我们从项目中下载了一个样本子集。下载数据后,处理它的代码可以在Chapter11/Zarr_Intro.py中找到。

如何操作…

查看以下步骤以开始:

  1. 让我们首先检查一下 Zarr 文件中提供的结构:

    import numpy as np
    import zarr 
    mosquito = zarr.open('data/AG1000G-AO')
    print(mosquito.tree())
    

我们从打开 Zarr 文件开始(正如我们很快会看到的,这可能实际上并不是一个文件)。之后,我们会打印出里面可用的数据树:

/
├── 2L
│   └── calldata
│       └── GT (48525747, 81, 2) int8
├── 2R
│   └── calldata
│       └── GT (60132453, 81, 2) int8
├── 3L
│   └── calldata
│       └── GT (40758473, 81, 2) int8
├── 3R
│   └── calldata
│       └── GT (52226568, 81, 2) int8
├── X
│   └── calldata
│       └── GT (23385349, 81, 2) int8
└── samples (81,) |S24

Zarr 文件包含五个数组:四个对应蚊子的染色体——2L、2R、3L、3R和X(Y不包括在内)——另一个包含文件中包含的 81 个样本。最后一个数组包含样本名称——我们在这个文件中有 81 个样本。染色体数据由 8 位整数(int8)组成,样本名称则是字符串。

  1. 现在,让我们探索2L染色体的数据。首先来看一些基本信息:

    gt_2l = mosquito['/2L/calldata/GT']
    gt_2l
    

这是输出:

<zarr.core.Array '/2L/calldata/GT' (48525747, 81, 2) int8>

我们有一个包含4852547个 SNP 和81个样本的数组。对于每个 SNP 和样本,我们有2个等位基因。

  1. 现在我们来检查数据是如何存储的:

    gt_2l.info
    

输出看起来是这样的:

Name               : /2L/calldata/GT
Type               : zarr.core.Array
Data type          : int8
Shape              : (48525747, 81, 2)
Chunk shape        : (300000, 50, 2)
Order              : C
Read-only          : False
Compressor         : Blosc(cname='lz4', clevel=5, shuffle=SHUFFLE, blocksize=0)
Store type         : zarr.storage.DirectoryStore
No. bytes          : 7861171014 (7.3G)
No. bytes stored   : 446881559 (426.2M)
Storage ratio      : 17.6
Chunks initialized : 324/324

这里有很多内容需要解析,但现在我们将专注于存储类型、存储的字节数和存储比率。Store type的值是zarr.storage.DirectoryStore,所以数据并不在一个单独的文件中,而是存储在一个目录内。数据的原始大小是7.3 GB!但是 Zarr 使用压缩格式,将数据的大小压缩到426.2 17.6。

  1. 让我们来看看数据是如何存储在目录中的。如果你列出AG1000G-AO目录的内容,你会发现以下结构:

    .
    ├── 2L
    │   └── calldata
    │       └── GT
    ├── 2R
    │   └── calldata
    │       └── GT
    ├── 3L
    │   └── calldata
    │       └── GT
    ├── 3R
    │   └── calldata
    │       └── GT
    ├── samples
    └── X
        └── calldata
            └── GT
    
  2. 如果你列出2L/calldata/GT目录的内容,你会发现很多文件在编码该数组:

    0.0.0
    0.1.0
    1.0.0
    ...
    160.0.0
    160.1.0
    

2L/calldata/GT目录中有 324 个文件。记住,在前一步中我们有一个叫做Chunk shape的参数,它的值是(300000, 50, 2)。

Zarr 将数组拆分成多个块——这些块比加载整个数组更容易在内存中处理。每个块包含 30000x50x2 个元素。考虑到我们有 48525747 个 SNP,我们需要 162 个块来表示这些 SNP 的数量(48525747/300000 = 161.75),然后乘以 2 以表示样本的数量(81 个样本/每块 50 个 = 1.62)。因此,我们最终会得到 162*2 个块/文件。

提示

分块是一个广泛应用的技术,用于处理不能完全一次性加载到内存中的数据。这包括许多其他库,如 Pandas 或 Zarr。稍后我们将看到一个 Zarr 的例子。更大的观点是,你应该意识到分块的概念,因为它在许多需要大数据的场景中都有应用。

  1. 在我们加载 Zarr 数据进行处理之前,先创建一个函数来计算一个块的基本基因组统计信息。我们将计算缺失值、祖先纯合子数量和异合子数量:

    def calc_stats(my_chunk):
        num_miss = np.sum(np.equal(my_chunk[:,:,0], -1), axis=1)
        num_anc_hom = np.sum(
            np.all([
                np.equal(my_chunk[:,:,0], 0),
                np.equal(my_chunk[:,:,0], my_chunk[:,:,1])], axis=0), axis=1)
        num_het = np.sum(
            np.not_equal(
                my_chunk[:,:,0],
                my_chunk[:,:,1]), axis=1)
        return num_miss, num_anc_hom, num_het
    

如果你查看前面的函数,你会注意到没有任何与 Zarr 相关的内容:它只是 NumPy 代码。Zarr 有一个非常轻量的应用程序接口(API),它将 NumPy 中的大多数数据暴露出来,使得如果你熟悉 NumPy,它非常容易使用。

  1. 最后,让我们遍历数据——也就是遍历我们的数据块来计算统计信息:

    complete_data = 0
    more_anc_hom = 0
    total_pos = 0
    for chunk_pos in range(ceil(max_pos / chunk_pos_size)):
        start_pos = chunk_pos * chunk_pos_size
        end_pos = min(max_pos + 1, (chunk_pos + 1) * chunk_pos_size)
        my_chunk = gt_2l[start_pos:end_pos, :, :]
        num_samples = my_chunk.shape[1]
        num_miss, num_anc_hom, num_het = calc_stats(my_chunk)
        chunk_complete_data = np.sum(np.equal(num_miss, 0))
        chunk_more_anc_hom = np.sum(num_anc_hom > num_het)
        complete_data += chunk_complete_data
        more_anc_hom += chunk_more_anc_hom
        total_pos += (end_pos - start_pos)
    print(complete_data, more_anc_hom, total_pos)
    

大多数代码负责管理数据块,并涉及算术运算来决定访问数组的哪部分。就准备好的 Zarr 数据而言,重要的部分是my_chunk = gt_2l[start_pos:end_pos, :, :]这一行。当你切片 Zarr 数组时,它会自动返回一个 NumPy 数组。

提示

在将数据加载到内存时要非常小心。记住,大多数 Zarr 数组的大小将远大于你可用的内存,因此如果尝试加载,可能会导致应用程序甚至计算机崩溃。例如,如果你执行all_data = gt_2l[:, :, :],你将需要大约 8 GB 的空闲内存来加载它——正如我们之前看到的,数据大小为 7.3 GB。

还有更多…

Zarr 具有比这里展示的更多功能,虽然我们将在接下来的示例中探索一些其他功能,但仍有一些可能性是你应该了解的。例如,Zarr 是少数几个允许并发写入数据的库之一。你还可以更改 Zarr 表示的内部格式。

正如我们在这里看到的,Zarr 能够以非常高效的方式压缩数据——这是通过使用 Blosc 库实现的(www.blosc.org/)。由于 Blosc 的灵活性,你可以更改 Zarr 数据的内部压缩算法。

另见

Zarr 有替代格式——例如,分层数据格式 5(HDF5)(en.wikipedia.org/wiki/Hierarchical_Data_Format)和网络公共数据格式(NetCDF)(en.wikipedia.org/wiki/NetCDF)。虽然这些格式在生物信息学领域之外更为常见,但它们功能较少——例如,缺乏并发写入功能。

使用 Python 多处理进行数据并行处理

处理大量数据时,一种策略是并行处理,以便利用所有可用的中央处理单元(CPU)的计算能力,因为现代计算机通常有多个核心。在理论上的最佳情况下,如果你的计算机有八个核心,你可以通过并行处理获得八倍的性能提升。

不幸的是,典型的 Python 代码只能使用一个核心。话虽如此,Python 具有内置功能来利用所有可用的 CPU 资源;事实上,Python 提供了几种方法来实现这一点。在本配方中,我们将使用内置的multiprocessing模块。这里提供的解决方案在单台计算机上运行良好,并且如果数据集能适应内存的话也没有问题,但如果你想要在集群或云端扩展,应该考虑使用 Dask,我们将在接下来的两篇配方中介绍它。

我们在这里的目标仍然是计算与缺失值和杂合度相关的统计信息。

准备工作

我们将使用与之前的配方相同的数据。该配方的代码可以在Chapter11/MP_Intro.py中找到。

如何做…

请按照以下步骤开始:

  1. 我们将使用与之前的配方完全相同的函数来计算统计信息——这是一个高度依赖 NumPy 的函数:

    import numpy as np
    import zarr
    def calc_stats(my_chunk):
        num_miss = np.sum(np.equal(my_chunk[:,:,0], -1), axis=1)
        num_anc_hom = np.sum(
            np.all([
                np.equal(my_chunk[:,:,0], 0),
                np.equal(my_chunk[:,:,0], my_chunk[:,:,1])], axis=0), axis=1)
        num_het = np.sum(
            np.not_equal(
                my_chunk[:,:,0],
                my_chunk[:,:,1]), axis=1)
        return num_miss, num_anc_hom, num_het
    
  2. 让我们访问我们的蚊子数据:

    mosquito = zarr.open('data/AG1000G-AO')
    gt_2l = mosquito['/2L/calldata/GT']
    
  3. 尽管我们使用相同的函数来计算统计信息,但我们对整个数据集的处理方式将有所不同。首先,我们计算所有将调用calc_stats的区间。这些区间将被设计成与变异体的块划分完美匹配:

    chunk_pos_size = gt_2l.chunks[0]
    max_pos = gt_2l.shape[0]
    intervals = []
    for chunk_pos in range(ceil(max_pos / chunk_pos_size)):
        start_pos = chunk_pos * chunk_pos_size
        end_pos = min(max_pos + 1, (chunk_pos + 1) * chunk_pos_size)
        intervals.append((start_pos, end_pos))
    

我们的区间列表必须与磁盘上的块划分相关。这项计算会很高效,只要这个映射尽可能接近。

  1. 现在,我们将把计算每个区间的代码分离到一个函数中。这一点很重要,因为multiprocessing模块将在它创建的每个进程中多次执行这个函数:

    def compute_interval(interval):
        start_pos, end_pos = interval
        my_chunk = gt_2l[start_pos:end_pos, :, :]
        num_samples = my_chunk.shape[1]
        num_miss, num_anc_hom, num_het = calc_stats(my_chunk)
        chunk_complete_data = np.sum(np.equal(num_miss, 0))
        chunk_more_anc_hom = np.sum(num_anc_hom > num_het)
        return chunk_complete_data, chunk_more_anc_hom
    
  2. 我们现在终于将让代码在多个核心上执行:

    with Pool() as p:
        print(p)
        chunk_returns = p.map(compute_interval, intervals)
        complete_data = sum(map(lambda x: x[0], chunk_returns))
        more_anc_hom = sum(map(lambda x: x[1], chunk_returns))
        print(complete_data, more_anc_hom)
    

第一行使用multiprocessing.Pool对象创建一个上下文管理器。Pool对象默认会创建多个编号为os.cpu_count()的进程。池提供了一个map函数,能够在所有创建的进程中调用我们的compute_interval函数。每次调用将处理一个区间。

还有更多…

本配方简要介绍了如何在 Python 中进行并行处理,而无需使用外部库。话虽如此,它展示了并发并行处理的最重要构建块。

由于 Python 中的线程管理方式,线程并不是实现真正并行处理的可行替代方案。纯 Python 代码无法通过多线程并行执行。

一些你可能使用的库——通常 NumPy 就是这样的——能够在执行顺序代码时利用所有底层处理器。确保在使用外部库时,不要过度占用处理器资源:当你有多个进程时,底层库也会使用多个核心。

另见

使用 Dask 处理基于 NumPy 数组的基因组数据

Dask 是一个提供高级并行处理的库,可以从单个计算机扩展到非常大的集群或云操作。它还提供了处理比内存更大的数据集的能力。它能够提供与常见 Python 库如 NumPy、Pandas 或 scikit-learn 相似的接口。

我们将重复之前配方中的一个子集——即计算数据集中 SNP 的缺失情况。我们将使用 Dask 提供的类似于 NumPy 的接口。

在我们开始之前,请注意 Dask 的语义与 NumPy 或 Pandas 等库有很大不同:它是一个懒加载库。例如,当你指定一个等效于 np.sum 的调用时,你实际上并没有计算和求和,而是在未来会计算它的任务。让我们进入配方来进一步澄清这一点。

准备就绪

我们将以一种完全不同的方式重新分块 Zarr 数据。我们这么做的原因是为了在准备算法时能够可视化任务图。包含五个操作的任务图比包含数百个节点的任务图更容易可视化。为了实际目的,你不应该像我们这里做的那样将数据重新分块为如此小的块。实际上,如果你根本不重新分块这个数据集,也是完全可以的。我们这么做只是为了可视化的目的:

import zarr
mosquito = zarr.open('data/AG1000G-AO/2L/calldata/GT')
zarr.array(
    mosquito,
    chunks=(1 + 48525747 // 4, 81, 2),
    store='data/rechunk')

我们最终会得到非常大的块,虽然这对我们的可视化目的很有用,但它们可能太大而无法放入内存中。

此配方的代码可以在 Chapter11/Dask_Intro.py 中找到。

如何实现…

  1. 让我们首先加载数据并检查 DataFrame 的大小:

    import numpy as np
    import dask.array as da
    
    mosquito = da.from_zarr('data/rechunk')
    mosquito
    

如果你在 Jupyter 中执行,这将是输出结果:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_001.jpg

图 11.1 - Dask 数组的 Jupyter 输出,汇总我们的数据

完整的数组占用 7.32 GB。最重要的数字是块的大小:1.83 GB。每个工作节点需要有足够的内存来处理一个块。记住,我们这里只是使用了较少的块数,以便能够在这里绘制任务。

由于大块数据的大小,我们最终只得到了四个块。

我们尚未将任何内容加载到内存中:我们只是指定了最终想要执行的操作。我们正在创建一个任务图来执行,而不是立即执行——至少目前如此。

  1. 让我们来看看我们需要执行哪些任务来加载数据:

    mosquito.visualize()
    

这是输出结果:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_002.jpg

图 11.2 - 加载我们的 Zarr 数组所需执行的任务

因此,我们有四个任务要执行,每个块对应一个任务。

  1. 现在,让我们看看计算每个块缺失值的函数:

    def calc_stats(variant):
        variant = variant.reshape(variant.shape[0] // 2, 2)
        misses = np.equal(variant, -1)
        return misses
    

每个块的函数将在 NumPy 数组上操作。请注意区别:我们在主循环中使用的代码是针对 Dask 数组的,但在块级别,数据以 NumPy 数组的形式呈现。因此,这些块必须适配内存,因为 NumPy 需要如此。

  1. 后面,当我们实际使用这个函数时,我们需要一个二维(2D)数组。由于数组是三维(3D)的,我们需要对数组进行重塑:

    mosquito_2d = mosquito.reshape(
        mosquito.shape[0],
        mosquito.shape[1] * mosquito.shape[2])
    mosquito_2d.visualize()
    

这是当前的任务图:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_003.png

图 11.3 - 加载基因组数据并重塑的任务图

reshape 操作发生在 dask.array 层,而不是 NumPy 层,因此它仅向任务图中添加了节点。仍然没有执行。

  1. 现在,让我们准备执行这个函数——意味着在整个数据集上向我们的任务图中添加任务。有很多种执行方式;在这里,我们将使用 dask.array 提供的 apply_along_axis 函数,它基于 NumPy 中同名的函数:

    max_pos = 10000000
    stats = da.apply_along_axis(
        calc_stats, 1, mosquito_2d[:max_pos,:],
        shape=(max_pos,), dtype=np.int64)
    stats.visualize()
    

目前,我们只打算研究前百万个位置。正如你在任务图中看到的,Dask 足够智能,只会对参与计算的块添加操作:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_004.jpg

图 11.4 - 包括统计计算在内的完整任务图

  1. 记住,在此之前我们还没有进行任何计算。现在是时候真正执行任务图了:

    stats = stats.compute() 
    

这将启动计算。计算的具体方式是我们将在下一个配方中讨论的内容。

警告

由于块大小的问题,这段代码可能会导致你的计算机崩溃。至少需要 16 GB 内存才能保证安全。记住,你可以使用更小的块大小——而且你应该使用更小的块大小。我们之所以使用这样的块大小,是为了能够生成前面展示的任务图(否则,它们可能会有数百个节点,无法打印出来)。

还有更多内容…

我们没有在这里讨论如何优化 Dask 代码的策略——那将是另一本书的内容。对于非常复杂的算法,你需要进一步研究最佳实践。

Dask 提供的接口类似于其他常见的 Python 库,如 Pandas 或 scikit-learn,可以用于并行处理。你也可以将它用于不依赖现有库的通用算法。

参见

使用 dask.distributed 调度任务

Dask 在执行方面非常灵活:我们可以在本地执行、在科学集群上执行,或者在云上执行。这种灵活性是有代价的:它需要被参数化。有多种配置 Dask 调度和执行的方式,但最通用的是 dask.distributed,因为它能够管理不同种类的基础设施。因为我不能假设你能够访问像 dask.distributed 这样存在于不同平台上的集群或云服务。

在这里,我们将再次计算 Anopheles 1000 基因组项目的不同变体的简单统计数据。

准备工作

在开始使用dask.distributed之前,我们需要注意,Dask 有一个默认的调度器,这个调度器实际上会根据你所使用的库而有所变化。例如,以下是我们 NumPy 示例的调度器:

import dask
from dask.base import get_scheduler
import dask.array as da
mosquito = da.from_zarr('data/AG1000G-AO/2L/calldata/GT')
print(get_scheduler(collections=[mosquito]).__module__)

输出将如下所示:

dask.threaded

Dask 在这里使用了一个线程调度器。对于 NumPy 数组来说,这样做是有道理的:NumPy 实现本身是多线程的(真正的多线程,带有并行性)。当底层库并行运行时,我们不希望有大量进程在后台运行。如果你使用的是 Pandas DataFrame,Dask 可能会选择一个多进程调度器。因为 Pandas 本身不支持并行,所以让 Dask 自己并行运行是有意义的。

好的——既然我们已经解决了这个重要细节,现在让我们回到环境准备工作。

dask.distributed 有一个集中式调度器和一组工作节点,我们需要启动它们。可以在命令行中运行以下代码来启动调度器:

dask-scheduler --port 8786 --dashboard-address 8787

我们可以在与调度器相同的机器上启动工作节点,方法如下:

dask-worker --nprocs 2 –nthreads 1 127.0.0.1:8786

我指定了每个进程使用一个线程。对于 NumPy 代码来说,这个配置是合理的,但实际配置将取决于你的工作负载(如果你在集群或云上,配置可能完全不同)。

小贴士

你实际上不需要像我这里所做的那样手动启动整个进程。dask.distributed 会为你启动一些东西——虽然它不会完全优化你的工作负载——如果你没有自己准备好系统(详情请见下一部分)。但我想给你一个概念,因为在很多情况下,你必须自己设置基础设施。

同样,我们将使用第一部分食谱中的数据。请确保按照准备工作部分的说明下载并准备好数据。我们不会使用重新分块的部分——我们将在下一部分的 Dask 代码中进行处理。我们的代码可以在Chapter11/Dask_distributed.py中找到。

如何做到这一点…

按照以下步骤开始:

  1. 让我们从连接到之前创建的调度器开始:

    import numpy as np
    import zarr
    import dask.array as da
    from dask.distributed import Client
    
    client = Client('127.0.0.1:8786')
    client
    

如果你使用的是 Jupyter,你将看到一个很好的输出,汇总了你在此食谱的准备工作部分所创建的配置:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_005.jpg

图 11.5 - 使用 dask.distributed 时的执行环境摘要

你会注意到这里提到了一个仪表板。dask.distributed 提供了一个实时仪表板,允许你跟踪计算的状态。你可以在浏览器中输入 http://127.0.0.1:8787/ 来访问它,或者直接点击 图 11.5 中提供的链接。

由于我们还没有进行任何计算,仪表板大部分是空的。一定要探索顶部的许多标签:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_006.jpg

图 11.6 - dask.distributed 仪表板的初始状态

  1. 让我们加载数据。更严格地说,让我们准备任务图以加载数据:

    mosquito = da.from_zarr('data/AG1000G-AO/2L/calldata/GT')
    mosquito
    

以下是在 Jupyter 上的输出:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_007.jpg

图 11.7 - 原始 Zarr 数组(2L 染色体)的汇总

  1. 为了方便可视化,让我们再次进行分块。我们还将为第二个维度——样本——创建一个单一的块。这是因为我们缺失值的计算需要所有样本,而在我们的特定情况下,为每个样本创建两个块是没有意义的:

    mosquito = mosquito.rechunk((mosquito.shape[0]//8, 81, 2))
    

提醒一下,我们有非常大的块,你可能会遇到内存问题。如果是这样,你可以使用原始的块进行运行。只是可视化效果将无法读取。

  1. 在继续之前,让我们要求 Dask 不仅执行重新分块操作,还要确保结果已经准备好并存储在工作节点中:

    mosquito = mosquito.persist()
    

persist 调用确保数据在工作节点中可用。在以下截图中,你可以看到计算过程中的仪表板。你可以查看每个节点上正在执行的任务、已完成和待完成的任务摘要,以及每个工作节点上存储的字节数。需要注意的是 溢写到磁盘 的概念(见屏幕左上角)。如果内存不足以容纳所有块,它们会暂时写入磁盘:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_008.jpg

图 11.8 - 执行持久化函数以重新分块数组时的仪表板状态

  1. 现在,让我们计算统计信息。对于最后一个配方,我们将使用不同的方法——我们将请求 Dask 对每个块应用一个函数:

    def calc_stats(my_chunk):
        num_miss = np.sum(
            np.equal(my_chunk[0][0][:,:,0], -1),
            axis=1)
        return num_miss
    stats = da.blockwise(
        calc_stats, 'i', mosquito, 'ijk',
        dtype=np.uint8)
    stats.visualize()
    

请记住,每个块不是 dask.array 实例,而是一个 NumPy 数组,因此代码是在 NumPy 数组上运行的。以下是当前的任务图。没有加载数据的操作,因为之前执行的函数已经完成了所有这些操作:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/bioinfo-py-cb/img/B17942_11_009.jpg

图 11.9 - 从持久化数据开始的每个块对 calc_stats 函数的调用

  1. 最后,我们可以得到我们的结果:

    stat_results = stats.compute()
    

还有更多…

关于 dask.distributed 接口,还有很多内容可以进一步讲解。在这里,我们介绍了其架构的基本概念和仪表盘。

dask.distributed 提供了基于 Python 标准 async 模块的异步接口。由于本章内容的介绍性性质,我们不会详细讨论它,但建议你查看相关内容。

另见

Python入门实战:Python生物信息学编程基础 本文旨在为生物学背景的研究人员和对生物信息学感兴趣的程序员提供一个全面的Python生物信息学编程入门指南。我们将从Python基础知识开始,逐步深入到生物信息学特定的工具和技术,最终达到能够独立开发生物信息学分析程序的水平。Python编程基础生物信息学常用数据结构和算法DNA和蛋白质序列分析基因组数据处理生物信息学数据可视化Biopython库的使用实际项目案例背景介绍:概述文章目的、范围和预期读者核心概念与联系:介绍Python和生物信息学的基本概念。 阅读详情

相关推荐

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Python 生物信息学秘籍第三版(一)

生物信息学是一个活跃的研究领域,使用各种简单到高级的计算方法从生物数据中提取有价值的信息,本书将展示如何使用 Python 管理这些任务。本书的更新版《Python 生物信息学实用手册》首先概述了 Python 生态系统中各种工具和库,它们将帮助你转换、分析和可视化生物数据集。在后续章节中,你将学习下一代测序、单细胞分析、基因组学、宏基因组学、群体遗传学、系统发育学和蛋白质组学等关键技术,并通过实际案例深入了解。

龙哥盟 1179

AI漫剧制作全流程零基础实操指南:从剧本到剪辑

AI漫剧是一种利用AI工具将剧本、分镜、出图、配音、剪辑整合为流水线的短视频内容形式。其技术原理基于文生图、图生图与文本转语音模型的组合,核心挑战在于角色一致性控制与分镜批量出图。这项技术大幅降低了视频制作门槛,使个人创作者无需演员和设备即可产出剧情向短内容,广泛应用于短视频平台的情景剧、玄幻、甜宠等题材。本文给出了一套零基础可照做的全流程实操方案,覆盖剧本提示词、分镜表、出图选型、配音合成与剪辑模板,帮助你快速跑通AI漫剧制作链路。

weixin_29048309的博客 527

【亲测免费】 生物信息学Python cookbook第三版教程

《生物信息学Python cookbook第三版》是由Packt Publishing出版的一本关于使用现代Python库和应用程序解决真实世界计算生物学问题的书籍。本书通过一系列的实例和案例,展示了如何使用Python进行生物数据分析、可视化和处理。本书涵盖了从基础到高级的生物信息学技术,包括下一代测序、单细胞分析、基因组学、群体遗传学、系统发育学和蛋白质组学等。 ## 项目快速启动 ###...

gitblog_00146的博客 1320

腾讯云服务器被攻击,带宽被占满的抗战日记

故事 时间:2021-08-23 地点:腾讯云服务器 事件:服务器内容被黑,修复后某人气不过,开始DDOS,占满服务器的带宽,导致网站访问非常缓慢。 杂记 根据腾讯云后台+宝塔后台,带宽被占满:(小垃圾水管没办法) 部分参考:记一次阿里云服务器ECS流出带宽占满的解决过程 https://blog.youkuaiyun.com/wangzhihao1994/article/details/99563456 首先是在云主机上使用远程连接访问到云主机,安装iftop工具 CentOS .

Rudon滨海渔村的博客 1303

常用元器件使用方法13:物理层接口芯片DP83848的使用方法

介绍: DP83848是以太网物理层接口芯片,具有多种型号,从便于焊接角度考虑LQFP-48封装较为合适,采用LQFP-48封装的芯片,有2种型号,分别为DP83848I和DP83848C,如下图所示。 其主要区别是使用温度不同,如下图所示。 这2种芯片芯片网上均有销售,按理说DP83848C价格应该更加便宜,实际不然,DP83848I的价格低于DP83848C,考虑或与芯片的出货量...

snmplink的博客 1万+

Python 生物信息学秘籍(四)

PCA 是一种统计程序,用于将多个变量的维度降低到一个更小的线性不相关的子集。在第六章中,我们看到了一个基于使用外部应用的 PCA 实现。在这个菜谱中,我们将为群体遗传学实现相同的 PCA,但将使用库。Scikit-learn 是用于机器学习的基本 Python 库之一,本菜谱是对该库的介绍。PCA 是一种无监督的机器学习形式——我们不提供关于样本类别的信息。我们将在本章的其他配方中讨论监督技术。提醒一下,我们将从 HapMap 项目中计算 11 个人类群体的 PCA。

龙哥盟 1187

高比例风电电力系统储能运行及配置研究(python&Matlab实现)

目录1 概述2 案例3 Matlab实现 3.1 题目及分析3.2 Matlab代码 4 七个题全部代码(值得学习) 下面我们先以第二题为例,然后给出Matlab代码:先考虑风电装机300MW直接替代机组3的发电功率曲线,观察系统功率平衡发生的变化情况。然后在此场景下,以最小发电成本为目标函数,将负荷分配给两台火电机组1、2和风电机组,绘制机组日发电计划图。再将风电装机容量作为一个决策变量,以最小发电成本为目标函数,求取最小发电成本对应的风电装机容量,绘制机组日发电计划图。1. 风电装机300MW、直接

weixin_46039719的博客 1741

Python 生物信息学秘籍第三版(三)

系统发育学是应用分子测序技术来研究生物之间的进化关系。通常用系统发育树来表示这一过程。从基因组数据中计算这些树是一个活跃的研究领域,并具有许多现实世界中的应用。本书将把之前提到的实际操作方法推向一个新高度:这里的大部分内容都受到了关于埃博拉病毒的最新研究的启发,研究了最近在非洲爆发的埃博拉疫情。该研究名为Genomic surveillance elucidates Ebola virus origin and transmission during the 2014 outbreak,由Gire et a

龙哥盟 834

Linux Kernel入门到精通系列讲解(RV-Kernel 篇) 5.3 从零移植 busybox,基于RISC-V

上一章节我们已经成功启动了`Ubuntu`,但是由于`Ubuntu`占用系统空间过大,所以我转向占用较小的`busybox`,预计就占用`30M`左右。开始移植busybox,基于riscv64

DSMGUOGUO的博客 857

(二)使用VS2022克隆下载C++自制植物大战僵尸游戏教程

本文将介绍如何使用VS2022克隆下载《植物大战僵尸C++自制版本》。Gitee项目地址:Gitee仓库地址Github项目地址:Github仓库地址游戏官网地址(下载可直接运行)游戏官网。

尔灵尔亿的博客 4936

Python 生物信息学秘籍第三版(二)

原文:annas-archive.org/md5/9694cf42f7d741c69225ff1cf52b0efe。

龙哥盟 1984

WIFI和BT测试(射频工程师)

买不了吃亏买不了上当,我卖的是技能,你收获的是经验。

m0_58834499的博客 599

Python 生物信息学秘籍(一)

原文:Bioinformatics with Python Cookbook 协议:CC BY-NC-SA 4.0 零、前言 生物信息学是一个活跃的研究领域,它使用一系列简单到高级的计算从生物数据中提取有价值的信息,这本书将向您展示如何使用 Python 管理这些任务。 这本更新版的《Python 生物信息学指南》从 Python 生态系统中各种工具和库的快速概述开始,这些工具和库将帮助您转换、分析和可视化生物数据集。随着章节的深入,您将借助真实世界的例子,涵盖下一代测序、单细胞分析、基因组学、宏基因组

龙哥盟 2299

扫地机器人行业 企业篇-产业总部地理分布

中国扫地机器人产业呈现区域集聚特征,广东省以13家企业领跑全国,其中深圳独占9家(如大疆、云鲸智能等),佛山、广州、东莞各有分布。江苏省6家企业主要集中在苏州(科沃斯、追觅科技等)。北京聚集了石头科技、小米等4家品牌。浙江、山东、湖南等地也有代表性企业分布。国际品牌方面,美国iRobot、韩国三星/LG、日本松下等均在各自国家设立总部,而戴森、飞利浦等欧洲品牌则将中国运营中心设在上海或苏州。值得注意的是,部分品牌如由利、宝家丽虽为外资起源,但主要运营实体已落户中国。

智能硬件研发,欢迎交流 363

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

探索生物信息学的奥秘:《Python生物信息学实战指南第三版》开源代码库

探索生物信息学的奥秘:《Python生物信息学实战指南第三版》开源代码库 项目地址:https://gitcode.com/gh_mirrors/bi/Bioinformatics-with-Python-Cookbook-third-edition 在生物学和计算科学的交汇点上,Python语言已经成为解决复杂生物数据问题的首选工具。《Python生物信息学实战指南第三版》的开源代码库是一个宝贵...

gitblog_00024的博客 952

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

如何自学生物信息学:从菜鸟到专家

看透了如此多的秘密,我们已停止相信尚有不可知之物。然而,那不可知之物却仍然坐在那里,冷静地舔着自己的嘴唇。 ——H.L. Mencken尽管人类已把航天器...

公众号/简说基因,知乎/简宝玉 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Bioinformatics with Python Cookbook 第三版安装和配置指南

### 项目介绍 `Bioinformatics with Python Cookbook` 第三版是一个专注于使用Python解决生物信息学问题的开源项目。该项目由Packt Publishing出版,旨在帮助生物信息学分析师、数据科学家、计算生物学家和研究人员使用现代Python库和应用程序来解决实际的计算生物学问题。 ### 主要编程语言 该项目主要使用Python编程语言。Python因...

gitblog_07912的博客 792

《python生物信息学数据管理》解读——前言

我是一名制药工程专业的研究生,方向偏向生物制药。三年前被骗学习python,逐渐有兴趣,又因想和自己的专业相关,于是开始自学生物信息。 这个专栏我想的是解读《python生物信息学数据管理》这本书。我会将书中的知识点解析,并附着上代码,这样可以免去读者敲代码的时间。当然如果时间允许的话我希望你们能自己敲一遍打败,就像好记性不如烂笔头一样,学习编程语言的烂笔头就是敲代码。 《python生物信息学数据管理》这本书分为六个部分,共21章。第一部分介绍python语言,如何写第一个小程序。第二部分介绍这个语言

qq_54510051的博客 756

Python 生物信息学秘籍(三)

在这里,我们将介绍 Biopython 的PDB模块,用于处理 PDB。我们将使用代表部分p53蛋白质的三个模型。你可以在 http://www.rcsb.org/pdb/101/motm.do?momID=31和阅读更多关于和p53的文件。银河(galaxyproject.org/tutorials/g101/)是一个开源系统,让非计算用户能够做计算生物学。这是最广泛使用的,用户友好的管道系统。

龙哥盟 2163

Bioinformatics with Python Cookbook 第三版项目推荐

Bioinformatics with Python Cookbook 第三版项目推荐 项目基础介绍和主要编程语言 Bioinformatics with Python Cookbook 第三版 是一个专注于使用Python解决生物信息学问题的开源项目。该项目由Packt Publishing出版,旨在帮助生物信息学分析师、数据科学家、计算生物学家和研究人员利用现代Python库和应用程序来解决实...

gitblog_07913的博客 505

生物信息学

生物信息学

青少年趣味编程 1105
上一篇: Python 生物信息学秘籍第三版(三)
下一篇: Clojure 数据科学(一)
绝不原创的飞龙
绝不原创的飞龙 优质创作者: 人工智能、数据科学与机器学习技术领域 优质创作者: 人工智能、数据科学与机器学习技术领域
博客等级 码龄15年 4万+粉丝 2万+原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值