[PYTHON] Lernen Sie während der Implementierung mit Scipy die Grundlagen der logistischen Regression und des mehrschichtigen Perzeptrons

In Optimierung wie Interpolation und Kurvenanpassung haben wir gelernt, wie verschiedene Kurven approximiert werden. Welche Kurve sollten wir also approximieren, wenn $ Y $ nur $ 0 $ oder $ 1 $ hat, wie folgt?

X1 = [4.7, 4.5, 4.9, 4.0, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 
      3.5, 4.2, 4.0, 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 
      4.8, 4.0, 4.9, 4.7, 4.3, 4.4, 4.8, 5.0, 4.5, 3.5, 
      3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4.0, 
      4.4, 4.6, 4.0, 3.3, 4.2, 4.2, 4.2, 4.3, 3.0, 4.1, 
      6.0, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 
      5.1, 5.3, 5.5, 5.0, 5.1, 5.3, 5.5, 6.7, 6.9, 5.0, 
      5.7, 4.9, 6.7, 4.9, 5.7, 6.0, 4.8, 4.9, 5.6, 5.8, 
      6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 
      5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5.0, 5.2, 5.4, 5.1]

Y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Lassen Sie uns die Daten vorerst veranschaulichen.

%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(12,4))
plt.scatter(X1, Y)
plt.grid()
plt.show()

output_3_1.png

Logistische Rückgabe

Um eine solche Beziehung zu approximieren, verwenden wir "Logistic Regression", die eine Sigmoidkurve approximiert. Lassen Sie es uns mit scipy.optimize.curve_fit implementieren.

#Lassen Sie uns eine Python-Liste in ein Numpy-Array konvertieren.
import numpy as np
X1 = np.array(X1)
Y = np.array(Y)

Die erklärende Variable nähert sich einer Sigmoidkurve an

Definiert eine Sigmoidkurve func1 mit einer erklärenden Variablen. Sie optimieren $ a $ und $ b $.

import numpy as np
def func1(X, a, b): #Sigmaid-Kurve
    f = a + b * X
    return 1. / (1. + np.exp(-f))

Ein Beispiel für die Verwendung von func1 sieht so aus.

func1(X1, 1, 1)
array([0.99666519, 0.99592986, 0.99726804, 0.99330715, 0.99631576,
       0.99592986, 0.99666519, 0.98661308, 0.99631576, 0.99260846,
       0.98901306, 0.9945137 , 0.99330715, 0.99666519, 0.9900482 ,
       0.99550373, 0.99592986, 0.9939402 , 0.99592986, 0.99260846,
       0.99698158, 0.99330715, 0.99726804, 0.99666519, 0.9950332 ,
       0.99550373, 0.99698158, 0.99752738, 0.99592986, 0.98901306,
       0.99183743, 0.9909867 , 0.99260846, 0.99776215, 0.99592986,
       0.99592986, 0.99666519, 0.99550373, 0.9939402 , 0.99330715,
       0.99550373, 0.99631576, 0.99330715, 0.98661308, 0.9945137 ,
       0.9945137 , 0.9945137 , 0.9950332 , 0.98201379, 0.9939402 ,
       0.99908895, 0.99776215, 0.99899323, 0.99864148, 0.99888746,
       0.9994998 , 0.99592986, 0.99932492, 0.99888746, 0.99917558,
       0.99776215, 0.99816706, 0.99849882, 0.99752738, 0.99776215,
       0.99816706, 0.99849882, 0.99954738, 0.99962939, 0.99752738,
       0.9987706 , 0.99726804, 0.99954738, 0.99726804, 0.9987706 ,
       0.99908895, 0.99698158, 0.99726804, 0.99864148, 0.99888746,
       0.99917558, 0.99938912, 0.99864148, 0.99776215, 0.99864148,
       0.99917558, 0.99864148, 0.99849882, 0.99698158, 0.9983412 ,
       0.99864148, 0.99776215, 0.99776215, 0.99899323, 0.9987706 ,
       0.99797468, 0.99752738, 0.99797468, 0.9983412 , 0.99776215])

Verwenden Sie scipy.optimize.curve_fit, um die optimale Lösung für $ a $ und $ b $ zu erhalten.

from scipy.optimize import curve_fit  
popt, pcov = curve_fit(func1,X1,Y) #popt ist die optimale Schätzung, pcov ist die Kovarianz
popt
array([-47.16056308,   9.69474387])

Dies ist die optimale Lösung für $ a $ und $ b $.

Wenn $ X_1 $ unter Verwendung der erhaltenen optimalen Lösung zur Sigmoidkurve zurückgegeben wird, wird der vorhergesagte Wert von $ Y $ "korrekt als 1 klassifiziert, wenn vorhergesagt wird, ob er als 0 oder 1 klassifiziert ist". Es kann als "Wahrscheinlichkeit des Seins" interpretiert werden. Schauen wir uns die Verteilung dieser Wahrscheinlichkeit an.

plt.figure(figsize=(12,4))
plt.hist(func1(X1, -47.16056308,   9.69474387))
plt.grid()
plt.show()

output_13_0.png

Wenn $ X_1 $ unter Verwendung der erhaltenen optimalen Lösung zur Sigmoidkurve zurückgeführt wird, wird die folgende Abbildung erhalten. Die blauen Punkte sind die Originaldaten, die Kurven sind die Regressionskurven und die orangefarbenen Punkte sind die Daten nach der Regression. Diese vertikale Achse ist "die Wahrscheinlichkeit, dass die Klassifizierung in $ 1 $ korrekt ist, wenn vorhergesagt wird, ob sie als $ 0 $ oder $ 1 $ klassifiziert wird".

output_15_0.png

Herausforderung 1

Verwenden Sie matplotlib, um die Regressionskurve wie oben gezeigt zu veranschaulichen.

Schätzung der Vorhersagegenauigkeit

Die tatsächliche Klassifizierung ($ 0 $ oder $ 1 $) befindet sich in einer Variablen namens $ Y $. Wenn Sie einen Schwellenwert festlegen, können Sie berechnen, wie genau er ist, z. B. als $ 1 $ klassifizieren, wenn der durch die Regression erhaltene Wert $ 0,5 $ oder mehr beträgt, und $ 0 $, wenn er weniger als $ 0,5 $ beträgt. Hier,

Wird besorgt.

Herausforderung 2

Es gibt verschiedene Bewertungsindizes. Das einfachste hier

Berechnen Sie "Genauigkeit = (TP + TN) / (TP + FP + FN + TN)".

Zeigen Sie auch die Wahrscheinlichkeitsverteilung für jedes "TP", "FP", "FN", "TN", wie in der folgenden Abbildung gezeigt.

print("Accuracy: ", len(TP + TN) / len(TP + FP + FN + TN))
plt.figure(figsize=(12,4))
plt.hist([TP, FP, FN, TN], label=['TP', 'FP', 'FN', 'TN'], color=['blue', 'green', 'orange', 'red'])
plt.legend()
plt.grid()
plt.show()

output_20_1.png

Die erklärende Variable approximiert zwei Sigmoidkurven

Versuchen wir den Fall mit zwei erklärenden Variablen.

X2 = [1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 
      1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 
      1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 
      1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 
      1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 
      2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 
      2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 
      2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 
      1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 
      2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8]

X = np.array([X1, X2])

Die erklärenden Variablen definieren eine Sigmoidkurve "func2" mit zwei. Sie optimieren $ a $, $ b $ und $ c $.

Herausforderung 3

Abbildung der Regressionsfläche

Da es zwei erklärende Variablen gibt, handelt es sich um eine "gekrümmte Regressionsfläche" anstelle einer "Regressionskurve". Verwenden wir "matplotlib", um das 3D-Diagramm als Referenz zu veranschaulichen.

N = 1000
x1_axis = np.linspace(min(X[0]), max(X[0]), N)
x2_axis = np.linspace(min(X[1]), max(X[1]), N)
x1_grid, x2_grid = np.meshgrid(x1_axis, x2_axis)
x_mesh = np.c_[np.ravel(x1_grid), np.ravel(x2_grid)]

Angenommen, die resultierenden $ a $, $ b $ und $ c $ haben die folgenden Werte:

y_plot = func2(x_mesh.T, -34.73855674,   4.53539756,   7.68378862).reshape(x1_grid.shape)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(x1_grid, x2_grid, y_plot, cmap='bwr', linewidth=0)
fig.colorbar(surf)
ax.set_title("Surface Plot")
fig.show()

output_32_0.png

Das Wichtigste dabei ist, dass wir zur Sigmoidkurve (oder gekrümmten Oberfläche) zurückkehren, aber wenn wir sie als Klassifizierungsproblem betrachten, ist die Klassifizierungsgrenze eine "gerade Linie" (oder Ebene).

Näher an einer multivariaten Sigmoidkurve

Lassen Sie es uns verbessern, damit es mehr erklärende Variablen verarbeiten kann.

X3 = [7.0, 6.4, 6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2, 
      5.0, 5.9, 6.0, 6.1, 5.6, 6.7, 5.6, 5.8, 6.2, 5.6, 
      5.9, 6.1, 6.3, 6.1, 6.4, 6.6, 6.8, 6.7, 6.0, 5.7, 
      5.5, 5.5, 5.8, 6.0, 5.4, 6.0, 6.7, 6.3, 5.6, 5.5, 
      5.5, 6.1, 5.8, 5.0, 5.6, 5.7, 5.7, 6.2, 5.1, 5.7, 
      6.3, 5.8, 7.1, 6.3, 6.5, 7.6, 4.9, 7.3, 6.7, 7.2, 
      6.5, 6.4, 6.8, 5.7, 5.8, 6.4, 6.5, 7.7, 7.7, 6.0, 
      6.9, 5.6, 7.7, 6.3, 6.7, 7.2, 6.2, 6.1, 6.4, 7.2, 
      7.4, 7.9, 6.4, 6.3, 6.1, 7.7, 6.3, 6.4, 6.0, 6.9, 
      6.7, 6.9, 5.8, 6.8, 6.7, 6.7, 6.3, 6.5, 6.2, 5.9]

X4 = [3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 
      2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 
      3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 
      2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 
      2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8, 
      3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6, 
      3.2, 2.7, 3.0, 2.5, 2.8, 3.2, 3.0, 3.8, 2.6, 2.2, 
      3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3.0, 2.8, 3.0, 
      2.8, 3.8, 2.8, 2.8, 2.6, 3.0, 3.4, 3.1, 3.0, 3.1, 
      3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0]

X = np.array([X1, X2, X3, X4])

Verbessern Sie die Funktion, um eine beliebige Anzahl erklärender Variablen aufzunehmen.

import numpy as np
def func(X, *params):
    f = np.zeros_like(X[0])
    for i, param in enumerate(params):
        if i == 0:
            f = f + param
        else:
            f = f + np.array(param * X[i - 1])
    return 1. / (1. + np.exp(-f))

Übung 4

Siehe Optimierung wie Interpolation und Kurvenanpassung.

Empfehlung von scikit-learn

Die obige Berechnung wird als "logistische Regression" bezeichnet. Die logistische Regression wird als eine der "Klassifizierungs" -Methoden beim maschinellen Lernen verwendet. Dieses Mal bestand der Zweck darin, die logistische Regression und die Verwendung von "scipy.optimize.curve_fit" zu verstehen. Praktisch ist es jedoch praktisch, mit einer maschinellen Lernbibliothek namens "scikit-learn" zu rechnen.

Mehrschichtiges Perceptron

Multilayer Perceptron (MLP) ist eine Art neuronales Vorwärtsausbreitungsnetzwerk, das aus mindestens drei Knotenschichten besteht (Eingangsschicht "X", verborgene Schicht "H", Ausgangsschicht "O"). Jeder andere Knoten als der Eingabeknoten ist ein Neuron, das eine nichtlineare Aktivierungsfunktion verwendet und nichtlinear trennbare Daten mithilfe einer überwachten Lerntechnik identifizieren kann, die als Backpropagation bezeichnet wird. .. Eine der als nichtlineare Aktivierungsfunktion verwendeten Funktionen ist die Sigmoidfunktion.

Dieses Mal werde ich MLP mit scipy.optimize.curve_fit wie folgt implementieren.

def mlp(X, *params):
    h01, h02, h03, h04, h0b = params[0], params[1], params[2], params[3], params[4]
    h11, h12, h13, h14, h1b = params[5], params[6], params[7], params[8], params[9]
    h21, h22, h23, h24, h2b = params[10], params[11], params[12], params[13], params[14]

    o01, o02, o03, o0b = params[15], params[16], params[17], params[18]

    h0 = 1. / (1. + np.exp(-(h01 * X[0] + h02 * X[1] + h03 * X[2] + h04 * X[3] + h0b)))
    h1 = 1. / (1. + np.exp(-(h11 * X[0] + h12 * X[1] + h13 * X[2] + h14 * X[3] + h1b)))
    h2 = 1. / (1. + np.exp(-(h21 * X[0] + h22 * X[1] + h23 * X[2] + h24 * X[3] + h2b)))

    o0 = 1. / (1. + np.exp(-(o01 * h0 + o02 * h1 + o03 * h2 + o0b)))

    return o0

Herausforderung 5

Scikit-Learn und Pytorch

MLP hat die einfachste Konfiguration von Methoden des maschinellen Lernens, die als Deep Learning bezeichnet werden. Dieses Mal bestand der Zweck darin, MLP und die Verwendung von "scipy.optimize.curve_fit" zu verstehen. In der Praxis ist es jedoch praktisch, Berechnungen mit Bibliotheken wie "scicit-learn" und "pytorch" durchzuführen.

Referenzartikel: Von der linearen multiplen Regression zur logistischen Regression regeln mit PyTorch mehrschichtiges Perzeptron und Auto-Encoder

Recommended Posts

Lernen Sie während der Implementierung mit Scipy die Grundlagen der logistischen Regression und des mehrschichtigen Perzeptrons
Implementierung der logistischen Regression mit NumPy
Sehen Sie, wie schnell Sie mit NumPy / SciPy beschleunigen können
Ich lernte die Grundlagen des intensiven Lernens und spielte mit Cart Pole (Implementierung von einfachem Q-Lernen).
Lernen Sie die Grundlagen von Python ① Grundlegende Anfänger
[Python] Ich habe die Theorie und Implementierung der logistischen Regression gründlich erklärt
Lernen Sie noch einmal die Grundlagen von Theano
Lernen Sie die Grundlagen, während Sie Python-Variablen berühren
Visualisieren Sie den Grenzwert des mehrschichtigen Perzeptrons
Überprüfen Sie das Konzept und die Terminologie der Regression
[Linux] Lernen Sie die Grundlagen von Shell-Befehlen
Ich habe die Geschwindigkeit der Listeneinschlussnotation für und während mit Python2.7 gemessen.
Lernen Sie mit Jubatus die Trends von Feature-Wörtern in Texten kennen und kategorisieren Sie Ihre Eingabetexte
Ich habe den gleitenden Durchschnitt des IIR-Filtertyps mit Pandas und Scipy verglichen
Mit PyTorch viel regeln, von linearer multipler Regression bis hin zu logistischer Regression, mehrschichtigem Perzeptron und Autoencoder
Lerne Nim mit Python (ab Anfang des Jahres).
Visualisieren Sie den Bereich der internen und externen Einfügungen mit Python
Berechnen Sie den Regressionskoeffizienten der einfachen Regressionsanalyse mit Python
Lineare multiple Regression, logistische Regression, mehrschichtiges Perzeptron, Auto-Encoder, Chainer Yo!
Lösen des Irisproblems mit scikit-learn ver1.0 (logistische Regression)
Animieren Sie die Grundlagen der dynamischen Planung und Rucksackprobleme
Perceptron Grundlagen und Implementierung
Die Gründung der Perceptron-Stiftung
Grundlagen der Regressionsanalyse
Die Geschichte der Implementierung des Themas Facebook Messenger Bot mit Python
Spielen Sie mit dem Passwortmechanismus von GitHub Webhook und Python