Цикл внутри цикла (или, желательно, обходной путь) для моделирования Монте-Карло

Этот вопрос связан с тем, который я задал в разделе «Перекрестная проверка», однако он ориентирован строго на R-кодирование.

Я пытаюсь выполнить моделирование Монте-Карло, чтобы создать агрегированное годовое распределение убытков. Он извлекает случайное число частот потерь из дискретного распределения (в данном случае Пуассона), а затем для каждой потери он рисует случайную серьезность для каждого из непрерывного распределения (например, логарифмически-нормальный).

Это не очень длинный или сложный фрагмент кода, однако я наткнулся на проблему.

Первое, что я должен сказать: я новичок в написании циклов в R (я не использую lapply или sapply только функции for). Мне удалось сгенерировать случайное количество проигрышей с определенной степенью серьезности для каждого из них, у меня есть две версии:

(Эта часть предназначена для обеих версий, сейчас я использую "обучающие" значения)

lambda=5 # lambda for poisson distribution
lnormpar1=2 #mean for lognormal distribution
lnormpar2=1 #standard deviation for lognormal distribution
simvect=10 #number of repeteation for monte carlo simulation

Ver1:

  vec.f=c()
  for(z in 1:1){
    vec.f[z]<- qpois(runif(1, min=0, max=1),lambda)
  }
  output=matrix(ncol=1,nrow=vec.f)
  for(i in 1:vec.f){
    output[i]<- qlnorm(runif(1, min=0, max=1),meanlog=lnormpar1, sdlog=lnormpar2)
  }
output

или короче, но я не уверен, что удобнее версия 2:

output2=c()
for(i in 1:qpois(runif(1, min=0, max=1),lambda)){
  output2[i]<- qlnorm(runif(1, min=0, max=1),meanlog=lnormpar1, sdlog=lnormpar2)
}
as.data.frame(output2)

Они оба делают одно и то же - генерируют «столбец» случайного числа потерь с заданной степенью серьезности, используя параметры, которые я разместил здесь, пример выглядит так:

Ver1 с матрицей:

          [,1]
[1,]  3.825669
[2,]  6.612618
[3,] 31.890079
[4,]  3.400814
[5,] 11.453274
[6,] 12.498189
[7,]  3.773497

Ver2:

    output2
1 18.632316
2 18.808997
3  1.526787
4  2.377593
5  5.786662

Это просто случайно сгенерированные числа, чтобы представить, как работают эти коды. В чем моя проблема, так это то, что я полагаю, что я поместил этот цикл в другой цикл, который будет повторять эту операцию определенное количество раз (определяется simvect=n, где n=10^5 или n=10^6 в окончательной версии). Я хочу, чтобы он выглядел так (вручную):

1.1 1.2 1.3
1.3 1.4 2.0
2.0 N/A 1.2
N/A N/A 3.0
N/A N/A 1.9

Итак, я хочу сгенерировать случайную строку, затем повторить процесс и сложить эти 2 вместе, чтобы создать фрейм данных или получить лучшее объяснение - матрица с количеством строк, равным максимальному отрисованному количеству частот, а номер столбца равен выбранному количеству повторений (обозначено здесь как simvect)

Это длинный пост, но я считаю, что он объясняет мою проблему. Спасибо всем заранее!


person Alexandros    schedule 20.01.2017    source источник
comment
Я добавляю здесь комментарий, потому что не хочу задавать другой вопрос: есть ли способ улучшить производительность (ускорить) R для 10 ^ 6 итераций? Или рекомендуется использовать другое ПО / среду / язык?   -  person Alexandros    schedule 24.01.2017


Ответы (1)


Я не совсем понимал, чего бы вы хотели достичь в конце, но это то, что я придумал. Надеюсь, это поможет!

lambda=5 # lambda for poisson distribution
lnormpar1=2 #mean for lognormal distribution
lnormpar2=1 #standard deviation for lognormal distribution
simvect=1000000 #number of repeteation for monte carlo simulation

Vec и output сохраняют для нас значения по мере прохождения цикла:

Vec=rep(0,simvect)       # first component
for(z in 1:simvect){
    Vec[z]<- qpois(runif(1, min=0, max=1),lambda)
}
Vec    # printing (not necessary)

output = rep(0,simvect)   # second component
for(i in 1:simvect){
  output[i]<- qlnorm(runif(1, min=0, max=1),meanlog=lnormpar1, sdlog=lnormpar2)
}

matrix(c(Vec,output), ncol=2)    # merging them
person A.Var    schedule 29.03.2017