Gaußsche Prozesse auf diskreten Datenstrukturen

Machine LearningMachine LearningBeginner
Jetzt üben

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

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Gauß-Prozesse sind ein beliebtes Werkzeug in der maschinellen Lernen für Regression- und Klassifizierungstasks. Allerdings erfordern sie normalerweise, dass die Daten in Form von Featurevektoren fester Länge vorliegen, was in bestimmten Anwendungen einschränkend sein kann. In diesem Lab werden wir untersuchen, wie Gauß-Prozesse auf variablen Sequenzen wie Gensequenzen angewendet werden können, indem wir eine Kernfunktion definieren, die direkt auf diesen Strukturen operiert. Wir werden scikit-learn verwenden, um unsere Gauß-Prozessmodelle zu implementieren.

Tipps für die VM

Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Operationen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie während des Lernens Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.

Definiere SequenceKernel

Wir definieren eine Klasse SequenceKernel, die von den Klassen Kernel und GenericKernelMixin von scikit-learn erbt. Dieser Kernel definiert ein Ähnlichkeitsmaß zwischen Sequenzen von variabler Länge. Dies geschieht mithilfe von R-Konvolution, die das Integrieren eines binären zeichenweise Kerns über alle Paare von Zeichen in einem Paar von Zeichenketten umfasst. Wir können dann diesen Kernel verwenden, um Regression- und Klassifizierungstasks auf Sequenzen durchzuführen.

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):
    """
    Ein minimaler (aber gültiger) konvolutionaler Kernel für Sequenzen von
    variabler Länge."""

    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):
        """
        Kernelwert zwischen einem Paar von Sequenzen
        """
        return sum(
            [1.0 if c1 == c2 else self.baseline_similarity for c1 in s1 for c2 in s2]
        )

    def _g(self, s1, s2):
        """
        Kernelableitung zwischen einem Paar von Sequenzen
        """
        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

Visualisiere die Sequenzähnlichkeitsmatrix

Wir können unseren SequenceKernel verwenden, um die Ähnlichkeitsmatrix zwischen Sequenzen zu berechnen. Wir werden diese Matrix mit einer Farbskala plotten, wobei hellere Farben eine höhere Ähnlichkeit anzeigen.

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("Sequence similarity under the kernel")
plt.show()

Führe Regression auf Sequenzen durch

Wir können unseren SequenceKernel verwenden, um Regression auf Sequenzen durchzuführen. Wir werden einen Datensatz von 6 Sequenzen verwenden und die 1., 2., 4. und 5. Sequenz als Trainingsmenge verwenden, um Vorhersagen für die 3. und 6. Sequenz zu machen.

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="prediction")
plt.bar(training_idx, Y[training_idx], width=0.2, color="r", alpha=1, label="training")
plt.xticks(np.arange(len(X)), X)
plt.title("Regression on sequences")
plt.legend()
plt.show()

Führe Klassifizierung auf Sequenzen durch

Wir können unseren SequenceKernel verwenden, um Klassifizierung auf Sequenzen durchzuführen. Wir werden einen Datensatz von 6 Sequenzen verwenden und trainieren, ob in der Sequenz 'A's vorhanden sind. Wir werden dann Vorhersagen für weitere 5 Sequenzen machen, wobei die tatsächlichen Werte einfach darauf abzielen, ob in der Sequenz mindestens ein 'A' vorhanden ist. Hierbei machen wir vier richtige Klassifizierungen und verfehlen eine.

X_train = np.array(["AGCT", "CGA", "TAAC", "TCG", "CTTT", "TGCT"])
## ob in der Sequenz 'A's vorhanden sind
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="training",
)
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="truth",
)
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="prediction",
)
plt.xticks(np.arange(len(X_train) + len(X_test)), np.concatenate((X_train, X_test)))
plt.yticks([-1, 1], [False, True])
plt.title("Classification on sequences")
plt.legend()
plt.show()

Zusammenfassung

In diesem Lab haben wir gezeigt, wie man Gaussian-Prozesse auf Sequenzen von variabler Länge mit einer benutzerdefinierten Kernfunktion anwendet. Wir haben gezeigt, wie man Regression- und Klassifizierungstasks auf Sequenzdaten mit scikit-learn durchführt.