কোলেস্কি পচন বা বিকল্প হিসাবে কীভাবে সম্পর্কিত ডেটা সিমুলেশন ব্যবহার করতে হয়


19

আমি কোলেস্কি পচন ব্যবহার করি একটি সম্পর্কযুক্ত ম্যাট্রিক্স প্রদত্ত পরস্পর সম্পর্কিত র্যান্ডম ভেরিয়েবলগুলি অনুকরণ করতে। বিষয়টি হ'ল ফলাফলটি পরস্পর সম্পর্ক কাঠামো যেমনটি দেওয়া হয় তেমন পুনরুত্পাদন করে না। পরিস্থিতি চিত্রিত করার জন্য পাইথনের একটি ছোট উদাহরণ এখানে।

import numpy as np    

n_obs = 10000
means = [1, 2, 3]
sds = [1, 2, 3] # standard deviations 

# generating random independent variables 
observations = np.vstack([np.random.normal(loc=mean, scale=sd, size=n_obs)
                   for mean, sd in zip(means, sds)])  # observations, a row per variable

cor_matrix = np.array([[1.0, 0.6, 0.9],
                       [0.6, 1.0, 0.5],
                       [0.9, 0.5, 1.0]])

L = np.linalg.cholesky(cor_matrix)

print(np.corrcoef(L.dot(observations))) 

এই মুদ্রণ:

[[ 1.          0.34450587  0.57515737]
 [ 0.34450587  1.          0.1488504 ]
 [ 0.57515737  0.1488504   1.        ]]

আপনি দেখতে পাচ্ছেন যে, পোস্ট-হকের আনুমানিক পারস্পরিক সম্পর্ক মেট্রিক্স পূর্বের তুলনায় মারাত্মকভাবে পৃথক। আমার কোডে কি কোনও ত্রুটি রয়েছে, বা কোলেস্কি পচন ব্যবহার করার কোনও বিকল্প আছে?

সম্পাদন করা

আমি এই গণ্ডগোলের জন্য আপনার ক্ষমা প্রার্থনা করছি। আমি মনে করি না কোডটিতে এবং / অথবা যেভাবে আগে পড়াশুনা করেছি তার কিছু ভুল বোঝাবুঝির কারণে কলসকি পচন প্রয়োগ হয়েছিল way আসলে আমি নিশ্চিত ছিল যে পদ্ধতিটি নিজেই সুনির্দিষ্ট নয় এবং যতক্ষণ না এই পরিস্থিতি আমাকে এই প্রশ্নটি পোস্ট করেছে, ততক্ষণ পর্যন্ত আমি এটির সাথে ঠিক ছিলাম। আমার যে ভুল ধারণা ছিল তা নির্দেশ করার জন্য আপনাকে ধন্যবাদ। @ সিলভারফিশের প্রস্তাবিত বাস্তব পরিস্থিতি আরও ভালভাবে প্রতিফলিত করার জন্য আমি শিরোনাম সম্পাদনা করেছি।


1
কোলেস্কি ঠিকঠাক কাজ করে, এবং এটি আসলে "টাইপ প্রশ্নটি" আপনি আমার কোডটিতে বাগটি খুঁজে পেতে পারেন "। প্রশ্নের শিরোনাম এবং বিষয়বস্তু, যেমন এটি লেখা আছে মূলত "কোলেস্কি কাজ করে না, বিকল্প কী?" এটি ব্যবহারকারীদের এই সাইটটি অনুসন্ধান করার জন্য খুব বিভ্রান্তিকর হবে। এটি প্রতিফলিত করার জন্য এই প্রশ্নটি সম্পাদনা করা উচিত? (নেতিবাচক দিকটি হ'ল জাভালাকেলের উত্তরটি কম প্রাসঙ্গিক হবে The উল্টোটি হল প্রশ্ন পাঠ্যটি অনুসন্ধানকারীরা পৃষ্ঠায় আসলে কী খুঁজে পাবে তা প্রতিফলিত করবে))
সিলভারফিশ

@ আন্টনি পরেল্লদা হ্যাঁ, আমি মনে করি আপনি আমার ম্যাটল্যাব কোডটি (ক) পাইথন আপাতে সঠিক পদ্ধতিতে অনুবাদ করেছেন, এনপি.লিনালগ.চোলেস্কি নিম্ন ত্রিভুজাকৃতির হওয়ায় সামঞ্জস্য রেখে সম্পূর্ণ ch আমি ইতিমধ্যে ওপির ভুল কোডটিকে তার ম্যাটল্যাব সমতুল্যে অনুবাদ করে দিয়েছি এবং তার ভুল ফলাফলগুলি সদৃশ করেছি।
মার্ক এল। স্টোন

উত্তর:


11

Cholesky পচন উপর ভিত্তি করে পদ্ধতির কাজ করা উচিত, এটি এখানে বর্ণনা করা হয়েছে এবং মার্ক এল। স্টোন প্রায় একই সময়ে পোস্ট করা উত্তর যে উত্তরটি দেখানো হয়েছে।

এন(μ,Σ)

ওয়াই=প্রশ্নঃএক্স+ +μ,সঙ্গেপ্রশ্নঃ=Λ1/2Φ,

ওয়াইএক্সΦΣΛΣΦ

উদাহরণস্বরূপ R(দুঃখিত যে প্রশ্নটিতে আপনি একই সফটওয়্যারটি ব্যবহার করছেন না):

n <- 10000
corM <- rbind(c(1.0, 0.6, 0.9), c(0.6, 1.0, 0.5), c(0.9, 0.5, 1.0))
set.seed(123)
SigmaEV <- eigen(corM)
eps <- rnorm(n * ncol(SigmaEV$vectors))
Meps <- matrix(eps, ncol = n, byrow = TRUE)    
Meps <- SigmaEV$vectors %*% diag(sqrt(SigmaEV$values)) %*% Meps
Meps <- t(Meps)
# target correlation matrix
corM
#      [,1] [,2] [,3]
# [1,]  1.0  0.6  0.9
# [2,]  0.6  1.0  0.5
# [3,]  0.9  0.5  1.0
# correlation matrix for simulated data
cor(Meps)
#           [,1]      [,2]      [,3]
# [1,] 1.0000000 0.6002078 0.8994329
# [2,] 0.6002078 1.0000000 0.5006346
# [3,] 0.8994329 0.5006346 1.0000000

আপনি এই পোস্ট এবং এই পোস্টে আগ্রহী হতে পারে ।


পুনরুত্পাদন সম্পর্কিত সংযোগ-ম্যাট্রিক্সকে সুনির্দিষ্ট করে তোলার জন্য ডেটা-প্রজন্মের পদ্ধতিতে প্রয়োগের আগে এলোমেলো-জেনারেটর থেকে এলোমেলো-ডেটাতে উদ্দীপনা সম্পর্কিত সম্পর্কগুলি সরিয়ে নেওয়া উচিত। উদাহরণস্বরূপ, প্রথমে জালিয়াতিপূর্ণ সম্পর্কগুলি দেখতে eps এ আপনার র্যান্ডম-ডেটার পারস্পরিক সম্পর্ক পরীক্ষা করুন।
গটফ্রাইড হেলস

17

কোডগুলির পরিবর্তে আপনি শব্দগুলি এবং বীজগণিত দিয়ে কী করেছেন তা ব্যাখ্যা করে (বা কমপক্ষে সিউডোকোড ব্যবহার করে এটি লিখেছেন) লোকেরা আপনার ত্রুটিটি আরও দ্রুত খুঁজে পেতে পারে।

আপনি এর সমতুল্য করছেন বলে মনে হচ্ছে (যদিও সম্ভবত স্থানান্তরিত):

  1. এন×জেড

  2. σআমিμআমি

  3. ওয়াই=এলএক্স

এল

আপনার যা করা উচিত তা হ'ল:

  1. এন×জেড

  2. এক্স=এলজেড

  3. σআমিμআমি

সাইটে এই অ্যালগরিদমের অনেক ব্যাখ্যা রয়েছে। যেমন

পারস্পরিক সম্পর্কযুক্ত এলোমেলো সংখ্যা (প্রদত্ত উপায়, রূপ এবং পারস্পরিক সম্পর্কের ডিগ্রি) কীভাবে উত্পন্ন করা যায়?

আমি কি নির্ধারিত গড় দিয়ে পারস্পরিক সম্পর্কযুক্ত র্যান্ডম ভেরিয়েবল তৈরির জন্য Cholesky- পদ্ধতিটি ব্যবহার করতে পারি?

এটি এটি পছন্দসই কোভেরিয়েন্স ম্যাট্রিক্সের ক্ষেত্রে সরাসরি আলোচনা করে এবং পছন্দসই নমুনা পাওয়ার জন্য একটি অ্যালগরিদমও দেয় সমবায় :

প্রদত্ত নমুনা কোভেরিয়েন্স ম্যাট্রিক্স সহ ডেটা তৈরি করা


11

কোলেস্কি ফ্যাক্টেরাইজেশনে কোনও ভুল নেই। আপনার কোডে একটি ত্রুটি আছে। নীচে সম্পাদনা দেখুন।

এখানে ম্যাটল্যাব কোড এবং ফলাফলগুলি রয়েছে, প্রথমে আপনার মতো এন_বস = 10000 এর জন্য, তারপরে এন_ববস = 1e8 এর জন্য। সরলতার জন্য, যেহেতু এটি ফলাফলগুলিকে প্রভাবিত করে না, তাই আমি উপায় নিয়ে বিরক্ত করি না, অর্থাত্ আমি তাদের শূন্য করে তুলি। নোট করুন যে ম্যাটল্যাবের চোল ম্যাট্রিক্স এম এর উপরের ত্রিভুজাকার কোলেস্কি ফ্যাক্টর আর তৈরি করে যেমন আর '* আর = এম নামি.লিনালগ.চোলেস্কি একটি ত্রিভুজাকার কোলেস্কি ফ্যাক্টর তৈরি করে, তাই আমার কোড বনাম একটি সমন্বয় প্রয়োজন; তবে আমি বিশ্বাস করি যে আপনার কোডটি সেই ক্ষেত্রে ভাল।

   >> correlation_matrix = [1.0, 0.6, 0.9; 0.6, 1.0, 0.5;0.9, 0.5, 1.0];
   >> SD = diag([1 2 3]);
   >> covariance_matrix = SD*correlation_matrix*SD
   covariance_matrix =
      1.000000000000000   1.200000000000000   2.700000000000000
      1.200000000000000   4.000000000000000   3.000000000000000
      2.700000000000000   3.000000000000000   9.000000000000000
   >> n_obs = 10000;
   >> Random_sample = randn(n_obs,3)*chol(covariance_matrix);
   >> disp(corr(Random_sample))
      1.000000000000000   0.599105015695768   0.898395949647890
      0.599105015695768   1.000000000000000   0.495147514173305
      0.898395949647890   0.495147514173305   1.000000000000000
   >> n_obs = 1e8;
   >> Random_sample = randn(n_obs,3)*chol(covariance_matrix);
   >> disp(corr(Random_sample))
      1.000000000000000   0.600101477583914   0.899986072541418
      0.600101477583914   1.000000000000000   0.500112824962378
      0.899986072541418   0.500112824962378   1.000000000000000

সম্পাদনা: আমি আপনার ভুল খুঁজে পেয়েছি। আপনি ভুলভাবে স্ট্যান্ডার্ড বিচ্যুতিটি প্রয়োগ করেছেন। এটি আপনি যা করেছেন তার সমতুল্য, যা ভুল।

   >> n_obs = 10000;
   >> Random_sample = randn(n_obs,3)*SD*chol(correlation_matrix);
   >> disp(corr(Random_sample))
      1.000000000000000   0.336292731308138   0.562331469857830
      0.336292731308138   1.000000000000000   0.131270077244625
      0.562331469857830   0.131270077244625   1.000000000000000
   >> n_obs=1e8;
   >> Random_sample = randn(n_obs,3)*SD*chol(correlation_matrix);
   >> disp(corr(Random_sample))
      1.000000000000000   0.351254525742470   0.568291702131030
      0.351254525742470   1.000000000000000   0.140443281045496
      0.568291702131030   0.140443281045496   1.000000000000000

6

সিভি কোড সম্পর্কিত নয়, তবে এটি কীভাবে সমস্ত ভাল উত্তরগুলি দেখাবে এবং বিশেষত @ মার্ক এল। স্টোন অবদানের দিকে নজর রাখবে তা জানতে আগ্রহী হয়েছিল। প্রশ্নের আসল উত্তর তার পোস্টে সরবরাহ করা হয়েছে (সন্দেহের ক্ষেত্রে দয়া করে তার পোস্টটি জমা দিন)। ভবিষ্যতে এই পোস্টটি পুনরুদ্ধারের সুবিধার্থে আমি এই সংযুক্ত তথ্যটি এখানে সরিয়ে নিচ্ছি। মার্কের উত্তরের পরে অন্য কোনও উত্তরের উত্তর না খেলেই এইটি ওপিতে পোস্টটি সংশোধন করে বিষয়টি জড়িয়ে দেয়।

সূত্র

পাইথনে:

import numpy as np

no_obs = 1000             # Number of observations per column
means = [1, 2, 3]         # Mean values of each column
no_cols = 3               # Number of columns

sds = [1, 2, 3]           # SD of each column
sd = np.diag(sds)         # SD in a diagonal matrix for later operations

observations = np.random.normal(0, 1, (no_cols, no_obs)) # Rd draws N(0,1) in [3 x 1,000]

cor_matrix = np.array([[1.0, 0.6, 0.9],
                       [0.6, 1.0, 0.5],
                       [0.9, 0.5, 1.0]])          # The correlation matrix [3 x 3]

cov_matrix = np.dot(sd, np.dot(cor_matrix, sd))   # The covariance matrix

Chol = np.linalg.cholesky(cov_matrix)             # Cholesky decomposition

array([[ 1.        ,  0.        ,  0.        ],
       [ 1.2       ,  1.6       ,  0.        ],
       [ 2.7       , -0.15      ,  1.29903811]])

sam_eq_mean = Chol .dot(observations)             # Generating random MVN (0, cov_matrix)

s = sam_eq_mean.transpose() + means               # Adding the means column wise
samples = s.transpose()                           # Transposing back

print(np.corrcoef(samples))                       # Checking correlation consistency.

[[ 1.          0.59167434  0.90182308]
 [ 0.59167434  1.          0.49279316]
 [ 0.90182308  0.49279316  1.        ]]

ইন [আরবি]:

no_obs = 1000             # Number of observations per column
means = 1:3               # Mean values of each column
no_cols = 3               # Number of columns

sds = 1:3                 # SD of each column
sd = diag(sds)         # SD in a diagonal matrix for later operations

observations = matrix(rnorm(no_cols * no_obs), nrow = no_cols) # Rd draws N(0,1)

cor_matrix = matrix(c(1.0, 0.6, 0.9,
                      0.6, 1.0, 0.5,
                      0.9, 0.5, 1.0), byrow = T, nrow = 3)     # cor matrix [3 x 3]

cov_matrix = sd %*% cor_matrix %*% sd                          # The covariance matrix

Chol = chol(cov_matrix)                                        # Cholesky decomposition

     [,1] [,2]      [,3]
[1,]    1  1.2  2.700000
[2,]    0  1.6 -0.150000
[3,]    0  0.0  1.299038

sam_eq_mean = t(observations) %*% Chol          # Generating random MVN (0, cov_matrix)

samples = t(sam_eq_mean) + means

cor(t(samples))

          [,1]      [,2]      [,3]
[1,] 1.0000000 0.6071067 0.8857339
[2,] 0.6071067 1.0000000 0.4655579
[3,] 0.8857339 0.4655579 1.0000000

colMeans(t(samples))
[1] 1.035056 2.099352 3.065797
apply(t(samples), 2, sd)
[1] 0.9543873 1.9788250 2.8903964

1

অন্যরা ইতিমধ্যে দেখিয়েছে: কোলেস্কি কাজ করে। এখানে কোডের একটি অংশ যা সিউডোকোডের খুব সংক্ষিপ্ত এবং খুব কাছে: ম্যাটমেটে একটি কোডপিস:

Co = {{1.0, 0.6, 0.9},  _
      {0.6, 1.0, 0.5},  _
      {0.9, 0.5, 1.0}}           // make correlation matrix


chol = cholesky(co)              // do cholesky-decomposition           
data = chol * unkorrzl(randomn(3,100,0,1))  
                                 // dot-multiply cholesky with random-
                                 // vectors with mean=0, sdev=1  
                                 //(refined by a "decorrelation" 
                                 //to remove spurious/random correlations)   


chk = data *' /100               // check the correlation of the data
list chk

1.0000  0.6000  0.9000
0.6000  1.0000  0.5000
0.9000  0.5000  1.0000
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.