1
resposta

sobre distribuição cumulativa

Nesta aula o Guilherme até menciona o insight de maneira tabular, mas acredito que ele não tenha utilizado. Ao buscar por distribuição cumulativa em python, encontrei a função numpy.linspace do numpy. Entendo que se eu passar o min e o max da coluna média consigo criar uma distribuição uniforme que me dê os mesmos insights que o Guilherme teve usando gráficos. Pode me dizer se é isso mesmo e me dar um exemplo de como ter os insights de distribuição cumulativa de maneira tabular? Obrigado!

1 resposta

Olá Pietro, tudo bem? Espero que sim!

Os histogramas são representações visuais de tabelas de frequências. As tabelas de frequências podem ser construídas utilizando a função value_counts(), que conta a quantidade de vezes que determinada categoria aparece.

Quando estivermos trabalhando com valores numéricos, podemos usar a função value_counts() usando o parâmetro bins e passando a quantidade de intervalos que queremos dividir nossos dados. Para separações manuais e mais personalizadas, podemos usar a função pd.cut() para selecionar os intervalos.

O problema é que a função não calcula de forma acumulada, mas podemos fazer isso utilizando algum código. Darei um exemplo usando os dados da aula, os mesmos usados na construção de um dos histogramas acumulados da aula. Primeiramente, vamos importar os dados do arquivo ratings.csv e fazer transformações necessárias para se chegar ao conjunto de dados que foi utilizado no histograma da aula. Esses códigos estão disponíveis no curso:

import pandas as pd
notas = pd.read_csv("ratings.csv")
nota_media_por_filme = notas.groupby("movieId").mean()["rating"]
quantidade_de_votos_por_filme = notas.groupby("movieId").count()
filmes_com_pelo_menos_10_votos = quantidade_de_votos_por_filme.query("rating >= 10").index
nota_media_dos_filmes_com_pelo_menos_10_votos = nota_media_por_filme.loc[filmes_com_pelo_menos_10_votos.values]

Através do conjunto de dados nota_media_dos_filmes_com_pelo_menos_10_votos, podemos construir uma tabela de frequências usando o método value_counts(). Vou utilizar bins = 10, para criar 10 intervalos de mesmo tamanho. Você pode alterar o parâmetro bins como desejar, se baseando em fórmulas como a Regra de Sturges para selecionar a quantidade de intervalos ideal. Além disso, utilizarei o parâmetro sort = False para que os dados não fiquem ordenados com base na quantidade e sim pela ordem natural dos intervalos. Transformarei em um DataFrame e vou armazenar em uma variável com nome freq.

freq = pd.DataFrame(nota_media_dos_filmes_com_pelo_menos_10_votos.value_counts(bins = 10, sort= False))
freq

Ao visualizar essa tabela, obtenho a tabela de frequências:

rating
(1.346, 1.674]5
(1.674, 1.998]12
(1.998, 2.322]45
(2.322, 2.646]112
(2.646, 2.97]235
(2.97, 3.295]388
(3.295, 3.619]563
(3.619, 3.943]555
(3.943, 4.267]324
(4.267, 4.591]30

Essa tabela de frequências ainda não é acumulada. Para encontrarmos a tabela de frequência acumulada, devemos somar os valores de intervalos anteriores para obter o valor acumulado daquele intervalo. Para isso, podemos utilizar o código a seguir:

acumulada = []
for indice, valor in enumerate(freq.values):
    acumulada.append(int(valor + sum(freq['rating'][:indice])))
freq['acumulada'] = acumulada
freq

Inicialmente, foi criada uma lista vazia, e utilizado um loop para percorrer os índices e valores da nossa tabela de frequências e foram salvos na lista acumulada a soma dos valores da tabela de frequências até o índice que está sendo percorrido. Essa lista então, foi armazenada em uma nova coluna do DataFrame, com nome 'acumulada'. Podemos observar a nova tabela de frequências acumulada:

ratingacumulada
(1.346, 1.674]55
(1.674, 1.998]1217
(1.998, 2.322]4562
(2.322, 2.646]112174
(2.646, 2.97]235409
(2.97, 3.295]388797
(3.295, 3.619]5631360
(3.619, 3.943]5551915
(3.943, 4.267]3242239
(4.267, 4.591]302269

Você também pode querer utilizar a tabela de frequências em forma de porcentagem, que contêm as frequências relativas e frequências relativas acumuladas. Para isso, pode utilizar o parâmetro normalize = True na função value_counts(). Multiplicarei por 100 para que os valores fiquem em forma de porcentagem, e o código será muito parecido com os códigos anteriores:

freq2 = pd.DataFrame(nota_media_dos_filmes_com_pelo_menos_10_votos.value_counts(bins = 10, sort= False, normalize= True)*100)
acumulada = []
for indice, valor in enumerate(freq2.values):
    acumulada.append(float(valor + sum(freq2['rating'][:indice])))
freq2['acumulada'] = acumulada
freq2

Obtemos assim a tabela:

ratingacumulada
(1.346, 1.674]0.2203610.2203
(1.674, 1.998]0.5288670.74922
(1.998, 2.322]1.983252.73248
(2.322, 2.646]4.93617.66858
(2.646, 2.97]10.35718.0256
(2.97, 3.295]17.135.1256
(3.295, 3.619]24.812759.9383
(3.619, 3.943]24.460184.3984
(3.943, 4.267]14.279498.6778
(4.267, 4.591]1.32217100

Você pode explorar outras opções como a função pd.cut(), a quantidade de bins, substituir a coluna rating pela acumulada para que tenha somente a informação desejada, e arredondar os valores com a função round() para que os valores não fiquem muito grandes.

Espero que tenha tirado sua dúvida.

Estou à disposição. Bons estudos!