Fortsetzung der vorherigen "Implementieren von Perceptron-Lernregeln in Python" Dieses Mal habe ich die Widrow-Hoff-Lernregel, eine der Mustererkennungsmethoden, in Python implementiert, ohne eine Bibliothek zu verwenden. Ich bin ein Anfänger sowohl in Python als auch im maschinellen Lernen. Bitte weisen Sie auf schlechte Punkte hin.
Die Umrisse und Formeln der Lernregeln von Widrow-Hoff sind in der folgenden Folie (ab der Mitte der Folie) grob zusammengefasst.
https://speakerdeck.com/kirikisinya/xin-zhe-renaiprmlmian-qiang-hui-at-ban-zang-men-number-3
Für die Trainingsdaten, die in einer Dimension vorhanden sind, wie in der folgenden Abbildung gezeigt, und zu einer der beiden Klassen gehören, wird die Unterscheidungsfunktion jeder Klasse erhalten.
Als Umsetzungspunkt
Der eigentliche Code sieht folgendermaßen aus:
main.py
# coding: UTF-8
# #1D Witwe-Implementierungsbeispiel für Hoff-Lernregeln
import numpy as np
import matplotlib.pyplot as plt
from widrow_hoff import get_wvec
if __name__ == '__main__':
data = np.array([[1.0, 1],[0.5, 1],[-0.2, 2],[-0.4, 1],[-1.3, 2],[-2.0, 2]])#Datengruppe
features = data[:,0].reshape(data[:,0].size,1)#Merkmalsvektor
labels = data[:,1]#Klasse (diesmal c1=1,c2=2)
wvec = np.array([0.2, 0.3])#Anfangsgewichtsvektor
xvecs = np.c_[np.ones(features.size), features]#xvec[0] = 1
#Über Klasse 1
tvec1 = labels.copy()#Klasse 1 Lehrer Vektor
tvec1[labels == 1] = 1
tvec1[labels == 2] = 0
wvec1 = get_wvec(xvecs, wvec, tvec1)
print "wvec1 = %s" % wvec1
print "g1(x) = %f x + %f" % (wvec1[1], wvec1[0])
for xvec,label in zip(xvecs,labels):
print "g1(%s) = %s (Klasse:%s)" % (xvec[1],np.dot(wvec1, xvec), label)
#Über Klasse 2
tvec2 = labels.copy()#Klasse 2 Lehrer Vektor
tvec2[labels == 1] = 0
tvec2[labels == 2] = 1
wvec2 = get_wvec(xvecs, wvec, tvec2)
print "wvec2 = %s" % wvec2
print "g2(x) = %f x + %f" % (wvec2[1], wvec2[0])
for xvec,label in zip(xvecs,labels):
print "g2(%s) = %s (Klasse:%s)" % (xvec[1],np.dot(wvec, xvec), label)
widrow_hoff.py
# coding: UTF-8
#Widrow-Lernlogik von Hoffs Lernregeln
import numpy as np
#Den Gewichtskoeffizienten lernen
def train(wvec, xvecs, tvec):
low = 0.2#Lernkoeffizient
for key, w in zip(range(wvec.size), wvec):
sum = 0
for xvec, b in zip(xvecs, tvec):
wx = np.dot(wvec,xvec)
sum += (wx - b)*xvec[key]
wvec[key] = wvec[key] - low*sum
return wvec
#Finden Sie den Gewichtungskoeffizienten
def get_wvec(xvecs, wvec, tvec):
loop = 100
for j in range(loop):
wvec = train(wvec, xvecs, tvec)
return wvec
Wenn dies getan wurde, wurden die folgenden Ergebnisse erhalten.
Die Diskriminanzfunktion jeder Klasse ist wie folgt.
g1(x) = 0.37x + 0.69 #Diskriminanzfunktion der Klasse 1
g2(x) = -0.37x + 0.35 #Diskriminanzfunktion der Klasse 2
Außerdem lautet die Widrof-Hoff-Lernregel "g1 (x)> g2 (x)" für Daten der Klasse 1 und "g1 (x) <g2 (x)" für Daten der Klasse 2. Es war gut, wenn es "wurde (es kann gut identifiziert werden!).
Basierend darauf, wenn Sie sich das Ausführungsergebnis ansehen
・ Wenn Daten x = 1.0
(Klasse 1)
g1(1.0)
> g2(1.0)
=> OK
・ Wenn Daten "x = 0,5" (Klasse 1)
g1(0.5)
> g2(0.5)
=> OK
-Für Daten x = -0,2
(Klasse 2)
g1(-0.2)
> g2(-0.2)
=> NG
-Für Daten x = -0,4
(Klasse 1)
g1(-0.4)
= g2(-0.4)
=> NG
-Für Daten x = -1,3
(Klasse 2)
g1(-1.3)
< g2(-1.3)
=> OK
・ Für Daten x = -2.0
(Klasse 2)
g1(-2.0)
< g2(-2.0)
=> OK
Daher sind die Daten "x = -0,2" und "x = -0,4" nahe der Mitte von Klasse 1 und Klasse 2 nicht gut identifiziert (falsche Identifizierung), und die anderen sind gut identifiziert. Dieses Ergebnis steht im Einklang mit der Intuition, dass es schwierig ist, nahe der Mitte der Klasse zu unterscheiden, und es wird angenommen, dass die Diskriminanzfunktion gut bestimmt ist.
Recommended Posts