Dieser Artikel ist der Artikel zum 6. Tag von Furukawa Lab Advent_calendar. Dieser Artikel wurde von einem Studenten des Furukawa Lab als Teil seines Lernens geschrieben. Der Inhalt kann mehrdeutig sein oder der Ausdruck kann leicht abweichen.
Da ich über NMF studiert habe, werde ich es auf leicht verständliche Weise erklären. Was ist NMF? Ich hoffe, es hilft denen, die zum ersten Mal NMF studieren (* ^^) v In der zweiten Hälfte wird der Lernzustand visualisiert. NMF(Non-negative Matrix Factorization) NMF zerlegt die Matrix $ Y $ unter nicht negativen Randbedingungen in zwei nicht negative Wertmatrizen $ W und H $ und approximiert sie. Mit anderen Worten, es sieht aus wie in der Abbildung unten.
Der Punkt ist, dass die Matrix $ Y, W, H, \ hat {Y} $ alle nicht negativ sind (keine negativen Werte). Das heißt, $ Y \ geq0, W \ geq0, H \ geq0, \ hat {Y} \ geq0 $. Im NMF-Algorithmus wird $ W, H $ aktualisiert, sodass $ \ hat {Y} $, das innere Produkt von $ W, H $, den Originaldaten $ Y $ so nahe wie möglich kommt. Wenn Sie die Aktualisierungsformel finden, sind einige Teile schwer analytisch zu berechnen. Ersetzen Sie daher die Formel durch Jensens Ungleichung. Die Aktualisierungsformel ist am Ende aufgeführt. (Bei Verwendung von Frobenius)
\begin{equation}
\begin{aligned}
D_{\mathrm{EU}}(\boldsymbol{W}, \boldsymbol{H}) &=\|\boldsymbol{Y}-\boldsymbol{W} \boldsymbol{H}\|_{F}^{2} \\
&=\sum_{m, n}\left|y_{m, n}-\sum_{k} w_{m, k} h_{k, n}\right|^{2}\\
&=\sum_{m, n}\left(\left|y_{m, n}\right|^{2}-2 x_{m, n} \sum_{k} w_{m, k} h_{k, n}+\underset{Analytische Schwierigkeit}{\left|\sum_{k} w_{m, k} h_{k, n}\right|^{2}}\right)
\end{aligned}
\end{equation}
\begin{equation}
\lambda_{k, m, n}=\frac{w_{m, k} h_{k, n}}{\sum_{k} w_{m, k} h_{k, n}}
\end{equation}
\begin{equation}
G:=\sum_{m, n}\left(\left|y_{m, n}\right|^{2}-2 y_{m, n} \sum_{k} w_{m, k} h_{k, n}+\sum_{k} \frac{w_{m, k}^{2} h_{k, n}^{2}}{\lambda_{k, m, n}}\right)
\end{equation}
Die folgenden zwei Gleichungen werden erhalten, indem die obige Gleichung teilweise differenziert wird. Die optimalen $ W und H $ werden erhalten, indem die folgende Formel für die Anzahl der Lernzeiten wiederholt wird.
\begin{equation}
\begin{aligned}
w_{m k} \leftarrow w_{m k} \frac{(\boldsymbol{Y} \boldsymbol{H})_{m n}}{\left(\boldsymbol{W} \boldsymbol{H} \boldsymbol{H}^{T}\right)_{m k}}
\end{aligned}
\end{equation}
\begin{equation}
\begin{aligned}
h_{k n} \leftarrow h_{k n} \frac{\left(\boldsymbol{W}^{T} \boldsymbol{Y}\right)_{m n}}{\left(\boldsymbol{W}^{T} \boldsymbol{W} \boldsymbol{H}\right)_{m n}}
\end{aligned}
\end{equation}
Lassen Sie uns NMF zum besseren Verständnis in Python implementieren! Hier werden wir die zweidimensionalen Koordinaten mit NMF approximieren. Die Abbildung links zeigt eine Darstellung von 80 Punkten, wobei der linearen Funktion Rauschen hinzugefügt wird. Nennen wir dies diesmal die Beobachtungsdaten $ Y $. Wenn diese Daten $ Y $ von NMF zerlegt und wiederhergestellt werden, wird die Abbildung rechts erhalten ($ \ hat {Y} $). Sie können es gut approximieren. Als nächstes werde ich $ W und H $ erklären. In zweidimensionalen Koordinaten können $ W und H $ als Gewichte und Basisvektoren interpretiert werden. Dieses Mal kann $ W $ als Gewicht und $ H $ als Basisvektor interpretiert werden. Die Abbildung rechts zeigt die tatsächliche Darstellung des Basisvektors. Mit anderen Worten kann der Datenpunkt durch Addieren dieser beiden Vektoren ausgedrückt werden.
Hier werden wir den Lernzustand visualisieren. ~~ Was bedeutet es zu visualisieren? ~~ Die Abbildung links ist der Datenpunkt, der mit der Funktion $ cos $ erstellt wurde. Die Abbildung rechts zeigt das Lernen mit NMF.
python code Es wird der Code der Animation sein.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anm
import matplotlib.cm as cm
from sklearn.decomposition import NMF
from sklearn import decomposition
np.random.seed(seed=32)
def true_fun(X):
return np.cos(X)**2
X=np.random.rand(80)*4+0.2
Y=true_fun(X)
Y=Y+np.random.normal(0,0.1,80)+1
x=np.zeros([80,2])
x[:,0]=X
x[:,1]=Y
k = 2
m, n = 80, 2
t=0
vecter_x=0,0
vecter_y=0,0
np.random.seed(seed=32)
U = np.abs(np.random.uniform(low=0, high=1, size=(m, k)))
V = np.abs(np.random.uniform(low=0, high=1, size=(n, k)))
xx=np.arange(50)
fig = plt.figure(figsize=(10,4.5))
def update(t):
global U,V
U = U * np.dot(x, V) / np.dot(np.dot(U, V.T), V)
V = V * np.dot(U.T, x).T / np.dot(U.T, np.dot(U, V.T)).T
NMF = np.dot(U, V.T)
print(NMF.shape)
plt.subplot(122)
plt.cla()
plt.title(t)
plt.xlim((0, 4.5))
plt.ylim((0, 3.3))
plt.scatter(NMF[:,0], NMF[:,1],s=60,cmap='blues',color=cm.jet((NMF[:,0]*0.25)),edgecolors='black',linewidths=0.1)
plt.quiver(0,0,V[0,1],V[0,0],angles='xy',scale_units='xy',scale=1)
plt.quiver(0,0,V[0,1],V[1,0],angles='xy',scale_units='xy',scale=1)
plt.subplot(121)
plt.cla()
plt.xlim((0, 4.5))
plt.ylim((0, 3.3))
plt.scatter(X, Y,s=60,cmap='blues',color=cm.jet((x[:,0]*0.25)),edgecolors='black',linewidths=0.1)
ani = anm.FuncAnimation(fig, update,interval = 200, frames = 50)
#ani.save("NMF_cos2.gif", writer = 'imagemagick') #Wird beim Speichern verwendet
[1] https://qiita.com/nozma/items/d8dafe4e938c43fb7ad1 [2] http://r9y9.github.io/blog/2013/07/27/nmf-euclid/ [3] https://qiita.com/mamika311/items/d920be626c343bcb423a [4] https://qiita.com/sumita_v09/items/d22850f41257d07c45ea
Recommended Posts