Processos Gaussianos em Estruturas de Dados Discretas

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Processos Gaussianos são uma ferramenta popular em aprendizado de máquina para tarefas de regressão e classificação. No entanto, eles normalmente exigem que os dados estejam em forma de vetor de características de comprimento fixo, o que pode ser limitador em alguns aplicativos. Neste laboratório, exploraremos como os processos Gaussianos podem ser usados em sequências de comprimento variável, como sequências gênicas, definindo uma função kernel que opera diretamente nesses tipos de estruturas. Usaremos o scikit-learn para implementar nossos modelos de processo Gaussiano.

Dicas da Máquina Virtual

Após o término da inicialização da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para você.

Definir SequenceKernel

Definimos uma classe SequenceKernel que herda das classes Kernel e GenericKernelMixin do scikit-learn. Este kernel define uma medida de similaridade entre sequências de comprimento variável. Ele faz isso usando a R-convolução, que envolve integrar um kernel binário de letra a letra sobre todos os pares de letras entre um par de strings. Podemos então usar este kernel para realizar tarefas de regressão e classificação em sequências.

import numpy as np
from sklearn.gaussian_process.kernels import Kernel, Hyperparameter
from sklearn.gaussian_process.kernels import GenericKernelMixin
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process import GaussianProcessClassifier
from sklearn.base import clone


class SequenceKernel(GenericKernelMixin, Kernel):
    """
    Um kernel convolucional mínimo (mas válido) para sequências de comprimentos variáveis.
    """

    def __init__(self, baseline_similarity=0.5, baseline_similarity_bounds=(1e-5, 1)):
        self.baseline_similarity = baseline_similarity
        self.baseline_similarity_bounds = baseline_similarity_bounds

    @property
    def hyperparameter_baseline_similarity(self):
        return Hyperparameter(
            "baseline_similarity", "numeric", self.baseline_similarity_bounds
        )

    def _f(self, s1, s2):
        """
        Valor do kernel entre um par de sequências.
        """
        return sum(
            [1.0 if c1 == c2 else self.baseline_similarity for c1 in s1 for c2 in s2]
        )

    def _g(self, s1, s2):
        """
        Derivada do kernel entre um par de sequências.
        """
        return sum([0.0 if c1 == c2 else 1.0 for c1 in s1 for c2 in s2])

    def __call__(self, X, Y=None, eval_gradient=False):
        if Y is None:
            Y = X

        if eval_gradient:
            return (
                np.array([[self._f(x, y) for y in Y] for x in X]),
                np.array([[[self._g(x, y)] for y in Y] for x in X]),
            )
        else:
            return np.array([[self._f(x, y) for y in Y] for x in X])

    def diag(self, X):
        return np.array([self._f(x, x) for x in X])

    def is_stationary(self):
        return False

    def clone_with_theta(self, theta):
        cloned = clone(self)
        cloned.theta = theta
        return cloned

Visualizar Matriz de Similaridade de Sequências

Podemos usar nosso SequenceKernel para calcular a matriz de similaridade entre sequências. Iremos plotar esta matriz usando uma escala de cores, onde cores mais brilhantes indicam maior similaridade.

import matplotlib.pyplot as plt

X = np.array(["AGCT", "AGC", "AACT", "TAA", "AAA", "GAACA"])

kernel = SequenceKernel()
K = kernel(X)
D = kernel.diag(X)

plt.figure(figsize=(8, 5))
plt.imshow(np.diag(D**-0.5).dot(K).dot(np.diag(D**-0.5)))
plt.xticks(np.arange(len(X)), X)
plt.yticks(np.arange(len(X)), X)
plt.title("Similaridade de sequências sob o kernel")
plt.show()

Realizar Regressão em Sequências

Podemos usar nosso SequenceKernel para realizar regressão em sequências. Usaremos um conjunto de dados de 6 sequências e usaremos as 1ª, 2ª, 4ª e 5ª sequências como conjunto de treinamento para fazer previsões nas 3ª e 6ª sequências.

X = np.array(["AGCT", "AGC", "AACT", "TAA", "AAA", "GAACA"])
Y = np.array([1.0, 1.0, 2.0, 2.0, 3.0, 3.0])

training_idx = [0, 1, 3, 4]
gp = GaussianProcessRegressor(kernel=kernel)
gp.fit(X[training_idx], Y[training_idx])

plt.figure(figsize=(8, 5))
plt.bar(np.arange(len(X)), gp.predict(X), color="b", label="predição")
plt.bar(training_idx, Y[training_idx], width=0.2, color="r", alpha=1, label="treinamento")
plt.xticks(np.arange(len(X)), X)
plt.title("Regressão em sequências")
plt.legend()
plt.show()

Realizar Classificação em Sequências

Podemos usar nosso SequenceKernel para realizar classificação em sequências. Usaremos um conjunto de dados de 6 sequências e treinarmos com base na presença de 'A's nas sequências. Em seguida, faremos previsões em outras 5 sequências, onde a verdade fundamental é simplesmente se existe pelo menos um 'A' na sequência. Aqui, fazemos quatro classificações corretas e falhamos em uma.

X_train = np.array(["AGCT", "CGA", "TAAC", "TCG", "CTTT", "TGCT"])
## se há 'A's na sequência
Y_train = np.array([True, True, True, False, False, False])

gp = GaussianProcessClassifier(kernel)
gp.fit(X_train, Y_train)

X_test = ["AAA", "ATAG", "CTC", "CT", "C"]
Y_test = [True, True, False, False, False]

plt.figure(figsize=(8, 5))
plt.scatter(
    np.arange(len(X_train)),
    [1.0 if c else -1.0 for c in Y_train],
    s=100,
    marker="o",
    edgecolor="none",
    facecolor=(1, 0.75, 0),
    label="treinamento",
)
plt.scatter(
    len(X_train) + np.arange(len(X_test)),
    [1.0 if c else -1.0 for c in Y_test],
    s=100,
    marker="o",
    edgecolor="none",
    facecolor="r",
    label="verdade",
)
plt.scatter(
    len(X_train) + np.arange(len(X_test)),
    [1.0 if c else -1.0 for c in gp.predict(X_test)],
    s=100,
    marker="x",
    facecolor="b",
    linewidth=2,
    label="predição",
)
plt.xticks(np.arange(len(X_train) + len(X_test)), np.concatenate((X_train, X_test)))
plt.yticks([-1, 1], [False, True])
plt.title("Classificação em sequências")
plt.legend()
plt.show()

Resumo

Neste laboratório, demonstramos como usar processos gaussianos em sequências de comprimento variável usando uma função de kernel personalizada. Mostramos como realizar tarefas de regressão e classificação em dados de sequência usando a biblioteca scikit-learn.