Jetzt, da ich für die runde Vortragspräsentation in Kapitel 4 von "Mustererkennung und maschinelles Lernen" verantwortlich bin, möchte ich über das, was ich studiert habe, und einen kleinen Kommentar schreiben. Ich bin einer der Menschen, die mit diesem Buch zu kämpfen haben, daher würde ich mich sehr freuen, wenn es hilfreich wäre, wenn es in Zukunft Menschen mit ähnlichen Umständen gibt. Wenn Sie mathematische Fehler finden oder darauf hinweisen, dass dies besser ist, zögern Sie bitte nicht, uns zu kontaktieren.
Der Begriff der Diskriminanzfunktion beginnt mit dem minimalen Quadrat, aber das minimale Quadrat wird weggelassen, da die Schlussfolgerung gezogen wird, dass "es natürlich ist, dass es nicht gut verwendet werden kann". Also aus der 2. Klasse Fisher. Hier betrachten wir die lineare Diskriminierung aus der Perspektive der Dimensionsreduktion.
Erhalten Sie einen D-dimensionalen Vektor als Eingabe und projizieren Sie ihn mit der folgenden Formel auf eine Dimension
python
y = \boldsymbol{w}^T\boldsymbol{x}
Setzen Sie einen Schwellenwert in $ y $ und klassifizieren Sie ihn in die Klasse $ C_1 $, wenn $ y \ ge -w_0 $, andernfalls klassifizieren Sie ihn in $ C_2 $. Informationsverlust tritt auf, wenn die Dimension gelöscht wird. Daher möchte ich $ \ boldsymbol {w} $ anpassen, um die Klassentrennung zu maximieren.
Unter der Annahme, dass es $ N_1 $ Punkte in der Klasse $ C_1 $ und $ N_2 $ Punkte in $ C_2 $ gibt, ist hier der durchschnittliche Vektor jeder Klasse
python
\boldsymbol{m}_1 = \frac{1}{N_1}\sum_{n \in C_1}\boldsymbol{x}_n, \quad
\boldsymbol{m}_2 = \frac{1}{N_2}\sum_{n \in C_2}\boldsymbol{x}_n
Wählen Sie zu diesem Zeitpunkt basierend auf der Idee "Lassen Sie uns projizieren, wo die Durchschnittswerte der Klassen am weitesten voneinander entfernt sind" $ \ boldsymbol {w} $ aus, um die folgende Formel zu maximieren.
python
m_2 - m_1 = \boldsymbol{w}^T(\boldsymbol{m}_2 - \boldsymbol{m}_1)
Hier repräsentiert $ m_k $ den Durchschnitt der von $ C_k $ projizierten Daten. Da es bedeutungslos ist, wenn $ \ boldsymbol {w} $ so weit wie möglich erhöht werden kann, wird eine Einschränkung von norm = 1 hinzugefügt. Die unentschlossene Multiplikatormethode des sogenannten Lagrange kommt ins Spiel. Wenn Sie die Grundlagen der Vektordifferenzierung kennen, gibt es kein Problem.
python
L = \boldsymbol{w}^T(\boldsymbol{m}_2 - \boldsymbol{m}_1) + \lambda(\boldsymbol{w}^T\boldsymbol{w}-1)\\
\\
\nabla L=(\boldsymbol{m}_2 - \boldsymbol{m}_1)+2\lambda\boldsymbol{w}\\
\\
\boldsymbol{w}=-\frac{1}{2\lambda}(\boldsymbol{m}_2 - \boldsymbol{m}_1)\propto(\boldsymbol{m}_2 - \boldsymbol{m}_1)
In der Realität kann dies jedoch immer noch dazu führen, dass sich die Klassen überlappen. Daher möchte ich eine Methode wie "dieselbe Klasse wird nach der Projektion zusammen gruppiert und die Klassen werden voneinander getrennt" verwenden. Aus diesem Grund haben wir die Diskriminierungskriterien von Fisher eingeführt. Klasseninterne Verteilung jeder Klasse
python
s_k^2 = \sum_{n \in C_k}(y_k - m_k)^2
Daher sind die Unterscheidungskriterien wie folgt
python
J(\boldsymbol{w}) = \frac{(m_2-m_1)^2}{s_1^2 + s_2^2}
Der Nenner ist die Verteilung innerhalb der Gesamtklasse, definiert durch die Summe der Verteilungen jeder Klasse. Die Moleküle sind zwischen Klassen verteilt. In diesem Abschnitt wird dies wie folgt umgeschrieben.
python
J(\boldsymbol{w}) = \frac{\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w}}{\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w}}
Hier
python
\boldsymbol{S}_\boldsymbol{B} = (\boldsymbol{m}_2 - \boldsymbol{m}_1)(\boldsymbol{m}_2 - \boldsymbol{m}_1)^T\\
\\
\boldsymbol{S}_\boldsymbol{W} =\sum_{k}\sum_{n\in C_k}(\boldsymbol{x}_n-m_k)(\boldsymbol{x}_n-m_k)
^T
Ersteres wird als Interklassen-Kovarianzmatrix bezeichnet, und Letzteres wird als Gesamt-Intraklassen-Kovarianzmatrix bezeichnet. Ich war verwirrt, weil es für mich etwas schwierig aussah, aber wenn ich es mit der Tatsache erweitere, dass sowohl der Nenner als auch das Molekül $ y = \ boldsymbol {w} ^ T \ boldsymbol {x} $ sind, das Original Es stellt sich heraus, dass es das gleiche wie die Formel ist.
Daher kann durch Differenzieren von J (w) in Bezug auf w und Setzen auf Null ein w erhalten werden, das J maximiert.
python
\frac{\partial J}{\partial w}=\frac{(2(\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w})(\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w})-2(\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w})(\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w}))}{(\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w})^2}=0\\
\\\\
(\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w})(\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w}) = (\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w})(\boldsymbol{w}^T\boldsymbol{S}_\boldsymbol{W}\boldsymbol{w})
$ \ Boldsymbol {w} ^ T \ boldsymbol {S} _ \ boldsymbol {W} \ boldsymbol {w} $ ist ein Skalar und die Kovarianzmatrix ist eine symmetrische Matrix, wenn die quadratische Form unterschieden wird Der Punkt ist, dass ich es benutze. Ich werde darüber in einem anderen Artikel schreiben.
Nach wie vor ist diesmal die Ausrichtung von $ \ boldsymbol {w} $ wichtig, nicht die Größe, also $ \ boldsymbol {S} _ \ boldsymbol {B} \ boldsymbol {w} $
python
\boldsymbol{S}_\boldsymbol{B}\boldsymbol{w} = (\boldsymbol{m}_2 - \boldsymbol{m}_1)(\boldsymbol{m}_2 - \boldsymbol{m}_1)^T\boldsymbol{w}
Indem Sie die Tatsache ausnutzen, dass es sich um einen Vektor in der gleichen Richtung wie $ (\ boldsymbol {m} _2- \ boldsymbol {m} _1) $ handelt
python
\boldsymbol{w} \propto \boldsymbol{S}_\boldsymbol{W}^-1(\boldsymbol{m}_2 - \boldsymbol{m}_1)
Nun, da die Richtung von w festgelegt wurde, ist es das!
fisher_2d.py
# Class 1
mu1 = [5, 5]
sigma = np.eye(2, 2)
c_1 = np.random.multivariate_normal(mu1, sigma, 100).T
# Class 2
mu2 = [0, 0]
c_2 = np.random.multivariate_normal(mu2, sigma, 100).T
# Average vectors
m_1 = np.sum(c_1, axis=1, keepdims=True) / 100.
m_2 = np.sum(c_2, axis=1, keepdims=True) / 100.
# within-class covariance matrix
S_W = np.dot((c_1 - m_1), (c_1 - m_1).T) + np.dot((c_2 - m_2), (c_2 - m_2).T)
w = np.dot(np.linalg.inv(S_W), (m_2 - m_1))
w = w/np.linalg.norm(w)
plt.quiver(4, 2, w[1, 0], -w[0, 0], angles="xy", units="xy", color="black", scale=0.5)
plt.scatter(c_1[0, :], c_1[1, :])
plt.scatter(c_2[0, :], c_2[1, :])
Hier ist das Ergebnis der Darstellung des mit dem Köcher erhaltenen Vektors
Die Richtung ist gut. Also werde ich das nächste Mal über die Mehrklassenversion schreiben.