[PYTHON] Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)

Einführung

Schritt für Schritt zur Theorie, Implementierung in Python und Analyse mit scikit-learn über den Algorithmus, der zuvor in "Klassifikation des maschinellen Lernens" verwendet wurde. Ich werde mit lernen. Ich schreibe es zum persönlichen Lernen, daher möchte ich, dass Sie alle Fehler übersehen.

Letztes Mal wurde die Klassifizierung für zwei Klassen auf die Klassifizierung für mehrere Klassen erweitert. Dieses Mal werde ich es tatsächlich in Python implementieren.

Ich habe auf die folgenden Seiten verwiesen. Vielen Dank.

Implementierungsrichtlinie

Ich möchte Zuvor implementierte logistische Regression auf mehrere Klassen ausweiten. Die Methode ist

Ich werde es versuchen.

Daten zur Klassifizierung verwendet

Ayame-Daten werden zur Klassifizierung verwendet. Es wird in 3 Klassen (setosa, versicolor, virginica) mit 4 Merkmalsgrößen (sepal_length, sepal_width, petal_length, petal_width) eingeteilt.

Im Folgenden werden wir der Übersichtlichkeit halber die Klassifizierung mit sepal_length und sepal_width implementieren.

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

from sklearn.datasets import load_iris

sns.set()
iris = sns.load_dataset("iris")
ax = sns.scatterplot(x=iris.sepal_length, y=iris.sepal_width,
                     hue=iris.species, style=iris.species)
qiita_classifier_multi_1.png

One-vs-Rest One-vs-Rest erstellt einen Zwei-Klassen-Klassifikator für jede zu lernende Label-Klasse und verwendet schließlich den plausibelsten Wert. Da die logistische Regression einen Wahrscheinlichkeitswert ausgibt, wird die Klassifizierung des Klassifikators mit der höchsten Wahrscheinlichkeit übernommen.

Wir werden die LogisticRegression-Klasse verwenden, eine leicht modifizierte Version des logistischen Regressionscodes, den wir zuletzt verwendet haben. Ich habe eine "Predict_Proba" -Methode erstellt, weil sie bestimmt, welcher Wert mit einer Wahrscheinlichkeit verwendet werden soll.

from scipy import optimize

class LogisticRegression:
  def __init__(self):
    self.w = None

  def sigmoid(self, a):
    return 1.0 / (1 + np.exp(-a))

  def predict_proba(self, x):
    x = np.hstack([1, x])
    return self.sigmoid(self.w.T @ x)
  
  def predict(self, x):
    return 1 if self.predict_proba(x)>=0.5 else -1

  def cross_entropy_loss(self, w, *args):
    def safe_log(x, minval=0.0000000001):
      return np.log(x.clip(min=minval))
    t, x = args
    loss = 0
    for i in range(len(t)):
      ti = 1 if t[i] > 0 else 0
      h = self.sigmoid(w.T @ x[i])
      loss += -ti*safe_log(h) - (1-ti)*safe_log(1-h)

    return loss/len(t)

  def grad_cross_entropy_loss(self, w, *args):
    t, x = args
    grad = np.zeros_like(w)
    for i in range(len(t)):
      ti = 1 if t[i] > 0 else 0
      h = self.sigmoid(w.T @ x[i])
      grad += (h - ti) * x[i]

    return grad/len(t)

  def fit(self, x, y):
    w0 = np.ones(len(x[0])+1)
    x = np.hstack([np.ones((len(x),1)), x])

    self.w = optimize.fmin_cg(self.cross_entropy_loss, w0, fprime=self.grad_cross_entropy_loss, args=(y, x))

  @property
  def w_(self):
    return self.w

Implementieren Sie die One-vs-Rest-Klasse. Ich habe auch die Methode "Genauigkeit_Wert" implementiert, um zu berechnen, wie korrekt die Antwort ist, da ich sie später für den Algorithmusvergleich verwenden werde.

from sklearn.metrics import accuracy_score

class OneVsRest:
  def __init__(self, classifier, labels):
    self.classifier = classifier
    self.labels = labels
    self.classifiers = [classifier() for _ in range(len(self.labels))]

  def fit(self, x, y):
    y = np.array(y)
    for i in range(len(self.labels)):
      y_ = np.where(y==self.labels[i], 1, 0)
      self.classifiers[i].fit(x, y_)

  def predict(self, x):
    probas = [self.classifiers[i].predict_proba(x) for i in range(len(self.labels))]
    return np.argmax(probas)

  def accuracy_score(self, x, y):
    pred = [self.labels[self.predict(i)] for i in x]
    acc = accuracy_score(y, pred)
    return acc

Klassifizieren Sie tatsächlich anhand der vorherigen Daten.

model = OneVsRest(LogisticRegression, np.unique(iris.species))
x = iris[['sepal_length', 'sepal_width']].values
y = iris.species
model.fit(x, y)
print("accuracy_score: {}".format(model.accuracy_score(x,y)))

accuracy_score: 0.8066666666666666

Die richtige Rücklaufquote von 81% ist nicht sehr gut. Lassen Sie uns visualisieren, wie es klassifiziert wurde. Verwenden Sie zur Visualisierung die Konturmethode von matplotlib. Farben, nach denen der Wert auf dem Gitterpunkt klassifiziert wird.

from matplotlib.colors import ListedColormap

x_min = iris.sepal_length.min()
x_max = iris.sepal_length.max()
y_min = iris.sepal_width.min()
y_max = iris.sepal_width.max()

x = np.linspace(x_min, x_max, 100)
y = np.linspace(y_min, y_max, 100)

data = []
for i in range(len(y)):
  data.append([model.predict([x[j], y[i]]) for j in range(len(x))])

xx, yy = np.meshgrid(x, y)

cmap = ListedColormap(('blue', 'orange', 'green'))
plt.contourf(xx, yy, data, alpha=0.25, cmap=cmap)
ax = sns.scatterplot(x=iris.sepal_length, y=iris.sepal_width,
                     hue=iris.species, style=iris.species)
plt.show()
qiita_classifier_multi_2.png

Wie Sie sehen können, ist setosa richtig klassifiziert, aber die verbleibenden zwei Klassen sind gemischt, so dass die richtige Antwortrate anscheinend etwas niedrig ist. Vorerst wird es so sein.

Mehrklassen-Soft max

Implementieren Sie die LogisticRegressionMulti-Klasse für die Softmax-Klassifizierung in der logistischen Regression.

Der Kreuzentropiefehler wurde als Fehlerfunktion für die Bewertung verwendet, und die Parameter wurden unter Verwendung der Methode des steilsten Gradientenabfalls berechnet. Ich habe es ganz richtig gemacht, tut mir leid

from sklearn.metrics import accuracy_score

class LogisticRegressionMulti:
  def __init__(self, labels, n_iter=1000, eta=0.01):
    self.w = None
    self.labels = labels
    self.n_iter = n_iter
    self.eta = eta
    self.loss = np.array([])

  def softmax(self, a):
    if a.ndim==1:
      return np.exp(a)/np.sum(np.exp(a))
    else:
      return np.exp(a)/np.sum(np.exp(a), axis=1)[:, np.newaxis]

  def cross_entropy_loss(self, w, *args):
    x, y = args
    def safe_log(x, minval=0.0000000001):
      return np.log(x.clip(min=minval))
    
    p = self.softmax(x @ w)
    loss = -np.sum(y*safe_log(p))

    return loss/len(x)

  def grad_cross_entropy_loss(self, w, *args):
    x, y = args

    p = self.softmax(x @ w)
    grad = -(x.T @ (y-p))

    return grad/len(x)

  def fit(self, x, y):
    self.w = np.ones((len(x[0])+1, len(self.labels)))
    x = np.hstack([np.ones((len(x),1)), x])

    for i in range(self.n_iter):
      self.loss = np.append(self.loss, self.cross_entropy_loss(self.w, x, y))
      grad = self.grad_cross_entropy_loss(self.w, x, y)
      self.w -= self.eta * grad
  
  def predict(self, x):
    x = np.hstack([1, x])
    return np.argmax(self.softmax(x @ self.w))

  def accuracy_score(self, x, y):
    pred = [self.predict(i) for i in x]
    y_ = np.argmax(y, axis=1)

    acc = accuracy_score(y_, pred)
    return acc

  @property
  def loss_(self):
    return self.loss

Die Eingabe in "LogisticRegressionMulti" verwendet ein One-Hot-Encoded-Label. Mit Pandas 'get_dummies` ist das ganz einfach. (Ich dachte, nachdem ich es gemacht habe, aber ich hätte get_dummies in der Klasse verwenden sollen)

model = LogisticRegressionMulti(np.unique(iris.species), n_iter=10000, eta=0.1)
x = iris[['sepal_length', 'sepal_width']].values
y = pd.get_dummies(iris['species']).values
model.fit(x, y)
print("accuracy_score: {}".format(model.accuracy_score(x, y)))

accuracy_score: 0.8266666666666667

Die richtige Antwortrate liegt bei 83%. Wenn man sich die Fehlerhistorie ansieht, scheint sie konvergiert zu sein, also scheint es so.

qiita_classifier_multi_3.png

Lassen Sie uns auch die Klassifizierung auf die gleiche Weise wie zuvor ausmalen.

qiita_classifier_multi_4.png

Vergleichen Sie mit der logistischen Regression von scikit-learn

Vergleichen Sie schließlich unter Verwendung aller Funktionen den diesmal erstellten Klassifikator mit der LogisticRegression-Klasse von scikit-learn.

Methode accuracy_score
OneVsRest 0.98
LogisticRegressionMulti 0.98
sklearn LogisticRegression 0.973

Selbst mit dieser Implementierung scheint es, dass Sie eine gute Punktzahl erzielen können, wenn es um die Klassifizierung von Ayame geht.

Zusammenfassung

Mehrklassenklassifizierung mithilfe logistischer Regression implementiert. Ich bin der Meinung, dass andere Klassifikatoren auf ähnliche Weise verwendet werden können. Insbesondere in neuronalen Netzen ist Softmax mit mehreren Klassen eine gängige Methode, daher hielt ich es für nützlich, den theoretischen Teil später zu verstehen.

Recommended Posts

Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
Zusammenfassung der Klassifizierung und Implementierung von Algorithmen für maschinelles Lernen
Klassifikation des maschinellen Lernens
Algorithmus für maschinelles Lernen (Verallgemeinerung der linearen Regression)
Python & Machine Learning Study Memo ⑤: Klassifikation von Ayame
Algorithmus für maschinelles Lernen (von der Klassifizierung in zwei Klassen bis zur Klassifizierung in mehreren Klassen)
Klassifizierung von Gitarrenbildern durch maschinelles Lernen Teil 2
Techniken im Zusammenhang mit maschinellem Lernen / Klassifizierung
Grundlagen des maschinellen Lernens (Denkmal)
Über das Testen bei der Implementierung von Modellen für maschinelles Lernen
Lernen mit dem Lehrer 1 Grundlagen des Lernens mit dem Lehrer (Klassifizierung)
Algorithmus für maschinelles Lernen (einfaches Perzeptron)
Bedeutung von Datensätzen für maschinelles Lernen
Überwachtes maschinelles Lernen (Klassifikation / Regression)
Algorithmus für maschinelles Lernen (Support Vector Machine)
Tiefes Lernen der Verstärkung 2 Implementierung des Lernens der Verstärkung
Algorithmus für maschinelles Lernen (logistische Regression)
Python Machine Learning Programming Kapitel 2 Klassifizierungsprobleme - Zusammenfassung des Trainingsalgorithmus für maschinelles Lernen
Versuchen Sie, die Leistung des Modells für maschinelles Lernen / Klassifizierung zu bewerten
<Kurs> Maschinelles Lernen Kapitel 6: Algorithmus 2 (k-Mittel)
Erklärung und Implementierung des ESIM-Algorithmus
Bedeutung des maschinellen Lernens und des Mini-Batch-Lernens
Qiskit: Implementierung einer Quantenbolzenmaschine
Algorithmus für maschinelles Lernen (Unterstützung von Vektor-Maschinenanwendungen)
Maschinelles Lernen mit Python (1) Gesamtklassifizierung
Algorithmus für maschinelles Lernen (multiple Regressionsanalyse)
Maschinelles Lernen ③ Zusammenfassung des Entscheidungsbaums
Algorithmus für maschinelles Lernen (Einzelregressionsanalyse)
Klassifikation und Regression beim maschinellen Lernen
Algorithmus für maschinelles Lernen (Gradientenabstiegsmethode)
Implementierung der Dyxtra-Methode durch Python
Maschinelles Lernen
Multi-Class Multi-Label-Klassifizierung von Bildern mit Pytorch
Deep Learning 2 durch Implementierung gelernt (Bildklassifizierung)
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (3)
[Maschinelles Lernen] LDA-Themenklassifizierung mit Scikit-Learn
Implementierung eines 3-Schicht-Neuronalen Netzwerks (kein Lernen)
2020 Empfohlen 20 Auswahlmöglichkeiten für einführende Bücher zum maschinellen Lernen
Erklärung und Implementierung des Decomposable Attention-Algorithmus
[Maschinelles Lernen] Liste der häufig verwendeten Pakete
Algorithmus für maschinelles Lernen (Zusammenfassung und Regularisierung der linearen Regression)
EV3 x Pyrhon Maschinelles Lernen Teil 3 Klassifizierung
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (2)
Maschinelles Lernen eines jungen Ingenieurs Teil 1
Gaußscher EM-Algorithmus mit gemischtem Modell [statistisches maschinelles Lernen]
Beginn des maschinellen Lernens (empfohlene Unterrichtsmaterialien / Informationen)
Maschinelles Lernen des Sports - Analyse der J-League als Beispiel - ②
[Super Einführung] Maschinelles Lernen mit Python - Von der Umgebungskonstruktion bis zur Implementierung von Simple Perceptron-
Numerai Turnier-Fusion von traditionellen Quants und maschinellem Lernen-
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
Python & Machine Learning Study Memo Introduction: Einführung in die Bibliothek
SVM (Mehrklassenklassifikation)
Wörterbuch-Lernalgorithmus
Liste der Links, die Anfänger des maschinellen Lernens lernen
Überblick über maschinelle Lerntechniken, die aus Scikit-Learn gelernt wurden
Über die Entwicklungsinhalte des maschinellen Lernens (Beispiel)
Zusammenfassung der beim maschinellen Lernen verwendeten Bewertungsfunktionen
Analyse der gemeinsamen Raumnutzung durch maschinelles Lernen