Em sistemas integrados de gestão (que atendem ao nível operacional, gerencial e estratégico), é muito comum o cálculo e apresentação de resultados estatísticos de dados gerados pelo nível operacional. Com estes resultados, é possível montar gráficos que facilitam a visualização (postei outro dia como gerar gráficos com o google chart). Neste artigo serão apresentadas algumas funções úteis para o cálculo de algumas informações estatísticas.
Extensão PECL "stat"
Existe uma extensão PECL chamada "stats" para PHP, que está disponível em http://pecl.php.net/package/stats e cuja documentação pode ser obtida em http://br.php.net/manual/pt_BR/book.stats.php. Para saber como instalar extensões PECL, veja o artigo: Instalação de Módulos Pear e Pecl.
Infelizmente, várias funções não estão claramente documentadas. Porém, mesmo assim, várias delas são compreensíveis e os parâmetros também são intuitivos para quem conhece a linguagem técnica usada em estatística (em inglês).
Por exemplo, para se obter o desvio padrão (standard deviation) de um conjunto de números, basta usar a função stats_standard_deviation, que recebe um array de números e, opcionalmente, um booleano indicando se deve ser considerada uma amostra do array ou todos os elementos (por padrão são considerados todos os elementos).
$array = array(8, 9, 6, 8.5, 7, 8.3, 9.1); $desvio_padrao = stats_standard_deviation($array);
Veja uma lista com as funções de estatística mais comuns:
- Funções gerais:
  
- stats_absolute_deviation - Desvio absoluto;
 - stats_covariance - Covariância entre dois arrays;
 - stats_kurtosis - Curtose;
 - stats_skew - Obliquidade;
 - stats_standard_deviation - Desvio Padrão;
 - stats_variance - Variância;
 - stats_stat_binomial_coef - Coeficiênte Binomial;
 - stats_stat_correlation - Coeficiente de correlação de Pearson;
 - stats_stat_powersum - Fórmula de Faulhaber;
 
 - Funções de Distribuição:
  
- stats_den_uniform - Distribuição uniforme;
 - stats_dens_beta - Distribuição beta;
 - stats_den_cauchy - Distribuição de Cauchy;
 - stats_dens_chisquare - Distribuição Chi-quadrado (χ2);
 - stats_dens_exponential - Distribuição Exponencial;
 - stats_dens_f - Distribuição f de Fisher-Snedecor;
 - - Distribuição Gama (Γ);
 - stats_dens_normal - Distribuição normal;
 - stats_dens_pmf_binomial - Distribuição binomial;
 - stats_dens_negative_binomial - Distribuição binomial negativa;
 - stats_dens_t - Distribuição t de Student;
 
 - Função Distribuição Acumulada (fda)
  
- stats_cdf_beta - Distribuição beta;
 - stats_cdf_binomial - Distribuição binomial;
 - stats_cdf_chisquare - Distribuição chi-quadrado;
 - stats_cdf_exponential - Distribuição exponencial;
 - stats_cdf_f - Distribuição f de Fisher-Snedecor
 - stats_cdf_gamma - Distribuição gama
 - stats_cdf_negative_binomial - Distribuição binomial negativa;
 - stats_cdf_normal - Distribuição normal;
 - stats_cdf_t - Distribuição t de Student;
 - stats_cdf_uniform - Distribuição uniforme;
 
 - Funções de Geração de Valores Aleatórios:
  
- stats_rand_gen_beta - Distribuição beta;
 - stats_rand_gen_chisquare - Distribuição chi-quadrado;
 - stats_rand_gen_exponential - Distribuição exponencial;
 - stats_rand_gen_f - Distribuição f de Fisher-Snedecor;
 - stats_rand_gen_gamma - Distribuição Gama;
 - stats_rand_gen_ibinomial - Distribuição binomial;
 - stats_rand_gen_ibinomial_negative - Distribuição binomial negativa;
 - stats_rand_gen_iuniform - Distribuição uniforme;
 - stats_rand_gen_normal - Distribuição normal;
 - stats_rand_gen_t - Distribuição t de Student;
 
 
Outras funções básicas
A extensão "stat" implementa várias funções complexas, mas existem outras mais simples que não estão disponíveis, tais como a média aritmética, a moda e a mediana. Para tanto, basta implementar como no exemplo abaixo:
/**
 * Calcula a media de um array de numeros
 * @param array $a Array de numeros
 * @return number Retorna a media dos valores do array
 */
function media_aritmetica(array $a) {
    return array_sum($a) / count($a);
}
/**
 * Retorna o valor que mais aparece no array (moda estatistica)
 * @param array $a Array de valores
 * @param int $quantidade Quantidade de vezes que a moda foi observada
 * @return array Valores mais observados no array
 */
function moda(array $a, &$quantidade = 0) {
    $moda = array();
    if (empty($a)) {
        return $moda;
    }
    // Calcular quantidade de ocorrencias de cada valor
    $ocorrencias = array();
    foreach ($a as $valor) {
        $valor_str = var_export($valor, true);
        if (!isset($ocorrencias[$valor_str])) {
            $ocorrencias[$valor_str] = array(
                'valor' => $valor,
                'ocorrencias' => 0
            );
        }
        $ocorrencias[$valor_str]['ocorrencias'] += 1;
    }
    // Determinar maior ocorrencia
    $quantidade = null;
    foreach ($ocorrencias as $item) {
        if ($quantidade === null || $item['ocorrencias'] >= $quantidade) {
            $quantidade = $item['ocorrencias'];
        }
    }
    // Obter valores com a maior ocorrencia
    foreach ($ocorrencias as $item) {
        if ($item['ocorrencias'] == $quantidade) {
            $moda[] = $item['valor'];
        }
    }
    return $moda;
}
/**
 * Obtem a mediana de um array de numeros.
 * @param array $a Array de numeros
 * @param callback $comparacao Funcao de comparacao para ordenar o array (ou null para usar a funcao sort para ordenar)
 * @return number || bool Mediana do array ou false, caso seja passado um array vazio
 */
function mediana(array $a, $comparacao = null) {
    if (empty($a)) {
        return false;
    }
    // Ordenar o array
    if ($comparacao === null) {
        sort($a);
    } else {
        usort($a, $comparacao);
    }
    $tamanho = count($a);
    // Tamanho impar: obter valor mediano
    if ($tamanho % 2) {
        $mediana = $a[(($tamanho + 1) / 2) - 1];
    // Tamanho par: obter a media simples entre os dois valores medianos
    } else {
        $v1 = $a[($tamanho / 2) - 1];
        $v2 = $a[$tamanho / 2];
        $mediana = ($v1 + $v2) / 2;
    }
    return $mediana;
}
2 comentários
Otimoo, me ajudou muito!
Adorei as funções, mas a função da moda está voltando um array com o array enviado. E para que serve o parâmetro quantidade? O objetivo da moda não é descobrir o item que aparece com maior frequência no array?
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com