Ответ 1
Как создать список случайных чисел с заданным средним и стандартным отклонением (sd) в JavaScript?
Это, по-видимому, вопрос о случайном создании списка чисел с точно указанным mean и точно указанным стандартное отклонение (а не вопрос о том, как рисовать случайные числа из определенного распределения вероятности с заданным значением и sd).
Простое решение состоит в том, чтобы нарисовать список случайных чисел, затем сдвинуть и масштабировать этот список, чтобы иметь желаемое среднее значение и sd, как описанное в этом ответе, из stats.stackexchange.
Скажем, мы генерируем следующие 5 случайных чисел между 1 и 10:
4.527991433628388
6.3254986488276055
5.123502737960912
7.3331068522336125
9.069573681037484
Этот список имеет среднее значение 6.475934670737601
и sd 1.8102412442104023
.
Затем мы преобразуем каждое число в список следующим образом:
newNum = oldSD * (oldNum - oldMean) / oldSD + newMean
Установив новое среднее значение 5 и новый sd на 2, мы получим следующий преобразованный список:
2.847863379160965
4.83379450402964
3.505799227476338
5.947025358346529
7.865517530986525
Вычисление среднего и sd этого списка подтверждает, что они действительно 5 и 2.
Ниже приведен код, демонстрирующий этот подход в JavaScript:
// create a list of 5 random numbers between 1 and 10
var list = randomList(5, 1, 10);
// transform the list to have an exact mean of 5 and sd of 2
var newList = forceDescriptives(list, 5, 2);
// display the transformed list and descriptive statistics (mean and sd)
console.log('Transformed random list', newList, descriptives(newList));
// display the original list and descriptive statistics (mean and sd)
console.log('Original random list', list, descriptives(list));
/* demo functions */
function randomList(n, a, b) {
// create a list of n numbers between a and b
var list = [],
i;
for (i = 0; i < n; i++) {
list[i] = Math.random() * (b - a) + a;
}
return list;
}
function descriptives(list) {
// compute mean, sd and the interval range: [min, max]
var mean,
sd,
i,
len = list.length,
sum,
a = Infinity,
b = -a;
for (sum = i = 0; i < len; i++) {
sum += list[i];
a = Math.min(a, list[i]);
b = Math.max(b, list[i]);
}
mean = sum / len;
for (sum = i = 0; i < len; i++) {
sum += (list[i] - mean) * (list[i] - mean);
}
sd = Math.sqrt(sum / (len - 1));
return {
mean: mean,
sd: sd,
range: [a, b]
};
}
function forceDescriptives(list, mean, sd) {
// transfom a list to have an exact mean and sd
var oldDescriptives = descriptives(list),
oldMean = oldDescriptives.mean,
oldSD = oldDescriptives.sd,
newList = [],
len = list.length,
i;
for (i = 0; i < len; i++) {
newList[i] = sd * (list[i] - oldMean) / oldSD + mean;
}
return newList;
}