1. nozma

    No comment

    nozma
Changes in body
Source | HTML | Preview
@@ -5,13 +5,13 @@
### なにをやりたいのか
行列$X$を行列$W$と行列$H$の積で近似したい。
-$$ X \approx WH $$
+$$ X WH $$
-ここで$X$は1つが$N$個の値からなる$p$個のデータをまとめて1つにしたような$N\times p$行列で、これを分解するのだから$W$は$N$行でなければならないし、$H$は$p$列でなければならない。そして、$W$の列数=$H$の行数を$r$とすると、$W$の列として$r$個の基底ベクトルができる。
+ここで$X$は1つが$N$個の値からなる$p$個のデータをまとめて1つにしたような$N× p$行列で、これを分解するのだから$W$は$N$行でなければならないし、$H$は$p$列でなければならない。そして、$W$の列数=$H$の行数を$r$とすると、$W$の列として$r$個の基底ベクトルができる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109348/4545f5d8-5360-f7b5-9055-4113e7a62d0c.png)
NMFのNMFたる所以は、$X$も$W$も$H$もそのすべての成分が非負であることを要求するという点にある。
@@ -49,11 +49,11 @@
``` {.python}
import numpy as np
from sklearn.decomposition import NMF
```
-$X$としてはこんな感じのものを用意する(前述の説明とは行列の向きが違い、各行が1つのデータになっているので注意)
+$X$としてはこんな感じのものを用意する。
``` {.python}
X = [
[1, 1, 1, 0, 0, 0],
[1, 1, 1, 0, 0, 0],
@@ -71,40 +71,46 @@
``` {.python}
nmf = NMF(n_components=3)
nmf.fit(X)
```
-$W$に相当するものは`.components_`に格納されている。$H$に相当するものは`.transform(X)`とやると得られる。これもそれぞれ行列が最初の説明と逆なので注意
+$W$に相当するものは`.transform(X)`とやると得られる。$H$に相当するものは`.components_`に格納されている
まずは$W$を確認する。
``` {.python}
-# そのまま表示すると桁数がアレなので`np.round`で適当に丸める。
-print(np.round(nmf.components_, 1))
+W = nmf.fit_transform(X)
+print(np.round(W, 1))
```
- ## [[0. 0. 1.1 1.1 1.1 0. ]
- ## [0.9 0.9 0.9 0. 0. 0. ]
- ## [0. 0. 0. 1.3 1.3 1.3]]
-
+```
+[[0. 1.2 0. ]
+ [0. 1.2 0. ]
+ [0.9 0. 0. ]
+ [0.9 0. 0. ]
+ [0. 0. 0.8]
+ [0. 0. 0.8]]
+```
+
いい感じっぽい。ついで$H$を確認する。
``` {.python}
-print(np.round(nmf.transform(X), 1))
+H = nmf.components_
+print(np.round(H, 1))
```
- ## [[0. 1.2 0. ]
- ## [0. 1.2 0. ]
- ## [0.9 0. 0. ]
- ## [0.9 0. 0. ]
- ## [0. 0. 0.8]
- ## [0. 0. 0.8]]
-
+```
+[[0. 0. 1.1 1.1 1.1 0. ]
+ [0.9 0.9 0.9 0. 0. 0. ]
+ [0. 0. 0. 1.3 1.3 1.3]]
+```
+
$W$と$H$を掛けたら元の$X$が得られるはずだ。
``` {.python}
-print(np.round(np.dot(nmf.transform(X), nmf.components_), 1))
+WH = np.dot(W, H)
+print(np.round(WH, 1))
```
## [[1. 1. 1. 0. 0. 0.]
## [1. 1. 1. 0. 0. 0.]
## [0. 0. 1. 1. 1. 0.]