Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Lineare Klassifizierung

Lineare Klassifizierung

In diesem Abschnitt werden wir die Grundlagen der linearen Klassifizierung durch einen einfachen ML-Algorithmus, das Perceptron, behandeln. Darüber hinaus werden wir die Konzepte hinter dem Perceptron-Algorithmus erweitern, indem wir Aspekte der *Regularisierung * berücksichtigen, um einen linearen Margin-Klassifikator zu erstellen.

Hyperflugzeuge

Angenommen, wir möchten positive und negative Objekte aus dem Trainingssatz unten klassifizieren (Abbildung links):

decisionbound

Figure 1:Training set of points with binary labels (+1, -1) and two-dimensional (x1,x2)(x_1, x_2) features. The decision boundary (grey line) is defined by the parameter vector θ\theta, which is normal to the decision boundary, and offset parameter θ0\theta_0 that linearly separates the data.

Der obige Datensatz wird als linear trennbar angesehen, da er mindestens eine lineare Entscheidungsgrenze existiert, die in der Lage ist, den gesamten Datensatz korrekt aufzuteilen. Zum Beispiel könnten wir eine Entscheidungsgrenze wie die graue Linie oben (Abbildung rechts) überschreiten.

In this case, since the features (x1,x2)R2(x_1, x_2) \in \mathbb{R}^2 , that is, the feature set belongs to the two-dimensional space, the decision boundary constitutes a line. If we were dealing with a set of features in the three-dimensional space (x1,x2,x3)(x_1, x_2, x_3), the decision boundary would be a plane. Analogously, if our feature set were in a higher-dimensional space, the decision boundary would constitute a hyperplane.

A hyperplane with dd dimensions is conventionally denoted by the vector normal to the plane, θRd\theta \in \mathbb{R}^d, and offset (scalar) parameter θ0\theta_0. In the example above, we would define the hyperplane (or decision boundary) as:

θX+θ0=0[θ1θ2][x1x2]+θ0=0\theta \cdot X + \theta_0 =0 \equiv \begin{bmatrix} \theta_1 & \theta_2 \end{bmatrix} \cdot \begin{bmatrix} x_1 \\ x_2 \end{bmatrix} + \theta_0 = 0

Unser Klassifikator h(x,θ,θ0)h(x, \theta, \theta_0) ist somit gleich sign(θX+θ0)sign(\theta \cdot X + \theta_0), wobei θR2\theta \in \mathbb{R}^2 und θ0R\theta_0 \in \mathbb{R}. Erinnern Sie sich an die Zeichenfunktion, auch bekannt als Signum-Funktion, ist eine mathematische Funktion, die das Zeichen oder die Richtung einer reellen Zahl zurückgibt. Das heißt, wenn die Eingabenummer positiv, negativ oder 0 ist, gibt die Vorzeichenfunktion +1, -1 bzw. 0 zurück.

Perceptron-Algorithmus

In the perceptron algorithm, we typically initialize θ\theta as zero (zero vector) and loop through the pair of training examples. At every iteration, we will check if the classifier makes a mistake classifying that training example (i-th example), and if so, then we update the parameters of θ\theta.

Assume that θ0=0\theta_0 =0 for simplicity (the decision boundary must pass through the origin). Our perceptron classifier will make a mistake if y(i)(θx(i))0y^{(i)}(\theta \cdot x^{(i)}) \leq 0. We will then update our θ\theta to no longer misclassify that training example. The way to do this is by adding y(i)x(i)y^{(i)}x^{(i)} to the previous θ\theta. Thus, the update would look like:

θ=θ+y(i)x(i)\theta = \theta + y^{(i)}x^{(i)}

We have in hands a set of different training examples which have the potential to nudge/update our classifier in many directions. Thus, it is possible and even expected that the last training examples cause updates that will overwrite earlier, initial updates. This will result that earlier examples will no longer be correctly classified. For this reason, we need to loop through the whole training set multiple TT times to ensure that all examples are correctly classified. Such iterations can be performed both in order or randomly selected from the training examples.

Wir können den Algorithmus wie folgt codieren:

import numpy as np


# Algorithm always starting to loop from x1
def perceptron(X, y, theta, t_times):
    n_mistakes = 0

    # Initialize list to show the progress (updates) of theta
    progress_theta = []

    # Initialize an array with same size as the total number of examples to count how many mistake are made at each training example
    explicit_mistakes = np.zeros(shape=y.shape[0])

    # Loop through the training set T times
    for t in t_times:

        # Loop through the training examples in order
        for index, x in enumerate(X):

            # Check if the algorithm makes a mistake in the i-th (or index-th) example
            if y[index] * np.dot(theta, x) <= 0:
                # Update theta to no longer misclassify the i-th example
                theta = theta + y[index] * x

                # Save the update theta
                progress_theta.append(theta)

                # Update total number of mistakes
                n_mistakes += 1

                # Update total number of mistakes at the i-th training example
                explicit_mistakes[index] += 1
    print('The perceptron did {} mistakes until convergence'.format(n_mistakes))
    return progress_theta, n_mistakes, explicit_mistakes


if __name__ == '__main__':
    X = np.array([[-1, -1], [1, 0], [-1, 1.5]])
    # X = np.array([[-1, -1], [1, 0], [-1, 10]])

    y = np.array([1, -1, 1])

    t_times = range(0, 100)

    theta = np.array([-1, -1])

    a, b, c = perceptron(X, y, theta, t_times)

Margin-Grenzen und Scharnierverlust

Wie Sie vielleicht bemerkt haben, verfügt der Perceptron-Algorithmus über keinen Regularisierungsbegriff. Das Ziel war einfach, eine Entscheidungsgrenze zu finden, die die Daten korrekt aufteilen kann. Hier werden wir das Konzept von *Hindernisverlust * und *Margengrenzen * vorstellen, um das Problem des Erlernens einer Entscheidungsgrenze in ein Optimierungsproblem unter Berücksichtigung der Regularisierung zu verwandeln.

Motivation hinter Margengrenzen

Werfen wir einen Blick auf unseren zuvor vorgestellten Trainingsdatensatz (Abbildung unten). Jede Entscheidungsgrenze innerhalb der gestrichelten grauen Linien teilt die Trainingsbeispiele korrekt auf. Wir möchten jedoch intuitiv eine Entscheidungsgrenze bevorzugen, die die Abstände zwischen der Entscheidungsgrenze und den Trainingspunkten maximieren kann. Der Grund dafür ist, dass die Punkte, die wir in Zukunft klassifizieren möchten, wahrscheinlich ein statistisches Rauschen haben, so dass eine Entscheidungsgrenze, die zu nahe an den Trainingsbeispielen liegt, eher leicht veränderte (lautere) Versionen der Trainingsbeispiele falsch klassifiziert. Im Gegensatz dazu wird ein Klassifikator, der eine relativ höhere Marge zwischen der Entscheidungsgrenze und den Beispielen hat, wahrscheinlich erfolgreicher bei der Klassifizierung zukünftiger, unsichtbarer Daten sein.

marginbound

Figure 3:Trainingssatz von Punkten mit binären Labels (+1, -1) im zweidimensionalen Feature Space (x1,x2)(x_1, x_2). Jede Entscheidungsgrenze innerhalb der gestrichelten grauen Linien kann die Daten korrekt aufteilen.

Optimierungsproblem

Denken Sie daran, dass es unser Ziel ist, einen linearen Klassifikator zu finden, der die Abstände zwischen der Entscheidungsgrenze und den Trainingspunkten maximiert (margin linearer Klassifikator), aber auch den Trainingsfehler minimiert. Dies stellt somit ein Optimierungsproblem dar, das diese beiden Faktoren ausgleichen muss, die wir als Folgendes angeben können:

Grenzgrenzen

Previously, we saw that the equation defining a decision boundary satisfies θX+θ0=0\theta \cdot X + \theta_0 =0.

Wir können nun parallele Randgrenzen (gestrichelte Linie in der vorherigen Abbildung) als definieren:

θX+θ0=±1\theta \cdot X + \theta_0 = \pm 1

Note that we can define the boundaries like this because we have a degree of freedom in our definition of the decision boundary, namely, the magnitude of the normal vector θ\| \theta \|. That is, regardless of the value θ\| \theta \|, our decision boundary remains unaltered.

Erinnern Sie sich an das Problem der Berechnung der kleinste Abstand eines Punktes zu einem Flugzeug]. Dieser Abstand beträgt:

θx(i)+θ0θ\frac{\theta \cdot x^{(i)} + \theta_0 }{\| \theta \|}

Wir können nun den signierten Abstand zwischen der Entscheidungsgrenze und dem i-ten Beispiel berechnen als:

γi(θ,θ0)=θx(i)+θ0θ\gamma_i (\theta, \theta_0) = \frac{\theta \cdot x^{(i)} + \theta_0 }{\| \theta \|}

Der Abstand zwischen den Randgrenzen und der Entscheidungsgrenze beträgt somit:

γi(θ,θ0)=1θ\gamma_i (\theta, \theta_0) = \frac{1}{\| \theta \|}

Gelenkverlust

We so far know that sign(θx(i)+θ0)sign(\theta \cdot x^{(i)} + \theta_0 ) will classify the i-th example. The way to know if the classification agrees with the label is by multiplying it by y(i)y^{(i)}. We can express this agreement also in a slightly modified version, using the hinge loss:

Lossh(z)={=0    if    z1=1z    if    <1Loss_h(z)= \begin{cases} = 0 \;\; \mbox{if} \;\; z \geq 1 \\ =1-z \;\; \mbox{if} \;\;< 1\end{cases}

Dabei ist zz die Vereinbarung (signierte Entfernung von der Entscheidungsgrenze) y(i)(θx(i)+θ0)y^{(i)}(\theta \cdot x^{(i)}+\theta_0).

Die folgende Abbildung zeigt, wie der Scharnierverlust entlang der z-Achse (Abstand von der Grenze) funktioniert, wie in dieser ResearchGate-Publikation] gezeigt:

hinge-loss-function

Zielfunktion

So now we can create an objective function that (1) minimizes the average hinge loss over the training examples, and (2) maximizes 1θ\frac{1}{\| \theta \|}. Expression (2) can be also reformulated towards minimizing 12θ2\frac{1}{2}\| \theta \|^2. Thus we define the objective function as:

C(θ,θ0)=1ni=1nLossh(y(i)(θx(i)+θ0))+λ2θ2C(\theta, \theta_0) = \frac{1}{n}\sum_{i=1}^n Loss_h(y^{(i)}(\theta \cdot x^{(i)}+\theta_0)) + \frac{\lambda}{2} \| \theta \|^2

where λ\lambda is the regularization parameter that balances the importance of minimizing the regularization term λ2θ2\frac{\lambda}{2}\| \theta \|^2 at the cost of incurring more losses (increasing the loss term). Vice versa, the smaller the value of λ\lambda, the more emphasis we will give to minimizing average loss.