数個のデータから共分散行列を生成するプログラムを実装しようと
考えています。そこで、次のようなプログラムを書きましたが、
結果があっているかがわかりません。共分散行列の生成方法に
詳しい方がおられましたら、どうか教えて頂きたいと思います。
共分散行列生成に用いた式は
Σ = E[(X-E[X])(X-E[X])^T] です。
(Σ:共分散行列 X:データ E[X]:Xの平均 ^T:転置行列)
double xave = 0.0; //式のE[x]にあたる部分
double work [ ]; //データを入れる一次元配列(式のXにあたる)
double a[][]; //共分散行列を入れる配列
work[0] = 3; //5つのデータを格納
work[1] = -2;
work[2] = 5;
work[3] = -3;
work[4] = 2;
for(i = 0; i < N; i++){ //E[x]を求めるためにxaveに全要素合計を入れる
xave += work[i];
}
xave /= N; //全要素合計をデータ数で割る
for(i = 0; i < N; i++){ //要素Xから平均を引く(X-E[x]にあたる)
work[i] -= xave;
}
for(i = 0; i < N; i++){
for(j = 0; j < N; j++){
a[i][j] = work[i]*work[j]/N; //a[][]に値を格納 Nで割っているのは式の一番外側のEにあたる
}
}
<実行結果>
0.0 | 0.0 | 0.0 | 0.0 | 0.0
0.0 | 4.0 | -6.0 | 8.0 | -8.0
0.0 | -6.0 | 9.0 | -12.0 | 12.0
0.0 | 8.0 | -12.0 | 16.0 | -16.0
0.0 | -8.0 | 12.0 | -16.0 | 16.0
No.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を一行の行ベクトルと考え、二つの行列の積を考えるとちょうど
正方行列になるので、これでいいかと思っていました。しかし、この考え方
では間違っているとういことでしょうか。
それならば、共分散行列を生成するには、二次元以上のデータが必要ということ
でしょうか。
No.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 …
…
上のような形式のデータなら変数ごとの分散と変数間の共分散を求めて、共分散行列を得ることが出来ます。
なるほど、quaestioさんの書いて下さった説明を読み、納得できました。
確かに一次元のデータのみでは共分散行列が求められないですね。
何度も親切に答えて頂き感謝します。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 3 2022/06/12 11:17
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
3行3列の行列の和と積の計算...
-
線形代数です。 正方行列A,BがA...
-
基本行列の積
-
数学「行列」の実生活への応用
-
matlabで条件をみたしたデータ...
-
逆行列(AB)^-1について
-
ブール代数を元に持つ行列の逆...
-
Vandermondeの逆行...
-
エクセルの行列式の計算
-
行列計算で、できること
-
3行3列の逆行列(ルートを含む)
-
行列の簡約化についての質問です!
-
3×3の逆行列の計算
-
数学C 行列の問題
-
行列の平方根?のようなもの
-
単因子の計算問題
-
単因子論で(1,1)が必ず1...
-
4次の行列式について
-
AとBは同じサイズの正方行列と...
-
行列を分割するメリットを教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
3行3列の行列の和と積の計算...
-
線形代数です。 正方行列A,BがA...
-
連続的ポストごめんなさい
-
数学「行列」の実生活への応用
-
matlabで条件をみたしたデータ...
-
行列を分割するメリットを教え...
-
基本行列の積
-
高校数学で教わる行列っていっ...
-
行列の式の英語読み方について
-
行列の平方根?のようなもの
-
逆行列(AB)^-1について
-
掃き出し法は、行の基本変形と...
-
3行3列の逆行列(ルートを含む)
-
Aが2次正方行列とする。 (1)A...
-
Aはn次正方行列で、どんなn次...
-
回転行列の4行4列の意味について
-
零行列 O のことも 零因子 と呼...
-
複素数を含む行列の逆行列は存...
-
[☆急いでます!!☆] 基本変形の解...
-
ansatzとは
おすすめ情報