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()
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)
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()
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".
Verwenden Sie matplotlib, um die Regressionskurve wie oben gezeigt zu veranschaulichen.
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.
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()
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 $.
func2
und benutze scipy.optimize.curve_fit
, um die optimale Lösung für die Koeffizienten $ a $, $ b $ und $ c $ zu erhalten.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()
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).
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))
Siehe Optimierung wie Interpolation und Kurvenanpassung.
func
, um eine Vorhersage nur mit der ersten Variablen $ X_1 $ zu treffen und den Prozentsatz der richtigen Antworten zu berechnen.func
, um eine Vorhersage nur mit den ersten beiden Variablen $ X_1 $ und $ X_2 $ zu treffen und die richtige Antwortrate zu berechnen.func
, um eine Vorhersage nur mit den ersten drei Variablen $ X_1 $, $ X_2 $ und $ X_3 $ zu treffen und die richtige Antwortrate zu berechnen.func
, um eine Vorhersage unter Verwendung aller vier Variablen $ X_1 $, $ X_2 $, $ X_3 $, $ X_4 $ zu treffen und die richtige Antwortrate zu berechnen.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.
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
mlp
, um eine Vorhersage unter Verwendung aller vier Variablen $ X_1 $, $ X_2 $, $ X_3 $, $ X_4 $ zu treffen und die richtige Antwortrate zu berechnen.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