質問

そこで、非常にまばらな、つまりゼロがたくさんある numpy 配列を使用して Kmeans 分類を行っています。scipyの「sparse」パッケージを使用してストレージのオーバーヘッドを削減しようと考えましたが、行列ではなく配列を作成する方法について少し混乱しています。

スパース行列の作成方法については、次のチュートリアルを実行しました。http://www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7

配列を模倣するには、1xN 行列を作成するだけですが、ご想像のとおり、2 つの 1xN 行列を乗算できないため、Asp.dot(Bsp) は完全に機能しません。各配列を Nx1 に転置する必要がありますが、すべての内積計算でそれを行うことになるため、これはかなり面倒です。

次に、列 1 == 行 1 である NxN 行列を作成しようとしました (2 つの行列を掛けて、左上隅を内積として取得できるようなものです) が、これは非常に非効率であることが判明しました。

scipy の sparse パッケージを numpy の array() の魔法の代替品として使用したいと思っていますが、まだ、何をすればよいのかよくわかりません。

何かアドバイス?

役に立ちましたか?

解決

を使用し、行または列ベースであるscipy.sparse形式:csc_matrixcsr_matrix

(乗算を含む)ボンネットの下にこれらの使用効率のよい、Cの実装、および転置は何もしません(特にあなたがtranspose(copy=False)を呼び出す場合)、ちょうどnumpyの配列と同じように。

EDITます:

ipython を経由して、いくつかのタイミング
import numpy, scipy.sparse
n = 100000
x = (numpy.random.rand(n) * 2).astype(int).astype(float) # 50% sparse vector
x_csr = scipy.sparse.csr_matrix(x)
x_dok = scipy.sparse.dok_matrix(x.reshape(x_csr.shape))

x_csrx_dokある50%スパースます:

print repr(x_csr)
<1x100000 sparse matrix of type '<type 'numpy.float64'>'
        with 49757 stored elements in Compressed Sparse Row format>

そしてタイミングます:

timeit numpy.dot(x, x)
10000 loops, best of 3: 123 us per loop

timeit x_dok * x_dok.T
1 loops, best of 3: 1.73 s per loop

timeit x_csr.multiply(x_csr).sum()
1000 loops, best of 3: 1.64 ms per loop

timeit x_csr * x_csr.T
100 loops, best of 3: 3.62 ms per loop

私はうそを告げたように見えるので。転位はを非常に安いのですが、CSRのない効率的なCの実装では、(最新のscipyのダウンロード0.9.0で)CSCは*ありません。新しいCSRオブジェクトが呼び出しごとに構築される: - (

ハックとして(scipyのダウンロードは、これらの日は比較的安定しているが)、あなたがまばらなデータを直接内積を行うことができます:

timeit numpy.dot(x_csr.data, x_csr.data)
10000 loops, best of 3: 62.9 us per loop

は、この最後のアプローチは再びnumpyの密な乗算を行います。それが2倍dot(x, x)よりも、実際に高速ですので、スパース性は、50%である。

他のヒント

あなたは、既存の2D疎配列の1

のサブクラスを作成することができます
from scipy.sparse import dok_matrix

class sparse1d(dok_matrix):
    def __init__(self, v):
        dok_matrix.__init__(self, (v,))
    def dot(self, other):
        return dok_matrix.dot(self, other.transpose())[0,0]

a=sparse1d((1,2,3))
b=sparse1d((4,5,6))
print a.dot(b)

それが実際にはるかに優れているか、より高速であるかはわかりませんが、転置の使用を避けるためにこれを行うことはできます。

Asp.multiply(Bsp).sum()

これは、2 つの行列の要素ごとの積を取得し、その積を合計するだけです。使用している行列形式のサブクラスを作成して、上記のステートメントを内積として持つことができます。

ただし、おそらく、これらを転置する方が簡単です。

Asp*Bsp.T

やるべきことはそれほど多くないようですが、サブクラスを作成して、 マル() 方法。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top