Histogramas com frequência Apache Commons

Histogramas com frequência Apache Commons

 

1. Visão geral

Neste tutorial, veremos como podemos apresentar dados em um histograma com a ajuda da classe Apache CommonsFrequency.

O sclassFrequency faz parte da biblioteca Apache Commons Math explorada nestearticle.

Um histograma é um diagrama de barras conectadas que mostra a ocorrência de um intervalo de dados em um conjunto de dados. É diferente de um gráfico de barras porque é usado para exibir a distribuição de variáveis ​​quantitativas contínuas, enquanto um gráfico de barras é usado para exibir dados categóricos.

2. Dependências do projeto

Neste artigo, usaremos um projeto Maven com as seguintes dependências:


    org.apache.commons
    commons-math3
    3.6.1


    org.knowm.xchart
    xchart
    3.5.2

A bibliotecacommons-math3 contém a classeFrequency que usaremos para determinar a ocorrência de variáveis ​​em nosso conjunto de dados. A bibliotecaxchart é o que usaremos para exibir o histograma em uma GUI.

A versão mais recente decommons-math3exchart pode ser encontrada no Maven Central.

3. Cálculo da frequência de variáveis

Para este tutorial, usaremos um conjunto de dados que compreende a idade dos alunos em uma escola específica. Gostaríamos de ver a frequência das diferentes faixas etárias e observar sua distribuição em um gráfico de histograma.

Vamos representar o conjunto de dados com uma coleçãoList e usá-lo para preencher uma instância da classeFrequency :

List datasetList = Arrays.asList(
  36, 25, 38, 46, 55, 68,
  72, 55, 36, 38, 67, 45, 22,
  48, 91, 46, 52, 61, 58, 55);
Frequency frequency = new Frequency();
datasetList.forEach(d -> frequency.addValue(Double.parseDouble(d.toString())));

Now that we’ve populated our instance of the Frequency class, we’re going to get the count of each age in a bin and sum it up so we can get the total frequency of ages in a particular age group:

datasetList.stream()
  .map(d -> Double.parseDouble(d.toString()))
  .distinct()
  .forEach(observation -> {
      long observationFrequency = frequency.getCount(observation);
      int upperBoundary = (observation > classWidth)
        ? Math.multiplyExact( (int) Math.ceil(observation / classWidth), classWidth)
        : classWidth;
      int lowerBoundary = (upperBoundary > classWidth)
        ? Math.subtractExact(upperBoundary, classWidth)
        : 0;
      String bin = lowerBoundary + "-" + upperBoundary;

      updateDistributionMap(lowerBoundary, bin, observationFrequency);
  });

A partir do snippet acima, primeiro determinamos a frequência deobservation usandogetCount() da classeFrequency. The method returns the total number of occurrence of the*observation*. 

Usando oobservation, atual, determinamos dinamicamente a qual grupo ele pertence, descobrindo seus limites superior e inferior em relação à largura da classe - que é 10.

Os limites superior e inferior são concatenados para formar um bin, que é armazenado junto comobservationFrequency em adistributionMap usandoupdateDistributionMap().

Se obin já existe, atualizamos a frequência, senão o adicionamos como chave e definimos a frequência doobservation atual como seu valor. Observe que mantivemos o controle das observações processadas para evitar duplicatas.

A classeFrequency também possui métodos para determinar a porcentagem e a porcentagem cumulativa de uma variável em um conjunto de dados.

4. Plotando o gráfico de histograma

Agora que processamos nosso conjunto de dados brutos em um mapa de grupos de idade e suas respectivas frequências, podemos usar a bibliotecaxchart para exibir os dados em um gráfico de histograma:

CategoryChart chart = new CategoryChartBuilder().width(800).height(600)
  .title("Age Distribution")
  .xAxisTitle("Age Group")
  .yAxisTitle("Frequency")
  .build();

chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW);
chart.getStyler().setAvailableSpaceFill(0.99);
chart.getStyler().setOverlapped(true);

List yData = new ArrayList();
yData.addAll(distributionMap.values());
List xData = Arrays.asList(distributionMap.keySet().toArray());
chart.addSeries("age group", xData, yData);

new SwingWrapper<>(chart).displayChart();

Criamos uma instância de aCategoryChart usando o criador de gráficos, então a configuramos e a populamos com os dados para os eixos xey.

Finalmente exibimos o gráfico em uma GUI usando oSwingWrapper:

image

No histograma acima, podemos ver que não há alunos com idades entre 80 e 90 anos, enquanto os estudantes entre 50 e 60 anos são predominantes. Provavelmente serão estudantes de doutorado ou pós-doutorado.

Também podemos dizer que o histograma tem uma distribuição normal.

5. Conclusão

Neste artigo, vimos como aproveitar o poder daFrequency class da biblioteca do Apachecommons-math3.

Existem outras classes interessantes para estatística, geometria, algoritmos genéticos e outras na biblioteca. Sua documentação pode ser encontradahere.

O código-fonte completo está disponívelover at Github.