- ベストアンサー
共分散行列の求め方
- 共分散行列の求め方や生成プログラムについて説明します。
- 数個のデータから共分散行列を生成する方法を解説します。
- 共分散行列の生成プログラムを実装した結果を示します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
> ・言語は一応Javaでやっています。 Javaでしたか、ずいぶん前にちょっと使ってみただけでしたので思いつきませんでした。 > Σ = E[(X-E[X])(X-E[X])^T] の式から、(X-E[X])を一列の列ベクトル、 > (X-E[X])^Tを一行の行ベクトルと考え、二つの行列の積を考えるとちょうど > 正方行列になるので、これでいいかと思っていました。しかし、この考え方 > では間違っているとういことでしょうか。 はい、そうなります。 E[X]は列ベクトルとなりますが、Xの要素が異なる変数なので、それぞれの期待値が等しくなるとは限りません。 なので、 > for(i = 0; i < N; i++){ //要素Xから平均を引く(X-E[x]にあたる) > work[i] -= xave; > } とするのはおかしいのです。 引くなら、work[i]の値を引くべきです。 (データ数が1個なので平均はwork[i]そのもの。その結果共分散行列は5×5の零行列になる) > それならば、共分散行列を生成するには、二次元以上のデータが必要ということでしょうか。 例えば、下記のようなデータなら計算できます。 番号 変数1 変数2 変数3 変数4 変数5 1 5 3 4 6 1 2 … … 上のような形式のデータなら変数ごとの分散と変数間の共分散を求めて、共分散行列を得ることが出来ます。
その他の回答 (1)
いろいろと問題がありますが、一番の問題は一次元のデータから共分散行列は計算できません。 aは対角要素がデータの平均からの偏差の二乗で、非対角要素がデータ間の平均からの偏差の積であるだけで、これは共分散行列とは言いません。 その他の問題としては、 ・プログラムの質問なのに使用した言語の記載が無い(C/C++だとは想像できますが) ・使用している変数の説明がない(Nの値は?) ・結果表示の関数が記載されていないが、多分間違っている(何故0.0という結果がでるのですか?)
補足
ご回答ありがとうございます。いろいろと抜け落ちていたり、 間違って記述していました。すみませんでした。 ・言語は一応Javaでやっています。 ・変数Nは配列の要素数(データの数)です。 実行結果ですが、配列の表示範囲を間違えていました。実際は 4.0 -6.0 8.0 -8.0 2.0 -6.0 9.0 -12.0 12.0 -3.0 8.0 -12.0 16.0 -16.0 4.0 -8.0 12.0 -16.0 16.0 -4.0 2.0 -3.0 4.0 -4.0 1.0 でした。 また、プログラムの最後のa[i][j] = work[i]*work[j]/N;の部分も 正しくはa[i][j] = work[i]*work[j];で /N はなかったです。 一次元のデータから共分散行列は計算できないということですが、 Σ = E[(X-E[X])(X-E[X])^T] の式から、(X-E[X])を一列の列ベクトル、 (X-E[X])^Tを一行の行ベクトルと考え、二つの行列の積を考えるとちょうど 正方行列になるので、これでいいかと思っていました。しかし、この考え方 では間違っているとういことでしょうか。 それならば、共分散行列を生成するには、二次元以上のデータが必要ということ でしょうか。
お礼
なるほど、quaestioさんの書いて下さった説明を読み、納得できました。 確かに一次元のデータのみでは共分散行列が求められないですね。 何度も親切に答えて頂き感謝します。ありがとうございました。