4 Вопрос: Генератор случайных чисел в Python, когда среднее известно

вопрос создан в Fri, Mar 29, 2019 12:00 AM

В Python я пытаюсь получить список из 10 случайных чисел между [0,100], которые имеют среднее значение 25. Вся информация, которую я имею, приведена ниже.

Total = 250
Number_of_users = 10
Average_score = 25

В прошлом я использовал функцию Гаусса случайным образом, но без стандартного отклонения я немного застрял. Есть ли другой способ сделать это?

Мой вывод будет выглядеть примерно так:

[20, 30, 18, 21, 27, 30, 15, 24, 31, 30]
    
4
  1. Требуете ли вы, чтобы их также добавляли до определенного заданного числа?
    2019-03-29 10: 56: 23Z
  2. Да, поэтому, если возможно, общая сумма также будет равна 250
    2019-03-29 10: 58: 11Z
4 ответа                              4                         

Ну, если вы хотите if possible the total would be 250 as well, тогда ответом будет выборка из мультиномиального распространения . По определению, он будет производить случайные значения, суммированные до 250 и со средним значением 25. Если одно из чисел будет больше 100 (это будет довольно редко), мы будем играть в игру принятия /отклонения. С помощью NumPy

import numpy as np

Total = 250
Number_of_users = 10
Average_score = 25
Upper_boundary = 100

probs = np.full(10, 1.0/np.float64(Number_of_users), dtype=np.float64) # probabilities

N = 10000 # samples to test
k = 0
while k < N:
    q = np.random.multinomial(Total, probs)
    t = np.where(q > Upper_boundary) # check for out-of boundaries
    if np.any(t):
        print("Rejected, out of boundaries") # reject, do another sample
        continue
    # accepted
    # do something with q, print((sum(q), len(q), np.mean(q)))

    k += 1
    
2
2019-03-29 14: 50: 40Z
  1. Спасибо, это дает действительно элегантное решение.
    2019-03-29 15: 39: 15Z

У меня есть мысль:

import random

Number_of_users = 10
Average_score = 25

index = Number_of_users / 2
result = []

while index:
    index -= 1
    random_number = random.randint(0,51)
    result.append(random_number)
    result.append(50-random_number)

print (result)
print (sum(result))

Вы получите 5 пар случайных чисел; для каждой пары случайных чисел первое генерируется случайным образом в диапазоне от 0 до 50, а второе зависит от первого числа.

Недостатком моего подхода является то, что он не обрабатывает нечетное количество случайных чисел.

    
1
2019-03-29 11: 13: 02Z
  1. Для нечетного числа вставьте значение 25 в список, оставив среднее значение без изменений. После этого можно поиграть со списком, выбрав случайное увеличение /уменьшение и пару чисел, увеличивая одно и уменьшая другое (следя за ограничениями значений чисел). Это можно повторить много раз, чтобы тщательно перемешать окончательные значения.
    2019-03-29 12: 24: 46Z

Вот два ограничения:

  1. Числа являются случайными

  2. Среднее значение сходится к 25

Поскольку нет ограничений на распределение, одним из способов достижения этого является выборка из 2 различных равномерных распределений:

import random
out_list = []
for i in range(1,10):
    random_number = random.uniform(0,1)
    if random_number < 0.75:
        # Append uniform random number between 0 - 25 with probability .75
        out_list.append(random.randint(0,25))
    else:
        #Append uniform random number between 0-75 with probability 0.25
        out_list.append(random.randint(25,100))

print(out_list)
import statistics
print(statistics.mean(out_list))

Кроме того, этот вопрос может быть лучше найден на stats.stackexchange.com.

    
1
2019-03-29 11: 55: 57Z
  1. Большое спасибо. отмечено на stats.exchange.
    2019-03-29 12: 09: 42Z
  2. График распределения таких чисел был бы ... бесполезным из-за отсутствия лучшего слова
    2019-03-29 14: 17: 05Z

Вы можете попробовать бетараспределение со средним значением 25, то есть выбираем параметры a, b так, чтобы a /(a ​​+ b) = 0,25. Вы можете получить представление о том, какую дисперсию вы хотите, на графике ниже с различными параметрами a, b. введите описание изображения здесь

from scipy.stats import beta
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(3, sharex=True, figsize=(7,7))

x = np.linspace(0,1,100)
a = [ 2.5,10, 25]
b = [ 7.5,30, 75]

for i in range(len(ax)):
    ax[i].plot(x,beta.pdf(x,a[i],b[i]))
    ax[i].text(0.75,0.75,"a={}, b={}".format(a[i],b[i]), transform=ax[i].transAxes)

plt.show()
result = list(map(int, 100*beta.rvs(10,30,size=9))) #to be more precise, need to check that these 9 values fall below 250
result.append(250-sum(result))
print("10 samples from a Beta(10,30) distribution:\n ",*result)



Out: 10 samples from a Beta(10,30) distribution:
  20 25 21 20 31 28 24 29 23 29
    
0
2019-03-29 12: 58: 22Z
  1. Ну, числа могут быть и выше 100, но это маловероятно и довольно легко проверить. Реальная проблема с этим подходом состоит в том, что 9 чисел из 10 будут иметь что-то, похожее на бета-распределение, а 10-е число будет ОЧЕНЬ распределено по-другому.
    2019-03-29 14: 58: 27Z
  2. Ну, это ограничение установки среднего, равного любому числу, это будет меньше степени свободы. Ни одно распределение не будет точным при таком условии.
    2019-03-29 17: 32: 58Z
  3. No distribution will be accurate given such a condition. А ?! Не имеет смысла Есть распределения, где такое условие выполняется с помощью функции deifniton - Multinomial для целых чисел или Dirichlet для вещественных чисел
    2019-03-31 03: 15: 02Z
источник размещен Вот
Другие вопросы