Nesse capítulo veremos algumas aplicações dos conceitos aprendidos para cálculos estatísticos. Não teremos conteúdo novo, vamos apenas aplicar os controles de fluxo e o uso de funções e aproveitar para rever parte do conteúdo de Estatística Básica.
A partir desse capítulo vamos nos concentrar na análise e implementação de algoritmos e por isso será evitado a apresentação de códigos prontos na linguagem R. Em vez disso serão apresentados e discutidos alguns pseudo-códigos (passo-a-passo), como costuma aparecer na maioria dos livros. As aulas práticas serão dedicadas à implementação dos algoritmos a partir dos pseudo-códigos apresentados em sala de aula.
A maioria das funções que serão implementadas nessa seção já estão prontas no R. Mas não vamos usar as funções prontas e sim criar as nossas próprias funções. O objetivo é parar para pensar como elas foram implementadas e escrever nosso próprio código.
Definição: Seja \(A\) um conjunto de dados. Dizemos que \(a \in A\) é o máximo desse conjunto se \(a \ge r \ \forall \ r \in A\).
Queremos escrever um pseudo-código que recebe como entrada um array de dados e retorna o seu máximo de acordo com a definição acima. Na semana anterior foi implementando uma função que recebe dois ou três números e retorna o maior entre eles. O que está sendo pedido agora é o caso geral: encontrar o máximo entre todos os elementos passados em um array.
A ideia principal do algoritmo apresentado a seguir é percorrer um vetor guardando o maior elemento encontrado até o momento. O algoritmo termina quando o vetor já foi percorrido por completo. Veja como isso pode ser feito no passo-a-passo a seguir.
Entrada: v
= array com os dados.
Saída: valor máximo em v
.
1. Defina n como o tamanho do vetor v;
2. Faça max = v[1];
3. Inicie i = 2;
4. Se v[i] > max , max = v[i];
5. Incremente i: i = i + 1;
6. Se i <= n, volta para a linha 4;
7. Retorne max.
Na linha 2 a variável max
guarda o primeiro elemento do vetor, pois no início do algoritmo esse é o único valor observado, logo o máximo até o momento. Na linha 4 acontece a troca do valor guardado em max
, caso o novo valor observado seja maior que o máximo até o momento.
Veja que o passo-a-passo descreve um loop: as linhas 4 - 6 se repetem várias vezes. Como podemos reproduzir isso em uma linguagem de programação? A resposta é: usando um dos controles de fluxo que repete iterações vistos no Capítulo 2.
A escolha do controle de fluxo depende do algoritmo. No caso deste temos a variável i
que começa assumindo o valor 2 e é incrementada até atingir o valor n
, ou seja, conhecemos o valor inicial e final da variável i
. Dessa forma parece que o for
é uma opção bastante razoável, onde i sera a variável definida dentro dele.
Definição: Seja \(A\) um conjunto de dados. Dizemos que \(a \in A\) é o mínimo desse conjunto se \(a \le r \ \forall \ r \in A\).}
Queremos agora escrever um pseudo-código que recebe como entrada um array de dados e retorna o seu mínimo, de acordo com a definição acima.
A ideia principal do algoritmo proposto é percorrer um vetor guardando o menor elemento encontrado até o momento. O algoritmo termina quando o vetor já foi percorrido por completo. Repare que esse algoritmo é análogo ao apresentado para o máximo, por isso a elaboração do pseudo-código (passo-a-passo) será deixada como exercício.
Definição: Seja \(A = \{a_1, a_2, \ldots, a_n\}\) um conjunto finito de dados e \(n\) o seu número de elementos. A média amostral desse conjunto é definido por: \[
\hbox{média} = \frac{a_1 + a_2 + \ldots + a_n}{n} = \frac{\sum_{i=1}^n a_i}{n}.
\] Queremos agora escrever um pseudo-código que recebe como entrada um array de dados e retorna a sua média de acordo com a definição acima. A ideia principal será percorrer o vetor v
somando seus elementos uma a um. Quando v
já tiver sido percorrido por completo, basta dividir a soma final pelo número total de elementos que encontraremos a média.
Entrada: v
= array com os dados.
Saída: a média amostral dos valores de v
.
1. Defina n como o tamanho do vetor v;
2. Inicie soma=0;
3. Inicie i=1;
4. Incremente a variável soma: soma = soma + v[i];
5. Incremente a variável i: i = i + 1;
6. Se i <= n, volta para a linha 4;
7. Faça media = soma/n;
8. Retorne media.
Repare que temos novamente a ocorrência de um loop
dentro do algoritmo, basta notar a repetição das linhas 4 - 6. Então quando esse passo-a-passo for implementado em uma linguagem de programação sera preciso escolher um controle de fluxo para realizar esse loop.
Definição: Seja \(A = \{a_1, a_2, \ldots, a_n\}\) um conjunto finito de dados e \(n\) o seu número de elementos. Considere a notação de estatística de ordem tal que \(A = \{a_{(1)}, a_{(2)}, \ldots, a_{(n)}\}\) e \(a_{(1)} \le a_{(2)} \le \ldots \le a_{(n)}\). A mediana desse conjunto é definida informalmente como o ponto que separa o conjunto ordenado em duas partes de mesmo tamanho. Sua definição formal encontra-se a seguir. \[ \hbox{mediana } = \left\{ \begin{array}{ll} a_{(\frac{n+1}{2})} & \hbox{, se } n \hbox{ é ímpar;}\\ (a_{(\frac{n}{2})} + a_{(\frac{n}{2}+1)})/2 & \hbox{, se } n \hbox{ é par;}\\ \end{array} \right. \]
Queremos agora escrever um pseudo-código que recebe como entrada um array de dados e retorna a sua mediana de acordo com a definição acima.
Entrada: v
= array com os dados.
Saída: a mediana dos valores de v
.
1. Defina n como o tamanho do vetor v;
2. Defina v_o como o vetor v ordenado;
3. Se n é ímpar, faça mediana = v_o[(n+1)/2];
4. Se n é par, faça mediana = (v_o[n/2] + v_o[(n/2)+1])/2;
5. Retorne mediana
Veja que nesse algoritmo não temos a ocorrência de loops.
Na linha 2 do passo-a-passo acima o vetor v
é ordenado. Ainda não aprendemos como ordenar vetores, isso será visto somente no Capítulo 8. Por isso, pro enquanto, usaremos o comando sort
do R para ordenar vetores.
Definição: Seja \(A = \{a_1, a_2, \ldots, a_n\}\) um conjunto finito de dados e \(n\) o seu número de elementos. Considere a notação de estatística de ordem tal que \(A = \{a_{(1)}, a_{(2)}, \ldots, a_{(n)}\}\) e \(a_{(1)} \le a_{(2)} \le \ldots \le a_{(n)}\). Os quartis desse conjunto é definido informalmente como os três pontos que separam o conjunto ordenado em quatro partes de mesmo tamanho.
Existem alguns métodos para encontrar os quartis de um conjunto de dados. Vejamos a seguir dois desses métodos.
Método 1
Método 2
Queremos escrever um pseudo-código que recebe como entrada um array de dados e retorna cada um dos seus quartis. A ideia será simplesmente seguir um dos métodos acima e recorrer ao cálculo da mediana, que já é conhecido. A seguir isso será feito considerando Método 1. Faça como exercício o pseudo-código considerando o Método 2.
Entrada: v
= array com os dados.
Saída: um array com os 3 quartis dos valores de v
.
1. Defina n como o tamanho do vetor v;
2. Defina v_o como o vetor v ordenado;
3. Sendo n par, defina k = n/2 e j=k+1;
4. Sendo n ímpar, defina k = (n-1)/2 e j=k+2;
5. Defina v_1 como um vetor com os elementos de v_o das posições de 1 até k;
6. Defina v_2 como um vetor com os elementos de v_o das posições de j até n;
7. q_1 = mediana de v_1;
8. q_2 = mediana de v;
9. q_3 = mediana de v_2;
10. Retorna o vetor (q_1, q_2, q_3).
Esse é mais um algoritmo que não apresenta loop. Mas veja que nesse exemplo, para facilitar a implementação, usamos o resultado de outra função teoricamente já implementada, a função que retorna a mediana de um conjunto de valores guardados em um array.
Definição: Seja \(A = \{a_1, a_2, \ldots, a_n\}\) um conjunto finito de dados e \(n\) o seu número de elementos. Seja \(m\) a média amostral de \(A\). A variância amostral desse conjunto é definido por: \[ S^2 = \frac{\sum_{i=1}^n (a_i - m)^2}{n-1}. \]
Queremos escrever um pseudo-código que recebe como entrada um array de dados e retorna a sua variância amostral. A ideia principal é primeiro encontrar a média amostral e em seguida percorrer o array de entrada calculando a variância amostral.
Entrada: v
= array com os dados.
Saída: variância amostral dos valores de v
.
1. Defina n como o tamanho do vetor v;
2. Defina m como a média amostral do vetor v;
3. Inicie soma = 0;
4. Inicie i=1;
5. Incremente a variável soma: soma = soma + (v[i] - m)^2;
6. Incremente i: i = i + 1;
7. Se i <= n, volta para a linha 5;
8. Faça s2 = soma/(n-1);
9. Retorne s2.
Definição: Seja \(A = \{a_1, a_2, \ldots, a_n\}\) e \(B = \{b_1, b_2, \ldots, b_n\}\) dois conjuntos de dados pareados e \(n\) o seu número de elementos. Seja \(m_A\) a média amostral de \(A\) e \(m_B\) a média amostral de \(B\). A covariância amostral entre os conjuntos \(A\) e \(B\) é definida por: \[ \hbox{cov}_{A,B} = \frac{\sum_{i=1}^n (a_i - m_A)(b_i - m_B)}{n-1}. \]
Queremos agora escrever um pseudo-código que recebe como entrada dois arrays de dados e retorna a covariância amostral entre eles.
Entrada: v
= array com os dados, w
= array com os dados.
Saída: covariância amostral entre os valores em v
e w
.
1. Defina n como o tamanho do vetor v;
2. Defina k como o tamanho do vetor w;
3. Se n e k forem diferentes, retorne uma mensagem de erro e FIM.
4. m_v = média amostral de v;
5. m_w = média amostral de w;
6. Inicie soma = 0;
7. Inicie i = 1;
8. Faça soma = soma + (v[i] - m_v)*(w[i] - m_w);
9. Incremente i = i + 1;
10. Se i < = n, volte para a linha 8;
11. Faça cov = soma/(n-1);
12. Retorne cov.