Como controlar seu randomizador em R

O que acontece quando você precisa de um tipo específico de randomização?

200 números aleatórios usando a distribuição normal.

Visão geral da geração de números aleatórios em R

R tem pelo menos 20 funções geradoras de números aleatórios. Cada um usa uma distribuição de probabilidade específica para criar os números. Todos exigem que você especifique o número de números aleatórios que deseja (a imagem acima mostra 200). Todos estão disponíveis na base R – não são necessários pacotes.

Distribuições geradoras de números aleatórios comuns são:

  • normal (rnorm): média padrão de 0 e desvio padrão de 1
  • binomial (rbinom): sem defaults, especifique o número de tentativas e a probabilidade de sucesso em cada tentativa
  • uniforme (runif): valor mínimo padrão de 0 e valor máximo de 1

Dos três acima, apenas o gerador de números aleatórios binomiais cria números inteiros.

Por que criar números aleatórios?

Problemas envolvendo números aleatórios são muito comuns – existem cerca de 50.000 perguntas relacionadas a números aleatórios no Stack Exchange.

Mas por que usá-los?

Números aleatórios têm muitas aplicações práticas. Eles são usados ??em simulações de Monte Carlo . Eles são usados ??em criptografia . Eles foram usados ??para produzir conteúdo CAPTCHA . Eles são usados ??em máquinas caça-níqueis . Eles também foram usados ??para tarefas mais comuns, como criar uma ordem de classificação aleatória para uma matriz de dados ordenados.

Problemas com números aleatórios

Perguntas comuns incluem "meus números aleatórios são realmente aleatórios?" E "como posso gerar números aleatórios não repetidos?"

Nota : o último diminui a aleatoriedade, porque a população de números aleatórios possíveis é diminuída em um cada vez que um número aleatório é sorteado. O método é apropriado em situações como loterias ou bingo, onde cada ticket ou bola só pode ser desenhado uma vez.

Esse problema traz outro problema! A amostragem gerada aleatoriamente, sem números de substituição, deve ser números inteiros. Ninguém tem bilhete 5.6932 ou bingo bola 0.18967.

Um exemplo prático de problemas numéricos aleatórios

Vamos dar o exemplo de que eu tenho 20 alunas da mesma idade. Eu tenho quatro métodos de ensino que quero testar. Eu só quero testar um método de ensino para cada aluno. Matemática fácil – preciso de cinco alunos em cada grupo.

Mas como faço isso para que cada aluno seja designado aleatoriamente?

E como posso ter certeza de que só tenho números inteiros produzidos?

E como faço tudo isso enquanto uso números gerados aleatoriamente sem substituição? Não quero, por exemplo, seis alunos em um grupo e quatro alunos em outro.

Primeiro, preciso criar alguns dados fictícios, em R. Vamos criar essa lista de alunas simuladas.

 FemaleStudents <- data.frame (Nomes = c ("Alice", "Betty", "Carol", "Denise", "Erica", "Frances", "Gina", "Helena", "Iris", "Julie" "Katherine" 
"Lisa", "Michelle", "Ngaire", "Olivia", "Penelope", "Rachel", "Sarah", "Trudy", "Uma")

Agora temos um conjunto de dados unidimensional de nossos 20 alunos.

Sabemos que a função runif() não cria números inteiros. Por que não arredondamos os números aleatórios para que só obtemos inteiros e usemos essa função? Podemos envolver o número aleatório em uma função de arredondamento.

Pergunta 1: por que estou usando a distribuição uniforme aleatória e não outra, como a distribuição normal aleatória?

Existem cinco tipos de funções de arredondamento em R. Usaremos round() .

Para que possamos obter os mesmos resultados, vou definir uma semente para a geração de números aleatórios. Cada vez que geramos números aleatórios, usamos a mesma semente. Eu decidi em 5 como a semente. Se você não definir uma semente, ou se você definir uma semente diferente de 5, seus resultados serão diferentes dos meus.

 set.seed (5) 
FemaleStudents $ Group <- round (runif (20, 1, 5))

Bem, isso pareceu funcionar. Cada aluno é alocado para um grupo numerado entre 1 e 5.

Vamos verificar novamente a nossa alocação.

 table (FemaleStudents $ Group) 
 1 2 3 4 5 
2 6 5 4 3

Maldito. Apenas um dos cinco grupos tem o número correto de alunos (Grupo 4). Por quê isso aconteceu?

Podemos verificar os números realmente runif() por runif() sem arredondar e deixar a saída ser impressa no console. Aqui, a saída é impressa porque não atribuí a função a um objeto (por exemplo, a uma variável data.frame).

 set.seed (5) 
runif (20,1,5)
 [1] 1.800858 3.740874 4.667503 2.137598 1.418601 3.804230 3.111840 4.231741 4.826001 1.441812 2.093140 2.962053 2.273616 3.236691 2.050373 
[16] 1,807501 2,550103 4,551479 3,219690 4,368718

Como podemos ver, o arredondamento causou nosso problema. Mas se não tivéssemos sido arredondados, cada aluno teria sido designado para um grupo diferente.

O que nós fazemos?

amostra()

sample() é agora uma das minhas funções favoritas em R. Vamos ver como funciona.

Alocar aleatoriamente para grupos de tamanho igual (conta matéria)

Como podemos usá-lo para atribuir aleatoriamente nossos 20 alunos a quatro grupos de tamanho igual?

O que acontece se tentarmos sample() normalmente?

 set.seed (5) 
FemaleStudents $ Sample <- sample (1: 5, nrow (FemaleStudents), substituir = TRUE)

Pergunta 2: qual saída você obteve quando usou a table(FemaleStudents$Sample) ?

Podemos corrigir esse problema criando um vetor de números de grupo e, em seguida, usando amostragem sem substituição desse vetor. O comando rep é usado para criar um intervalo de valores repetidos. Você pode usá-lo para repetir cada número da série, como usei aqui. O número 1 é repetido quatro vezes, depois o número 2 é repetido quatro vezes e assim por diante. Você também pode usá-lo para repetir uma seqüência de números, se você usar este código: rep(1:5,4)

 OurGroups <- rep (1: 5, cada = 4) 
set.seed (5)
FemaleStudents $ Sample <- amostra (OurGroups, nrow (FemaleStudents), replace = FALSE)

Usamos nosso vetor de números ( OurGroups ) para alocar nossos alunos em grupos. Usamos amostragem sem substituição ( replace=FALSE ) de OurGroups porque precisamos usar cada valor nesse vetor. Precisamos remover cada valor conforme o usamos.

E nós conseguimos o resultado que queríamos!

 table (FemaleStudents $ Sample) 
 1 2 3 4 5 
4 4 4 4 4

Pergunta 3 : por que eu ainda coloquei uma semente?

Outra vantagem do sample() é que ele não se importa com o tipo. Podemos repetir a alocação usando um vetor de strings. Isso pode ser útil se você não quiser continuar se referindo ao que significa "1".

 OurNamedGroups <- rep (c ("Acima", "Abaixo", "Encantado", "Estranho", "Superior"), cada = 4) 
set.seed (5)
FemaleStudents $ Sample2 <- sample (OurNamedGrupos, nrow (FemaleStudents), replace = FALSE)
table (FemaleStudents $ Sample2)
 Charmed Down Strange Top Up 
4 4 4 4 4

Como usamos a mesma semente, podemos ver que a mesma alocação de alunos foi executada, independentemente de termos usado dados numéricos ou de caractere para a tarefa.

 table (FemaleStudents $ Sample, FemaleStudents $ Sample2) 

Charmed Down Strange Top Up
1 0 0 0 0 4
2 0 4 0 0 0
3 4 0 0 0 0
4 0 0 4 0 0
5 0 0 0 4 0

Alocar aleatoriamente quando o tamanho do grupo não é restrito

Às vezes queremos alocar aleatoriamente para grupos, mas não temos um vetor de grupos. Ainda estamos alocando cada unidade (pessoa, ovelha, bloco de queijo) para um único grupo, e usamos alocação completamente aleatória.

Digamos que nossa escola tenha uma nova e especial sala de biblioteca. Foi construído para ser à prova de som para proporcionar aos alunos um melhor ambiente de estudo. O bibliotecário chefe gostaria de saber sobre as experiências dos alunos naquela sala. O único problema é que o quarto é limitado em tamanho. O bibliotecário-chefe acha que cerca de quatro alunos é um grupo grande o suficiente para fornecer o feedback inicial.

Mais uma vez, podemos usar sample() para selecionar nossos grupos de alunos. Neste caso, temos “alunos que testam a sala” e “alunos que não testam a sala”. Eu vou chamá-los de "teste" e "não teste". Estas etiquetas foram escolhidas por serem 1. curtas e 2. facilmente distinguidas.

Como fizemos amostragem sem substituição antes, não especificamos probabilidades de atribuição a grupos – simplesmente extraímos uma atribuição de um vetor. Agora vamos usar amostragem com substituição. Com substituição refere-se ao grupo, não aos alunos.

Precisamos amostrar com a substituição, pois só temos dois grupos ("Teste", "Não teste") e 20 alunos. Se tentássemos amostrar sem substituição, nosso código seria um erro.

Nosso código é muito parecido:

 set.seed (5) 
FemaleStudents $ Library <- sample (c ("Teste", "Não teste"), nrow (FemaleStudents), substituir = TRUE, prob = c (4 / 20,16 / 20))
table (biblioteca de FemaleStudents $)
 Não teste teste 
15 5

Como você pode ver, alocamos cinco alunos para testar a sala, não quatro. Esse tipo de resultado é esperado ao lidar com amostras pequenas. No entanto, nossa alocação de estudantes é completamente aleatória. Cada aluno tinha exatamente a mesma probabilidade de ser designado para testar a sala. Se os alunos anteriores foram testadores ou não, não tiveram impacto na alocação do próximo aluno.

Vamos percorrer alguns desses códigos.

Eu construí uma nova variável no data.frame para coletar a alocação ( Library ).

Em vez de lidar com números para nomes de grupos, usei as strings que mencionei anteriormente. Como usei strings, o c() deve envolver os nomes dos grupos ( “Test”, “Not test” ) e cada nome de grupo é separado por uma vírgula.

A substituição foi definida para TRUE .

A probabilidade de atribuição a um dos grupos deve ser fornecida. Esta é a parte prob=c(4/20,16/20) da função sample() . Novamente, observe como c() é usado para conter as probabilidades. Também é interessante que as probabilidades possam ser expressas como frações, em vez de decimais.

Hooray para amostra ()

Eu uso sample() o tempo todo para o trabalho que estou fazendo. A capacidade de usar strings, bem como restringir a saída numérica a números inteiros (e definir o intervalo inteiro desejado), me fornece mais controle do que tentar usar uma das funções numéricas aleatórias.

Respostas

Resposta 1 : usei uma distribuição uniforme aleatória porque queria que cada valor fosse igualmente provável.

Resposta 2 : recebi esta saída:

 1 2 3 4 5 
2 7 4 2 5

Resposta 3: Se não definirmos um valor de semente, ou se usarmos um valor diferente, a alocação de alunos específicos será diferente. Por exemplo, quando a semente é 5, Alice é alocada para o grupo 2. Se a semente for 7, Alice é alocada para o grupo 5. A replicação é importante quando o código precisa ser executado novamente (por exemplo, em teste).

Texto original em inglês.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *