Як імітувати дані, що задовольняють конкретним обмеженням, таким як специфічне середнє та стандартне відхилення?


56

Це питання мотивоване моїм питанням про метааналіз . Але я думаю, що це також було б корисно в навчанні контекстів, де ви хочете створити набір даних, який би точно відображав наявний опублікований набір даних.

Я знаю, як генерувати випадкові дані із заданого розподілу. Наприклад, якщо я прочитав про результати дослідження, яке мало:

  • середнє значення 102,
  • стандартне відхилення 5,2 і
  • розмір вибірки 72.

Я міг би генерувати подібні дані за допомогою rnormР. Наприклад,

set.seed(1234)
x <- rnorm(n=72, mean=102, sd=5.2)

Звичайно, середнє значення і значення SD не було б точно рівним 102 і 5.2 відповідно:

round(c(n=length(x), mean=mean(x), sd=sd(x)), 2)
##     n   mean     sd 
## 72.00 100.58   5.25 

Взагалі мене цікавить, як імітувати дані, які задовольняють набір обмежень. У вищенаведеному випадку контейнери - це розмір вибірки, середнє значення та стандартне відхилення. В інших випадках можливі додаткові обмеження. Наприклад,

  • мінімум і максимум в даних або базовій змінній можуть бути відомі.
  • може бути відомо, що змінна може приймати лише цілі значення або лише негативні значення.
  • дані можуть включати кілька змінних із відомими взаємозв'язками.

Запитання

  • Як правило, як я змоделюю дані, які точно задовольняють набір обмежень?
  • Чи про це написано статті? Чи є в R програми, які роблять це?
  • Для прикладу, як я міг і чи повинен я імітувати змінну, щоб вона мала конкретне значення та sd?

1
Чому ви хочете, щоб вони були точно такими, як опубліковані результати? Чи не ці середні оцінки чи середнє відхилення населення з урахуванням їх вибірки даних. Зважаючи на невизначеність цих оцінок, хто скаже, що зразок, який ви показуєте вище, не відповідає їхнім спостереженням?
Гевін Сімпсон

4
Оскільки на це питання, схоже, є збір відповідей, які пропускають позначку (ІМХО), я хотів би зазначити, що концептуально відповідь є однозначною: обмеження рівності трактуються як граничні розподіли, а обмеження нерівності є багатовимірними аналогами усічення. Зрізання відносно просте в обробці (часто з відбором відхилень); складніше проблема полягає у пошуку способу вибірки цих граничних розподілів. Це означає або вибіркові маргінали з урахуванням розподілу та обмеження, або інтегрування для пошуку граничного розподілу та вибірки з нього.
whuber

4
До речі, останнє питання є тривіальним для сімей розподілу в масштабі локації. Наприклад, x<-rnorm(72);x<-5.2*(x-mean(x))/sd(x)+102робить трюк.
whuber

1
@whuber, як кардинал натякає на коментар до моєї відповіді (в якому згадується цей «трюк») та коментар до іншої відповіді - цей метод, як правило, не утримуватиме змінні в одній родині розповсюдження, оскільки ви розділяєте за стандартним відхиленням вибірки.
Макрос

5
@Macro Це хороший момент, але, мабуть, найкраща відповідь - "звичайно, вони не матимуть однакового розподілу"! Ви бажаєте, щоб розподіл було обумовлене обмеженнями. Загалом, це не буде з тієї ж сім'ї, що і батьківський розподіл. Наприклад, кожен елемент вибірки розміром 4 із середнім значенням 0 та SD 1, отриманим із звичайного розподілу, матиме майже однакову ймовірність на [-1,5, 1,5], оскільки умови ставлять верхню та нижню межі на можливі значення.
whuber

Відповіді:


26

Загалом, щоб середнє значення та дисперсія вибірки були точно рівними заздалегідь заданим значенням, ви можете відповідним чином змістити та масштабувати змінну. Зокрема, якщо є вибіркою, то нові змінніX1,X2,...,Xn

Zi=c1(XiX¯sX)+c2

де - вибіркове середнє значення, а - дисперсія вибірки є такою, що середнє значення вибірки 'є рівно а їх дисперсія вибірки - рівно . Аналогічно побудований приклад може обмежувати діапазон -s 2 X =1X¯=1ni=1nXiZic2c1sX2=1n1i=1n(XiX¯)2Zic2c1

Bi=a+(ba)(Ximin({X1,...,Xn})max({X1,...,Xn})min({X1,...,Xn}))

створить набір даних який обмежений інтервалом . B1,...,Bn(a,b)

Примітка. Ці типи зсуву / масштабування, як правило, змінять сімейство розподілу даних, навіть якщо вихідні дані походять із сімейства масштабів місцеположення.

В контексті нормального розподілуmvrnorm функція R дозволяє моделювати нормальні (або багатовимірні нормальні) дані з наперед визначеним зразком означають / ковариацию шляхом установки empirical=TRUE. Зокрема, ця функція імітує дані з умовного розподілу нормально розподіленої змінної, враховуючи середнє значення вибірки та (спів) дисперсію, що дорівнює заздалегідь заданому значенню . Зауважте, що граничні розподіли, які виникають в результаті, не є нормальними, на що вказував @whuber у коментарі до головного питання.

Ось простий універсальний приклад, коли середнє значення вибірки (від вибірки ) обмежено рівним 0, а стандартне відхилення вибірки - 1. Ми можемо бачити, що перший елемент набагато більше схожий на рівномірний розподіл, ніж нормальний розподіл:n=4

library(MASS)
 z = rep(0,10000)
for(i in 1:10000)
{
    x = mvrnorm(n = 4, rep(0,1), 1, tol = 1e-6, empirical = TRUE)
    z[i] = x[1]
}
hist(z, col="blue")

                  введіть тут опис зображення


1
нормально не розподілений, хоча вони можуть бути приблизно так , якщо розмір вибірки є великим. Перший коментар до відповіді @ Sean натякає на це. Zi
кардинал

1
Ну, це дуже природна річ, що хочеться зробити ... і часто не викликає занадто багато проблем.
кардинал

1
+1. У прикладі, між іншим, точна відповідь. (Очевидна крапля в кінці сюжету є артефактом того, як R малює гістограми.)
похмуріння

1
@whuber, дякую за мотивацію цього прикладу. Зважаючи на той факт, що граничні розподіли змінюються, коли ви обумовлюєте середню / дисперсію вибірки, схоже, що найкраща "відповідь" у дусі питання ОП - це просто імітувати дані із середньою / дисперсією сукупності, що дорівнює звітності як вибірки кількості (як запропонував сам ОП), чи не так? Таким чином, ви отримуєте кількість вибірок, "подібних" до бажаних, і граничні розподіли - це те, чим ви хотіли.
Макрос

1
@whuber, Якщо ваш зразок нормальний, то має -розподіл, так? Розглянута "нова" змінна буде просто лінійною комбінацією . Ti=(XiX¯)/stTi
Макрос

22

Щодо Вашого запиту на документи, є:

Це не зовсім те, що ви шукаєте, але може служити приводом для млина.


Є ще одна стратегія, яку, схоже, ніхто не згадував. Можна згенерувати (псевдо) випадкові дані з набору розміру таким чином, що весь набір відповідає обмеженням до тих пір, поки решта даних фіксуються у відповідних значеннях. Необхідні значення повинні бути вирішені за допомогою системи рівнянь, алгебри та деякої ліктьової змазки. NkNkkk

Наприклад, щоб генерувати набір даних із звичайного розподілу, який матиме задану середню вибірку та дисперсію, , вам потрібно буде зафіксувати значення двох точок: та . Оскільки середнє значення вибірки: має бути: Дисперсія вибірки: таким чином (після заміни вищевказаного на , складання / розповсюдження та перестановки ... ) ми отримуємо: Nx¯s2yz

x¯=i=1N2xi+y+zN
y
y=Nx¯(i=1N2xi+z)
s2=i=1N2(xix¯)2+(yx¯)2+(zx¯)2N1
y
2(Nx¯i=1N2xi)z2z2=Nx¯2(N1)+i=1N2xi2+[i=1N2xi]22Nx¯i=1N2xi(N1)s2
Якщо візьмемо , , і як заперечення РЗС ми можемо вирішити для використовуючи квадратичну формулу . Наприклад, у , може бути використаний такий код: a=2b=2(Nx¯i=1N2xi)czR
find.yz = function(x, xbar, s2){
  N    = length(x) + 2
  sumx = sum(x)
  sx2  = as.numeric(x%*%x)          # this is the sum of x^2
  a    = -2
  b    = 2*(N*xbar - sumx)
  c    = -N*xbar^2*(N-1) - sx2 - sumx^2 + 2*N*xbar*sumx + (N-1)*s2
  rt   = sqrt(b^2 - 4*a*c)

  z    = (-b + rt)/(2*a)
  y    = N*xbar - (sumx + z)
  newx = c(x, y, z)
  return(newx)
}

set.seed(62)
x    = rnorm(2)
newx = find.yz(x, xbar=0, s2=1)
newx                                # [1] 0.8012701  0.2844567  0.3757358 -1.4614627
mean(newx)                          # [1] 0
var(newx)                           # [1] 1

Щодо цього підходу слід зрозуміти. По-перше, це не гарантовано працює. Наприклад, можливо, що ваші початкові дані такі, що не існує значень і які зроблять дисперсію отриманого набору рівним . Поміркуйте: y z s 2N2yzs2

set.seed(22)    
x    = rnorm(2)
newx = find.yz(x, xbar=0, s2=1)
Warning message:
In sqrt(b^2 - 4 * a * c) : NaNs produced
newx                                # [1] -0.5121391  2.4851837        NaN        NaN
var(c(x, mean(x), mean(x)))         # [1] 1.497324

По-друге, хоча стандартизація робить граничні розподіли всіх ваших змінних більш рівномірними, такий підхід впливає лише на два останні значення, але робить їх граничні розподіли перекошеними:

set.seed(82)
xScaled = matrix(NA, ncol=4, nrow=10000)
for(i in 1:10000){
  x           = rnorm(4)
  xScaled[i,] = scale(x)
}

(вставити сюжет)

set.seed(82)
xDf = matrix(NA, ncol=4, nrow=10000)
i   = 1
while(i<10001){
  x       = rnorm(2)
  xDf[i,] = try(find.yz(x, xbar=0, s2=2), silent=TRUE)  # keeps the code from crashing
  if(!is.nan(xDf[i,4])){ i = i+1 }                      # increments if worked
}

(вставити сюжет)

По-третє, отриманий зразок може виглядати не дуже нормально; це може виглядати так, що у нього є "чужі люди" (тобто пункти, що надходять з іншого процесу генерування даних, ніж решта), оскільки це, по суті, так. Це менш ймовірно, що це проблема з більшими розмірами вибірки, оскільки статистика вибірки з генерованих даних повинна збігатися до необхідних значень і, таким чином, потребувати менших коригувань. При менших зразках, ви завжди можете поєднувати цей підхід з прийняттям / відхиленням алгоритму , який намагається знову , якщо згенерований зразок має статистичні форми (наприклад, асиметрія і ексцес) , які виходять за межі допустимих меж (див, @ кардинальські коментарів ), або продовжити цей підхід для створення вибірки з фіксованою середньою, дисперсією, косою такуртоз (хоча алгебру я залишаю тобі). Крім того, ви можете генерувати невелику кількість зразків і використовувати один з найменшими (скажімо) статистикою Колмогорова-Смірнова.

library(moments)
set.seed(7900)  
x = rnorm(18)
newx.ss7900 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss7900)                       # [1] 1.832733
kurtosis(newx.ss7900) - 3                   # [1] 4.334414
ks.test(newx.ss7900, "pnorm")$statistic     # 0.1934226

set.seed(200)  
x = rnorm(18)
newx.ss200 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss200)                        # [1] 0.137446
kurtosis(newx.ss200) - 3                    # [1] 0.1148834
ks.test(newx.ss200, "pnorm")$statistic      # 0.1326304 

set.seed(4700)  
x = rnorm(18)
newx.ss4700 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss4700)                       # [1]  0.3258491
kurtosis(newx.ss4700) - 3                   # [1] -0.02997377
ks.test(newx.ss4700, "pnorm")$statistic     # 0.07707929S

(додати сюжет)


10

Загальною технікою є "Метод відхилення", де ви просто відхиляєте результати, які не відповідають вашим обмеженням. Якщо у вас є якісь вказівки (наприклад, MCMC), ви можете створити безліч випадків (залежно від сценарію), які відхиляються!

Якщо ви шукаєте щось на зразок середнього і стандартного відхилення, і ви можете створити якусь метрику відстані, щоб сказати, наскільки ви віддалені від своєї мети, ви можете використовувати оптимізацію для пошуку вхідних змінних, які дають бажаний вихід значення.

Як потворний приклад, коли ми будемо шукати випадковий рівномірний вектор довжиною 100, який має середнє значення = 0 і стандартне відхилення = 1.

# simplistic optimisation example
# I am looking for a mean of zero and a standard deviation of one
# but starting from a plain uniform(0,1) distribution :-)
# create a function to optimise
fun <- function(xvec, N=100) {
  xmin <- xvec[1]
  xmax <- xvec[2]
  x <- runif(N, xmin, xmax)
  xdist <- (mean(x) - 0)^2 + (sd(x) - 1)^2
  xdist
}
xr <- optim(c(0,1), fun)

# now lets test those results
X <- runif(100, xr$par[1], xr$par[2])
mean(X) # approx 0
sd(X)   # approx 1

7
Обмеження, що виникають з нульовою вірогідністю, важко виконати. ;-) У конкретному прикладі, що відповідає правильному зрушенню та розширенню, легко досягти заявлених цілей, хоча, можливо, варто трохи глибше проаналізувати, щоб подивитися, як розподіл даних обумовлений такою операцією.
кардинал

Дякую. Безумовно, було б легко відхилити спостереження менше, ніж мінімум та більше, ніж макс. І я бачу, як ви могли б визначити це як проблему оптимізації. Було б чудово побачити кілька прикладів або, можливо, мати деякі пропозиції, що читати далі.
Джеромі Англім

1
@cardinal - погодився. Слід дивитись на розподіли (тобто гістограму) як вхідних модельованих чисел, так і вихідних, оскільки іноді вони можуть виглядати дуже дивно!
Шон

9

Чи є в R програми, які роблять це?

Пакет Runuran R містить безліч методів для генерування випадкових величин. Він використовує бібліотеки C проекту UNU.RAN (Універсальний нерівномірний генератор випадкових чисел). Мої власні знання в області генерації випадкових змінних обмежені, але віньєтка Runuran дає хороший огляд. Нижче наведено доступні методи пакету Runuran, взяті з віньєтки:

Постійні дистрибуції:

  • Адаптивний вибір відхилення
  • Відхилення від зворотної трансформованої щільності
  • Поліноміальна інтерполяція зворотного CDF
  • Простий метод співвідношення уніформ
  • Відхилення від трансформованої щільності

Дискретні розподіли:

  • Дискретна автоматична інверсія відхилення
  • Метод Псевдонім-Урна
  • Метод посібника-таблиці для дискретної інверсії

Багатовимірні розподіли:

  • Алгоритм натискання та запуску методом Ratio-of-Uniforms
  • Метод багатовимірного наївного співвідношення уніформ

Приклад:

Для швидкого прикладу, припустимо, ви хотіли створити нормальний розподіл, обмежений між 0 і 100:

require("Runuran")

## Normal distribution bounded between 0 and 100
d1 <- urnorm(n = 1000, mean = 50, sd = 25, lb = 0, ub = 100)

summary(d1)
sd(d1)
hist(d1)

urnorm()Функція є зручною функцією обгортки. Я вважаю, що за лаштунками він використовує поліноміальну інтерполяцію зворотного методу CDF, але не впевнений. Для чогось більш складного, скажімо, дискретного нормального розподілу, обмеженого між 0 і 100:

require("Runuran")

## Discrete normal distribution bounded between 0 and 100
# Create UNU.RAN discrete distribution object
discrete <- unuran.discr.new(pv = dnorm(0:100, mean = 50, sd = 25), lb = 0, ub = 100)

# Create UNU.RAN object using the Guide-Table Method for Discrete Inversion
unr <- unuran.new(distr = discrete, method = "dgt")

# Generate random variates from the UNU.RAN object
d2 <- ur(unr = unr, n = 1000)

summary(d2)
sd(d2)
head(d2)
hist(d2)

3

Схоже, існує пакет R, який відповідає вашій вимозі, опублікований лише вчора! Сімстуді Кіт Голдфельд

Моделює набори даних, щоб вивчити методи моделювання або краще зрозуміти процеси генерації даних. Користувач визначає набір відносин між коваріатами та генерує дані на основі цих специфікацій. Кінцеві набори даних можуть представляти дані з рандомізованих контрольних випробувань, повторних вимірювань (поздовжніх) проектів та кластеризованих рандомізованих випробувань. Відсутність може бути створена за допомогою різних механізмів (MCAR, MAR, NMAR).


1
Ні в віньєтці, ні на домашній сторінці програми не згадується точне дотримання обмежень. Чому, на вашу думку, цей пакет відповідає вимозі виведення з умовних розподілів?
gg

2

Ця відповідь приходить так пізно, що, мабуть, безглузда, але завжди існує рішення MCMC. А саме, спроектувати щільність з'єднання вибірки на колектор, визначений обмеженнями, наприклад Єдине питання полягає в моделюванні значень над цим колектором, тобто знаходження параметризації правильного виміру. 2015 документ з досліджень Bornn, Шепард і Solgi це дуже проблема (з цікавим , якщо не остаточною відповіддю ).

i=1nf(xi)
i=1nxi=μ0i=1nxi2=σ02

2

Ця відповідь розглядає інший підхід до випадку, коли ви хочете змусити змінні лежати у визначеному діапазоні та додатково продиктувати середнє та / або відхилення.

Обмежте нашу увагу на одиничному інтервалі . Давайте скористаємось середньозваженим середнім для загальності, тому зафіксуйте деякі ваги допомогою , або встановіть якщо ви хочете стандартного зважування. Припустимо, величини та являють собою бажану (зважену) середню і (зважену) дисперсію відповідно. Верхня межа необхідна, оскільки це максимально можлива дисперсія на одиничному інтервалі. Нам цікаво намалювати деякі змінні з з цими обмеженнями.[0,1]wk[0,1]k=1Nwk=1wk=1/Nμ(0,1)0<σ2<μ(1μ)σ2x1,...,xN[0,1]

Спочатку ми намалюємо деякі змінні з будь-якого розподілу, наприклад . Цей розподіл вплине на форму остаточного розподілу. Тоді ми обмежуємо їх одиничним інтервалом використовуючи логістичну функцію:y1,...,yNN(0,1)[0,1]

xk=11+e(ykvh)

Перш ніж ми зробимо це, однак, як видно з рівняння вище, ми перетворимо з перекладом і масштабом . Це аналогічно першому рівнянню у відповіді @ Макроса. Тепер полягає в тому, щоб вибрати і щоб перетворені змінні мали бажаний момент (и). Тобто, нам потрібно тримати одне або обидва з наступного: ykhvhvx1,...,xN

μ=k=1Nwk1+e(ykvh)σ2=k=1Nwk(1+e(ykvh))2(k=1Nwk1+e(ykvh))2

Інвертувати аналітичні рівняння для і не представляється можливим, але чисельно це робити прямо вперед, тим більше, що похідні відносно і легко обчислити; потрібно лише кілька ітерацій методу Ньютона.vhvh

В якості першого прикладу, скажімо, ми дбаємо лише про обмеження середньозваженої середньої величини, а не відхилення. Виправити , , , . Тоді для базових розподілів , та ми закінчуємо наступними гістограмами відповідно та таким чином, що середнє значення змінних рівно (навіть для малих ):v = 1 w k = 1 / N N = 200000 N ( 0 , 1 ) N ( 0 , 0,1 ) Unif ( 0 , 1 ) 0,8 Nμ=0.8v=1wk=1/NN=200000N(0,1)N(0,0.1)Unif(0,1) 0.8N

Приклад1

Далі обмежимо як середнє, так і дисперсійне. Візьміть , , і розгляньте три бажаних стандартних відхилення . Використовуючи той самий базовий розподіл , ось гістограми для кожної:w k = 1 / N N = 2000 σ = 0,1 , 0,05 , 0,01 N ( 0 , 1 )μ=0.2wk=1/NN=2000σ=0.1,0.05,0.01N(0,1)

Приклад 2

Зауважте, що вони можуть виглядати дещо бета-розподіленими, але це не так.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.