numpy memmapを利用する

やりたいこと

numpy arrayを使った行列計算をしたい。

が、マシンスペックから行列をメモリ上に保持しておくことができない。

どうするか?

解決策

arrayをディスクに保存しておき、一気にすべてのarrayをメモリに載せなくてもいいようにする。

こんな解決策があるよ。と教えてもらったので、さっそく、中身を読んでみる。

どうやら、ディスクに保存しておくには2つのやり方があるようだ。

1 pytableを使う。

2 numpy memmapを使う(numpy nd arrayのサブクラス)

1を試してみようとするも、いろんなところでつまって、よくわからん?状態に。

ならば、ということで、2のmemmapを使ってみる。

scipyの公式サイトに公式ドキュメントが乗っているので、これをそのまま試してみる。

In [5]: data = np.arange(12, dtype='float32')

In [6]: data.resize((3,4))

In [7]: data
Out[7]: 
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]], dtype=float32)

In [16]: fp = np.memmap('tmp.dat', dtype='float32', mode='w+', shape=(3,4))

In [17]: fp
Out[17]: 
memmap([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]], dtype=float32)

In [18]: fp[:] = data[:]

In [19]: fp
Out[19]: 
memmap([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]], dtype=float32)

先頭にmemmapと表記されていることから、きっとこのarrayはディスク上のtmp.datにその実体があるのだろう。

memmapってscikit-learnにも使えるの?

問題はここである。

もし、memmap型のarrayがscikit-learnで使えなければ、いままでの機械学習お手軽コードは書き換えが必要になってしまう。

そこで、PCA(要は固有値計算)にmemmapが適応できるのか?試してみた。

In [26]: from sklearn.decomposition import PCA

In [29]: pca = PCA(n_components=2)

In [30]: pca.fit(newfp)
Out[30]: PCA(copy=True, n_components=2, whiten=False)

In [31]: data_low = pca.transform(newfp)


In [32]: data_low
Out[32]: 
array([[  8.00000000e+00,  -2.38418579e-07],
       [  0.00000000e+00,   0.00000000e+00],

できた。

ただ、一個気がかりなのは、出力がarray型になっていること。

実は、PCA内部で一気にメモリ上にarrayをロードしているのではないか??とちょっと心配している。