問題タブ [dirichlet]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
0 に答える
35 参照

r - DirichletMultinomial Rパッケージで「混合」と「予測」が異なる結果をもたらすのはなぜですか

私は DirichletMultinomial R パッケージを使用して、データセットのクラスタリングを構築しています。今、私が構築したモデルを使用して、これらのグループを別のデータセットで予測したいと思います。それを行う前に、元のデータセットで予測を使用したところ、その結果に驚きました。

DirichletMultinomial パッケージに含まれている Twins データセットでそれを行うと、次の結果が得られますが、これはほとんど同じように見えます。

しかし、データセットでそれを行うと、いくつかの不一致があり (特に最後の 2 行で)、それがどこから来たのかわかりません。メソッドの動作方法を誤解したのかもしれませんが、混合と予測でほぼ同じ結果が得られると期待していました。ここでどのように間違っていますか?

0 投票する
1 に答える
462 参照

numpy - Python でのランダム直交行列の効率的な生成

仕事のためにランダムな平均不変直交行列をたくさん生成する必要があります。平均不変行列にはプロパティ がありますA*1_n=1_n。ここで、1_n はスカラー 1 のサイズ n のベクトルであり、基本的にnp.ones(n)です。Python、特に Numpy を使用して行列を作成していますが、自分の方法が正しく、最も効率的であることを確認したいと考えています。また、私が試した 3 つの別々の直交化方法に関する調査結果を提示し、うまくいけば、ある方法が他の方法よりも高速である理由について説明したいと思います。投稿の最後で、調査結果について 4 つの質問をします。

一般に、平均不変ランダム直交行列 A を作成するには、ランダム正方行列 M1 を作成し、その最初の列を 1 の列に置き換えて、行列を直交化する必要があります。次に、別の行列 M2 を使用してこれを繰り返します。最終的な平均不変ランダム直交行列は A = M1*(M2.T) です。このプロセスのボトルネックは直交化です。直交化には主に 3 つの方法があります。つまり、射影を使用するグラム・シュミット過程、鏡映とギブンス回転を使用するハウスホルダー変換です。

Numpy: を使用すると、nxn ランダム行列を簡単に作成できます M1 = np.random.normal(size=(n,n))。次に、M1 の最初の列を 1_n に置き換えます。

私が知る限り、Gram-Schmidt プロセスは非常に人気のあるライブラリには存在しないため、問題なく動作する次のコードを見つけました。

明らかに、上記のコードは M1 と M2 の両方に対して実行する必要があります。

10,000x10,000 ランダム平均不変直交行列の場合、このプロセスは私のコンピューター (8 コア @3.7GHz、16GB RAM、512GB SSD) で約1 時間かかります。

Gram-Schmidt プロセスの代わりに、Numpy で行列を直交化できることがわかりました。 q1, r1 = np.linalg.qr(M1) ここで、q1 は直交化された行列で、r1 は上三角行列です (r1 を保持する必要はありません)。M2 に対しても同じことを行い、q2 を取得します。次に、A=q1*(q2.T)。同じ 10,000x10,000 マトリックスのこのプロセスは、同じコンピューターで約70 秒かかります。ライブラリはハウスホルダー変換を使用していると思いますlinalg.qr()が、誰かに確認してもらいたいです。

最後に、最初の乱数行列 M1 と M2 が生成される方法を変更しようとしました。代わりに M1 = np.random.normal(size=(n,n))、ディリクレ分布: を使用しました M1 = np.random.default_rng().dirichlet(np.ones(n),size=(n))。その後、linalg.qr()以前のようなものを使用して、 とほぼ同じ時間で 10000x10000 マトリックスを取得しましたM1 = np.random.normal(size=(n,n))

私の質問は次のとおりです。

  1. Numpy のnp.linalg.qr()メソッドは実際に Householder 変換を使用しますか? それともギブンズの回転?
  2. グラム-シュミット法が よりもずっと遅いのはnp.linalg.qr()なぜですか?
  3. ディリクレ過程がほぼ直交行列を生成することを知っています。10,000 次元を作成しているため、他のすべてのベクトルと直交するベクトルがランダムに取得される可能性が高いためですか? はnp.linalg.qr()、行列が直交性にどれだけ近いかを気にしません。
  4. ランダムな直交行列を生成するさらに高速な方法はありますか? コードを高速化/効率化するためにコードを最適化できますか?

編集:cp.linalg.qr()同じ 10,000x10,000 のランダム マトリックスでの cupy は、CPU での numpy の 70 秒ではなく、私の 2080ti で 16 秒しかかかりません (8 コア @3.7 GHz マルチスレッド、16 GB RAM および 512 GB SSD)。