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:
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.