回答 受付中

人工的なデータを作成するアルゴリズム

  • 困ってます
  • 質問No.9489335
  • 閲覧数91
  • ありがとう数1
  • 気になる数2
  • 回答数1

お礼率 100% (8/8)

人工的なデータを作成するアルゴリズムを探しています。
条件は,
1. データの個数はN=500個を3セット
2. それぞれのセットは1から500までの整数を並べ替えたもの
3. セット間の相関係数は,セット1とセット2が0.7,セット1とセット3が0.6,セット2とセット3が0.5とします。
このうち条件1と条件2は絶対です。条件3はできるだけ近ければよいとします。
どのようにして作成すれば良いでしょうか?
通報する
  • 回答数1

回答 (全1件)

  • 回答No.1
レベル10

ベストアンサー率 66% (82/124)

探索すべき対象が非常に多く、期待している相関係数は比較的大きいです。そこでリスト [1, 2, ..., 500] をふたつに分けひっくり返した形のものだけを探してみました。
セット1 = x = [1, 2, ..., 500],
セット2 = y = [22, 23, ..., 500, 1, 2, ..., 21],
セット3 = z = [470, 471, ..., 500, 1, 2, ..., 469]
を考えると相関係数はおよそ
r(x, y) ~ 0.76,
r(x, z) ~ 0.65,
r(y, z) ~ 0.44
となります。これくらいではいかが?

以下、計算に使ったpythonのコード(どうもインデントが正しく表示できないようですが、理解する上で特に問題はないでしょう)。計算はラップトップで一分ほどでした。
from scipy.stats import pearsonr

N = 500
a = range(1, N+1)

def r(x, y): return pearsonr(x, y)[0]

def rev(n): return a[n:] + a[:n]

## find date set
score = float("inf")
x = rev(0)
for j in range(N):
y = rev(j)
score1 = (r(x, y) - 0.7)**2
for k in range(N):
z = rev(k)
score2 = (r(x, z) - 0.6)**2 + (r(y, z) - 0.5)**2
if score1 + score2 < score:
score = score1 + score2
j0 = j; k0 = k

## result
x = rev(0); y = rev(j0); z = rev(k0)
print j0, k0
print r(x, y), r(x, z), r(y, z)
補足コメント
f272

お礼率 100% (8/8)

以下のように書いてみると約0.3秒で答えがでます。しかし,実際にやりたかったことは3セットではなく9セットなのです。同じように書いてみても実際的な計算時間では収まりません。4セットですら約38秒かかります。
その上,9セットは大まかには2-3-2-2のサブセットに分かれていて,与えられる相関係数はサブセット内は大きく0.63くらいですが,サブセット間は小さくて約0.07です。
なにか画期的な方法はないものでしょうか?

#include<iostream>
#include<cmath>
inline double sqr(double v) {return v*v;}
double pearsonr(double *x,double *y,int n)
{
double sx=0.0,sy=0.0,sxy=0.0,sxx=0.0,syy=0.0;
int i;
for (i=0;i<n;++i) {
sx+=x[i];
sy+=y[i];
}
double mx=sx/n,my=sy/n;
for (i=0;i<n;++i) {
sxy += (x[i]-mx)*(y[i]-my);
sxx += sqr(x[i]-mx);
syy += sqr(y[i]-my);
}
return sxy/sqrt(sxx*syy);
}
int main() {
double x[1000];
double r[3][3],rr[3][3],s[3];
double r0[3][3]={{1.0},
{0.7,1.0},
{0.6,0.5,1.0},
};
int n=500;
int i,j,k[3],kk[3];
for (i=0;i<n;++i) {
x[i]=x[i+n]=i+1;
}
double ss=999;
kk[0]=k[0]=0;
for (k[1]=1;k[1]<n;++k[1]) {
r[1][0] = pearsonr(x+k[1],x+k[0],n);
s[1]=sqr(r[1][0]-r0[1][0]);
if (ss<s[1]) continue;
for (k[2]=1;k[2]<n;++k[2]) {
for (i=0;i<2;++i) r[2][i] = pearsonr(x+k[2],x+k[i],n);
s[2]=s[1];
for (i=0;i<2;++i) s[2]+=sqr(r[2][i]-r0[2][i]);
if (ss>s[2]) {
ss=s[2];
for (i=1;i<3;++i) {
kk[i]=k[i];
for (j=0;j<i;++j) rr[i][j]=r[i][j];
}
}
}
}
std::cout << "kk=";
for (i=1;i<3;++i) std::cout << " " << kk[i];
std::cout << std::endl;
std::cout << "r=";
for (i=1;i<3;++i) {
for (j=0;j<i;++j) std::cout << " " << rr[i][j];
std::cout << std::endl;
}
std::cout << std::endl;
}
投稿日時 - 2018-04-17 14:20:46
お礼コメント
f272

お礼率 100% (8/8)

ありがとうございます。
投稿日時 - 2018-04-17 14:20:49
  • 回答数1
このQ&Aで解決しましたか?
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する

特集


より良い社会へ。感謝経済プロジェクト始動

ピックアップ

ページ先頭へ