09 de maio, 2020
A Netflix é uma provedora global de filmes e séries de televisão via streaming sediada em Los Gatos, Califórnia, e que atualmente possui mais de 160 milhões de assinantes. Fundada em 1997 nos Estados Unidos, a empresa surgiu como um serviço de entrega de DVD pelo correio. A expansão do streaming, disponível nos Estados Unidos a partir de 2007, começou pelo Canadá em 2010. Hoje, mais de 190 países têm acesso à plataforma. Sua primeira websérie original de sucesso foi House of Cards, lançada em 2013. Hoje em dia, a empresa produz centenas de horas de programação original em diferentes países do mundo, querendo aprimorar-se nas aplicações e em novas programações.
Neste projeto iremos analisar os principais dados financeiros fornecidos trimestralmente pela Netflix entre 2012 e 2018. Os dados foram extraídos da página Netflix Investor.
Objetivo: utilizar a linguagem R para preparar um resumo estatístico dos dados da empresa, demonstrando sua saúde financeira e outras informações relevantes, que poderão ajudar potenciais investidores a decidir sobre investir ou não na companhia.
Começaremos nosso projeto, importanto todas as bilbiotecas necessárias, para a realização das fases iniciais de exploração, e transformação dos dados (Data Munging).
# Definindo a ocultação de warnings.
options(warn = -1)
# Difinindo o nome das bibliotecas que serão utilizadas.
librarys <- c(
'ggplot2',
'plyr',
'corrplot',
'caret',
'GGally',
'dplyr',
'DMwR',
'e1071',
'data.table',
'readxl',
'lubridate',
'car',
'xts',
'forecast',
'tseries',
'tidyr',
'ggfortify'
)
# Instalando bibliotecas necesárias diretamente do repósito no Github.
devtools:: install_github("brisneve/ggplottimeseries")
# Atribuindo bilioteca a lista de importações.
librarys <- append(librarys, 'ggplottimeseries')
# Se não possuir uma das bibliotecas importadas abaixo, use a função a seguir:
install.packages(librarys, character.only = TRUE)
# Importando as bibliotecas presentes na lista.
for(l in librarys) {
# Importa a biblioteca especificada.
library (
package = l, # Define o nome da biblioteca que deve ser importada.
character.only = TRUE # Define que o nome do pacote deve ser considerado como uma String.
)
}
# Importando os dados do dataset.
dataset <- read_xlsx("/content/datasets/Netflix_Data.xlsx", col_names = T)
# Criando cópia do dataset.
data <- dataset
# Visualizando os primeiros registros do conjunto de dados.
head(data)
Antes de prosseguirmos, é importante destacarmos que cada observação do dataset, contém dados que foram extraídos do site da Netflix Investor, e estão distribuídos nas seguintes variáveis:
Variável | Tipo | Descrição |
---|---|---|
Time | Character | É a data de emissão do resultado trimestral; |
Total subscriptions at end of period | Double | É o número total de assinaturas registradas no final do trimestre; |
Paid subscriptions at end of period | Double | É o número de assinaturas pagas registradas no final do trimestre; |
Free Trails | Double | É o número de assinaturas em período de utilização gratuita registradas no final do trimestre; |
Revenue | Double | É a receita trimestral gerada para o Streaming doméstico (em milhares de dólares); |
Cost of revenues | Double | É o custo trimestral da receita gerada para o Streaming doméstico (em milhares de dólares); |
Marketing | Double | É o custo trimestral de Marketing gerado para o Streaming doméstico (em milhares de dólares); |
Contribution profit | Double | É o lucro da contribuição trimestral (em milhares de dólares); |
Contribution Margin | Double | É a margem de contribuição trimestral (Contribution profit / Revenue); |
Cost per Customer (excluding marketing) | Double | É a taxa de custo por cliente desconsiderando os gastos com Marketing (Cost of revenues / Total subscriptions at end of period); |
Revenue per Customer | Double | É a taxa de receita por cliente (Revenue / Total subscriptions at end of period); |
Earnings per Customer | Double | É a taxa de lucro por cliente ((Revenue - Cost of revenues) / Total subscriptions at end of period) e; |
Segment | Character | É o segmento de operação da companhia ao qual os dados se referem. |
Nosso primeio passo, será trocar o nome das colunas para facilitar a análise nas próximas etapas.
# Alterando os nomes das colunas do dataset.
names(data) <- c(
"date",
"totalSubscriptions",
"paidSubscriptions",
"freeTrails",
"revenue",
"costOfRevenues",
"marketing",
"contributionProfit",
"contributionMargin",
"costPerCustomer",
"revenuePerCustomer",
"earningsPerCustomer",
"segment"
)
# Visualizando os primeiros registros do conjunto de dados.
head(data)
# Verificando a existência de registros duplicados.
table(duplicated(data))
Bom, constatamos que não há registros duplicados no conjunto de dados.
# Verificando a existência de valores NA no dataset.
data.frame(anyNA = sapply(data, anyNA))
Não foi detectado nenhum valor NA dentro do conjunto de dados.
Algumas varíaveis no dataset, foram associadas a tipos de dados incorretos. Observe que:
Começaremos alterando o tipo de dado da variável date.
# Alterando o tipo de dado da variável date.
data$date <- as.Date(data$date, format = "%B %d, %Y")
Converteremos o tipo de dado da variável segment.
# Alterando o tipo de dado da variável segment.
data$segment <- as.factor(data$segment)
Agora, iremos verificar, se existe algum valor frácionário no conjunto de dados das variáveis totalSubscriptions, paidSubscriptions e freeTrails, que justifique, a utilização do tipo de dado com o qual o dataset foi carregado.
# Verificando os valores únicos existentes, em cada variável do dataset, antes da conversão do tipo de dado.
uniqValuesBefore <- sapply(data, function(v) {
sort(unique(v))
})
# Exibindo valores únicos, em cada variável do dataset, que irá sofrer a conversão.
uniqValuesBefore[c('totalSubscriptions', 'paidSubscriptions', 'freeTrails')]
Bom, não encontramos nenhum valor fracionário e por isso iremos converter as variáveis para o tipo de dado inteiro.
# Alterando o tipo da variável totalSubscriptions para o tipo inteiro.
data$totalSubscriptions <- as.integer(data$totalSubscriptions)
# Alterando o tipo da variável paidSubscriptions para o tipo inteiro.
data$paidSubscriptions <- as.integer(data$paidSubscriptions)
# Alterando o tipo da variável freeTrails para o tipo inteiro.
data$freeTrails <- as.integer(data$freeTrails)
# Visualizando os primeiros registros do conjunto de dados.
head(data)
# Verificando os valores únicos existentes, em cada variável do dataset, após a conversão do tipo de dado.
uniqValuesAfter <- sapply(data, function(v) {
sort(unique(v))
})
# Exibindo valores únicos, em cada variável do dataset, que sofreu a conversão.
uniqValuesAfter[c('totalSubscriptions', 'paidSubscriptions', 'freeTrails')]
Por precaução, vamos nos certificar de que não perdemos nenhuma informação, e que todos os dados do conjunto das variáveis convertidas, permanecem iguais.
# Verificando se todos os valores únicos da variável totalSubscriptions permanecem iguais, após a conversão do tipo de dado.
as.data.frame(table(totalSubscriptions = uniqValuesBefore$totalSubscriptions == uniqValuesAfter$totalSubscriptions))
# Verificando se todos os valores únicos da variável paidSubscriptions permanecem iguais, após a conversão do tipo de dado.
as.data.frame(table(paidSubscriptions = uniqValuesBefore$paidSubscriptions == uniqValuesAfter$paidSubscriptions))
# Verificando se todos os valores únicos da variável freeTrails permanecem iguais, após a conversão do tipo de dado.
as.data.frame(table(freeTrails = uniqValuesBefore$freeTrails == uniqValuesAfter$freeTrails))
Perfeito, nenhum dos valores das variáveis que manipulamos foi alterado, ou seja, não perdemos nenhuma informação, e já temos nosso dataset pronto para as próximas fases de análise.
Ter variáveis que representem o mês e o ano de cada um dos registros do conjunto de dados, pode ser interessante, e por isso, extrairemos estas informações e as armazenaremos nas variáveis month e year.
# Criando variáveis para armazenar o mês e o ano de cada registro do dataset.
data <- data %>%
mutate(
month = as.factor(months(date)),
year = as.factor(year(date))
)
# Visualizando as primeiras linhas do dataset.
head(data)
Ao analisar as características do dataset, e como elas podem se relacionar, vemos a possibilidade de se criar duas variáveis novas, que podem ser úteis para o processo de análise:
Iremos denominá-las como: freeTrialsFromTotal e marketingFromTotal, respectivamente.
# Criando as variáveis freeTrialsFromTotal e marketingFromTotal.
data <- data %>%
mutate(
# Proporção de avaliações gratuitas do total de assinaturas.
freeTrialsFromTotal = freeTrails / totalSubscriptions * 100,
# Proporção de custo com marketing em relação ao custo total.
marketingFromTotal = marketing / (costOfRevenues + marketing) * 100
)
# Visualizando as primeiras linhas do dataset.
head(data)
Iremos definir algumas funções, para padronizar as plotagens de gráficos que criaremos.
# Definindo uma função para criar gráficos de barras.
barPlot <- function(col, data, x = 'date', color = '#EE4266', startTime = '2012-01-31') {
data %>%
mutate(date = format(date, "%b, %Y")) %>%
ggplot(aes(x = reorder(date, 1:length(date)))) +
geom_bar(aes_string(y = col), stat = 'identity', fill = color, alpha = 0.85) +
theme_bw() +
xlab('Quarter') +
ggtitle(paste("Bar chart for variable:", col)) +
coord_flip()
}
# Definindo uma função para criar gráficos de Séries Temporais.
timeSeriesPlot <- function(col, data, x = 'date', color = '#69B3A2', startTime = '2012-01-31') {
data %>%
ggplot(aes_string(x = x, y = col)) +
geom_line(color = color, size = 2) +
geom_point(size = 2) +
theme_bw() +
theme(axis.text.x = element_text(angle = 60, hjust = 1)) +
scale_x_date(
limits = as.Date(c(startTime, NA)),
date_labels = "%b, %Y",
date_breaks = '3 months'
) +
xlab('Quarter') +
ggtitle(paste("Time series chart for variable:", col))
}
# Definindo uma função para criar gráficos Boxplot.
boxPlot <- function(col, data, x = 'date', color = c('#777DA7', '#04F06A', '#D5573B'),
startTime = '2012-01-31', categ = 'None') {
# Cria gráficos de Boxplot, para representar os valores da variável especificada, agrupados por ano.
if(categ == 'year') {
data %>%
select_at(c('year', col)) %>%
ggplot(aes_string(x = 'year', y = col)) +
geom_boxplot(fill = color[1], alpha = 0.85) +
theme_bw() +
ggtitle(paste("Boxplot by year for variable:", col)) +
xlab('Year')
# Cria gráficos de Boxplot, para representar os valores da variável especificada, agrupados por mês.
} else if (categ == 'month'){
data %>%
select_at(c('month', col)) %>%
ggplot(aes_string(x = 'month', y = col)) +
geom_boxplot(fill = color[2], alpha = 0.85) +
theme_bw() +
ggtitle(paste("Boxplot by month for variable:", col)) +
xlab('Month')
# Cria gráficos de Boxplot, para representar os valores da variável especificada.
} else {
data %>%
ggplot(aes_string(x = col)) +
geom_boxplot(fill = color[3], alpha = 0.85) +
theme_bw() +
theme(axis.text.y = element_blank()) +
ggtitle(paste("Boxplot for variable:", col))
}
}
# Definindo uma função para criar gráficos de Densidade.
densityPlot <- function(col, data, x = 'date', color = '#258EA6', startTime = '2012-01-31') {
data %>%
ggplot(aes_string(x = col)) +
geom_density(fill = color, alpha = 0.75) +
theme_bw() +
ggtitle(paste("Density chart for variable:", col))
}
Criaremos uma função, para padronizar as estatísticas que calcularemos, em cada uma das variáveis a serem estudadas.
# Definindo uma função, para gerar um dataframe, com as estatísticas de uma variável do dataset.
varStats <- function(col, data) {
isFactor = sapply(data, is.factor)
if(!isFactor[col]) {
# Calcula estatísticas de variáveis numéricas.
result <- data %>%
summarize(
Min = min(get(col)),
Q1 = unname(quantile(get(col), probs = c(0.25))),
Median = median(get(col)),
mean = mean(get(col)),
Q3 = unname(quantile(get(col), probs = c(0.75))),
Max = max(get(col)),
Sd = sd(get(col)),
Sk = skewness(get(col)),
Ck = kurtosis(get(col))
)
} else {
# Contabiliza o número de registros, dentro de cada classe da variável.
result <- data %>%
group_by_at(col) %>%
summarise(
count = n(),
prop = n() / nrow(data) * 100
)
}
# Retorna o resultado das estatísticas geradas.
data.frame(result, row.names = col)
}
O coeficente de Assimetria (Skewness), indica como os dados estão distribuídos, e para interpretar seu resultado podemos olhar a tabela a seguir:
Índice de Assimetria | Descrição |
---|---|
SK ≈ 0 | Os dados são simétricos. Tanto a cauda do lado direito, quanto a do lado esquerdo da função densidade de probabilidade, são iguais; |
SK < 0 | A assimetria é negativa. A cauda do lado esquerdo da função densidade de probabilidade, é maior que a do lado direito e; |
SK > 0 | A assimetria é positiva. A cauda do lado direito da função densidade de probabilidade, é maior que a do lado esquerdo. |
O coeficiente de Curtose (Kurtosis), é uma medida que caracteriza o achatamento da curva da função de distribuição, e para interpretar seu resultado, podemos olhar a tabela a seguir:
Índice de Curtose | Descrição |
---|---|
CK ≈ 0 | A distribuição é normal, e é chamada de Curtose Mesocúrtica; |
CK < 0 | A Cauda é mais leve que a normal. Para um coeficiente de Curtose negativo, tem-se uma Curtose Platicúrtica e; |
CK > 0 | A Cauda é mais pesada que a normal. Para um coeficiente de Curtose positivo, tem-se uma Curtose Leptocúrtica. |
Atenção: Há diferentes fórmulas para calcular estes coeficientes. Mas, para este estudo utilizamos as funções fornecidas pela biblioteca e1071, com suas respectivas configurações padrão. Em caso de dúvida, consulte a documentação.
Também criaremos um função, para nos auxiliar na detecção de outliers.
# Função para extrair os registros, que apresentem valores outliers, para um determinada variável.
getOutliers <- function(col, data) {
# Extraindo variável, a ser manipulada, pelo nome.
dt <- data %>% select_at(col)
# Renomeando variável.
colnames(dt) <- 'var'
# Determinando o limite superior e inferior da variável especificada.
limits <- dt %>% summarise(
lowerOutliers = quantile(var, probs = c(.25)) - 1.5 * IQR(var),
upperOutliers = quantile(var, probs = c(.75)) + 1.5 * IQR(var)
)
# Identificando registros, que estão fora dos limites especificados.
data[dt$var < limits$lowerOutliers | dt$var > limits$upperOutliers, ]
}
As demais funções a seguir, foram criadas com o objetivo de abstrair a complexidade dos cálculos estatísticos, e aumentar a legibilidade das análises.
# Função para calcular o aumento, ou a diminuição, percentual do valor da variável especificada, entre o primeiro e último
# trimestre registrados.
statsBetweenFirstAndLastQuarters <- function(col, data) {
# Capturando os valores da coluna especificada, com o registro da data mais antiga, e da mais recente.
minDate <- data[data$date == min(data$date), col]
maxDate <- data[data$date == max(data$date), col]
# Calculando o valor do ganho percentual, e a diferença entre os valores registrados.
data.frame(
percentIncrease = (maxDate - minDate) / minDate * 100, # Define o valor percentual.
amp = maxDate - minDate # Define a amplitude entre os valores registrados.
)
}
# Função para calcular o aumento, ou a diminuição, percentual do valor da variável especificada, entre o primeiro e último
# trimestre de cada ano registrado.
statsBetweenFirstAndLastQuartersToYear <- function(col, data) {
# Capturando os valores da coluna especificada, com o registro da data mais antiga, e da mais recente, para cada ano.
dt <- data %>%
select_at(c('year', 'month', col)) %>%
group_by(year) %>%
filter(month == 'March' | month == 'December')
# Criando dataframe para armazenar as estatísticas.
result <- data.frame()
# Extraindo os anos limite, presentes no conjunto de dados.
years <- unique(year(data$date))
# Aplica o cálculo das estatísticas, para cada um dos anos presentes no dataset.
for (y in years){
# Extraí os dados do ano especificado.
firstQuarter <- dt[dt$year == y & dt$month == 'March', col]
lastQuarter <- dt[dt$year == y & dt$month == 'December', col]
# Calcula as estatísticas, e armazena os resultados, no dataframe.
result <- rbind(
result,
data.frame(
# Define o valor percentual.
percentIncrease = (lastQuarter - firstQuarter) / firstQuarter * 100,
# Define a amplitude entre os valores registrados.
amp = lastQuarter - firstQuarter,
row.names = as.character(y)
)
)
}
# Retorna os resultados obtidos pelo cálculo das estatísticas.
result
}
# Função para calcular o aumento, ou a diminuição, percentual dos trimestres, em relação aos anos.
statsBetweenQuartersPerYear <- function(col, data) {
# Criando dataframe para armazenar as estatísticas.
result <- data.frame()
# Define o nome, e a sequência, com a qual os meses serão analisados.
for(m in unique(months(data$date))) {
# Capturando os valores, da coluna especificada, e o mês, a ser analisado.
dt <- data %>%
select_at(c('year', 'month', col)) %>%
group_by(year) %>%
filter(month == m)
# Criando um dataframe, para armazenar as estatísticas geradas, para o mês em análise.
rows <- data.frame()
# Define um loop, para percorrer cada linha do dataframe.
for(l in 2:nrow(dt)) {
# Extraí os dados, do ano do registro selecionado, e do registro anterior.
firstYear <- dt[dt$year == dt$year[l - 1], col]
lastYear <- dt[dt$year == dt$year[l], col]
# Calcula as estatísticas, e armazena os resultados no dataframe.
rows <- rbind(
rows,
data.frame(
# Define o valor percentual.
percentIncrease = (lastYear - firstYear) / firstYear * 100,
row.names = paste(as.character(dt$year[l]), ' - ', as.character(dt$year[l - 1]), sep = '')
)
)
}
# Identifica o mês, ao qual, as estatíscas pertecencem.
colnames(rows) <- paste('pInc', unique(dt$month), sep = '_')
# Atribui os resultados gerados, ao dataframe de resultados.
if(ncol(result) == 0) {
# Caso o dataframe esteja vazio, o preenchemos com os resultados computados, para o primeiro mês analisado.
result <- rows
} else {
# Caso o dataframe não esteja vazio, adiconamos a coluna com as novas estatísticas, ao dataframe.
result <- cbind(result, rows)
}
}
# Retorna os resultados gerados.
result
}
Muitos dos testes estatísticos, incluindo correlação, regressão, teste t e análise de variância (ANOVA), assumem certas características sobre os dados. Eles exigem que os dados sigam uma distribuição normal ou distribuição gaussiana. Esses testes são chamados de testes paramétricos, porque sua validade depende da distribuição dos dados.
Antes de usar um teste paramétrico, devemos executar alguns testes preliminares para garantir que as premissas do teste sejam atendidas. Nas situações em que as suposições são violadas, recomenda-se a realização de testes não paramatricos.
É possível usar um teste de significância comparando a distribuição da amostra com a normal, a fim de verificar se os dados mostram ou não um desvio grave da normalidade.
Existem vários métodos para o teste de normalidade, como o teste de normalidade Kolmogorov-Smirnov (KS) e o teste de Shapiro-Wilk.
O método de Shapiro-Wilk é amplamente recomendado para teste de normalidade e fornece melhor potência que o KS. É baseado na correlação entre os dados e as pontuações normais correspondentes, e é ele que utilizaremos em nossas análises.
As hipóteses deste teste são:
Teste de hipótese |
---|
H0: A amostra provêm de uma população normal. |
Ha: A amostra não provêm de uma população normal. |
# Definindo uma função, para avaliar a normalidade, das variáveis numéricas do dataset.
normalityTest <- function(data, sig = 0.05) {
# Determinando quais variáveis do dataset são do tipo numérico.
numVars <- sapply(data, is.numeric)
# Aplicando o teste de Shapiro-Wilks, a cada uma das variáveis numéricas.
shapiroTest <- sapply(data[numVars], shapiro.test)['p.value', ]
# Transpondo dados.
normTest <- t(data.frame(shapiroTest))
# Atribuindo o nome da coluna com os p-values.
colnames(normTest) <- 'pValue'
# Criando uma variável, para determinar se o p-value é menor do que o nível de significância especificado
# (por padrão, o nível de significância é de 5%).
thereIsEvidenceOfNormality <- sapply(normTest, function(pvalue) { ifelse(pvalue > sig, TRUE, FALSE) })
# Convertendo variáveis para um dataframe.
normTest <- data.frame(normTest)
# Retornando um dataframe com os resultados obtidos.
cbind(normTest, thereIsEvidenceOfNormality)
}
O teste de Bartlett é usado para testar a homogeneidade das variâncias em k amostras, onde k pode ser maior que dois. É adaptado para dados normalmente distribuídos. O teste de Levene, é uma alternativa mais robusta ao teste de Bartlett quando as distribuições dos dados não são normais.
As hipóteses deste teste são:
Teste de hipótese |
---|
H0: As variâncias entre os grupos é homogênea. |
Ha: As variâncias entre os grupos não é homogênea. |
Para saber mais sobre testes estatísticos para comparar variâncias, consulte este link.
# Definindo uma função, para avaliar a homogeneidade das variâncias dos subgrupos categorizados,
# das variáveis numéricas do dataset.
normVarTest <- function(categ, data, sig = 0.05) {
# Determinando quais variáveis do dataset, são do tipo numérico.
numVars <- sapply(data, is.numeric)
# Determinando a posição da variável target, dentro do dataset.
isTarget <- sapply(colnames(data), function(n){n == categ})
# Capturando variáveis que serão utilizadas no teste.
data <- data[numVars | isTarget]
# Definindo os nomes das variáveis target.
target <- colnames(data)
# Elimina o nome da varíavel categórica da lista.
target <- target[target != categ]
# Aplica o teste de Levene, com as variáveis numérica e categórica especificadas.
result <- sapply(target, function(t) {
leveneTest(formula(paste(t, '~', categ)), data = data)[1, 'Pr(>F)']
})
# Transpondo dados.
normTest <- data.frame(result)
# Atribuindo o nome da coluna com os p-values.
colnames(normTest) <- 'pValue'
# Criando uma variável, para determinar se o p-value é menor do que o nível de significância especificado
# (por padrão, o nível de significância é de 5%).
thereIsEvidenceOfNormVar <- sapply(normTest, function(pvalue) { ifelse(pvalue > sig, TRUE, FALSE) })
# Renomeando o nome da variável especificada.
colnames(thereIsEvidenceOfNormVar) <- 'thereIsEvidenceOfNormVar'
# Convertendo as variáveis para um dataframe.
normTest <- data.frame(normTest)
# Retornando um dataframe com os resultados obtidos.
cbind(normTest, thereIsEvidenceOfNormVar)
}
A análise de variância One-Way (ANOVA), também conhecido como one-factor ANOVA, é uma extensão do teste t para duas amostras independentes, e visa comparar a média em uma situação em que há mais do que dois grupos. Na ANOVA One-Way, os dados são organizados em vários grupos, com base em uma única variável de agrupamento (também chamada de variável fator).
Observe que, se você tiver apenas dois grupos, poderá usar o teste t. Nesse caso, o teste F e o teste t são equivalentes.
O teste ANOVA só pode ser aplicado quando:
As observações são obtidas de forma independente e aleatória a partir da população definida pelos níveis de fator;
Os dados de cada nível de fator são normalmente distribuídos;
Essas populações normais têm uma variância comum (O teste de Levene pode ser usado para verificar isso) e;
Os dados devem ser contínuos.
As hipóteses deste teste são:
Teste de hipótese |
---|
H0: As médias dos grupos são iguais. |
Ha: As médias dos grupos não são iguais. |
Para saber mais sobre testes estatísticos para comparar variâncias, consulte este link.
# Definindo uma função, para aplicar a análise de variância nos subgrupos categorizados, das variáveis numéricas do dataset.
anovaTest <- function(categ, parametricVars, data, sig = 0.05) {
# Aplicando o teste Anova, com as variáveis numérica e categórica especificadas.
result <- sapply(parametricVars, function(t) {
anovaModel <- lm(formula(paste(t, '~', categ)), data = data)
anova(anovaModel)[categ, 'Pr(>F)']
})
# Transpondo dados.
anovaTest <- data.frame(result)
# Atribuindo o nome da coluna com os p-values.
colnames(anovaTest) <- 'pValue'
# Criando uma variável, para determinar se o p-value é menor do que o nível de significância especificado
# (por padrão, o nível de significância é de 5%).
thereIsEvidenceForEqualsMeans <- sapply(anovaTest, function(pvalue) { ifelse(pvalue > sig, TRUE, FALSE) })
# Renomeando o nome da variável especificada.
colnames(thereIsEvidenceForEqualsMeans) <- 'thereIsEvidenceForEqualsMeans'
# Convertendo variáveis para um dataframe.
anovaTest <- data.frame(anovaTest)
# Retornando um dataframe com os resultados obtidos.
cbind(anovaTest, thereIsEvidenceForEqualsMeans)
}
O teste de Kruskal-Wallis por classificação é uma alternativa não-paramétrica ao teste ANOVA One-Way, que estende o teste de Wilcoxon de duas amostras na situação em que existem mais de dois grupos. É recomendado quando as suposições do teste ANOVA One-Way não são atendidas.
As hipóteses deste teste são:
Teste de hipótese |
---|
H0: As médias dos grupos são iguais. |
Ha: As médias dos grupos não são iguais. |
Para saber mais sobre testes estatísticos para comparar variâncias, consulte este link.
# Definindo uma função, para aplicar a análise de variância nos subgrupos categorizados, das variáveis numéricas não
# paramétricas do dataset.
kruskalTest <- function(categ, nonParametricVars, data, sig = 0.05) {
# Aplicando o teste de Kruskal-Wallis, com as variáveis numérica e categórica especificadas.
result <- sapply(nonParametricVars, function(t) {
kruskal.test(formula(paste(t, '~', categ)), data = data)$p.value
})
# Transpondo dados.
krTest <- data.frame(result)
# Atribuindo o nome da coluna com os p-values.
colnames(krTest) <- 'pValue'
# Criando um variável, para determinar se o p-value é menor do que o nível de significância especificado
# (por padrão, o nível de significância é de 5%).
thereIsEvidenceForEqualsMeans <- sapply(krTest, function(pvalue) { ifelse(pvalue > sig, TRUE, FALSE) })
# Renomeando o nome da variável especificada.
colnames(thereIsEvidenceForEqualsMeans) <- 'thereIsEvidenceForEqualsMeans'
# Convertendo variáveis para um dataframe.
krTest <- data.frame(krTest)
# Retornando um dataframe com os resultados obtidos.
cbind(krTest, thereIsEvidenceForEqualsMeans)
}
Nesta etapa, buscaremos entender a disposição e as características das nossas variáveis, além de extrair insigths para enriquecer nossa análise.
Após todas as alterações que fizemos, a configuração das variavéis no dataset passou a ser a seguinte:
Variável | Tipo | Descrição |
---|---|---|
date | Date | É a data de emissão do resultado trimestral; |
totalSubscriptions | integer | É o número total de assinaturas registradas no final do trimestre; |
paidSubscriptions | integer | É o número de assinaturas pagas registradas no final do trimestre; |
freeTrails | integer | É o número de assinaturas em período de utilização gratuita registradas no final do trimestre; |
revenue | Double | É a receita trimestral gerada para o Streaming doméstico (em milhares de dólares); |
costOfRevenues | Double | É o custo trimestral da receita gerada para o Streaming doméstico (em milhares de dólares); |
marketing | Double | É o custo trimestral de Marketing gerado para o Streaming doméstico (em milhares de dólares); |
contributionProfit | Double | É o lucro da contribuição trimestral (em milhares de dólares); |
contributionMargin | Double | É a margem de contribuição trimestral (contributionProfit / revenue); |
costPerCustomer | Double | É a taxa de custo por cliente desconsiderando os gastos com Marketing (costOfRevenues / totalSubscriptions); |
revenuePerCustomer | Double | É a taxa de receita por cliente (revenue / totalSubscriptions); |
earningsPerCustomer | Double | É a taxa de lucro por cliente ((revenue - costOfRevenues) / totalSubscriptions); |
segment | Factor | É o segmento de operação da companhia ao qual os dados se referem; |
month | Factor | É o mês de emissão do resultado trimestral; |
year | Factor | É o ano de emissão do resultado trimestral; |
freeTrialsFromTotal | Double | É a proporção de avaliações gratuitas do total de assinaturas (freeTrails / totalSubscriptions * 100) e; |
marketingFromTotal | Double | É a proporção de custo com marketing em relação ao custo total (marketing / (costOfRevenues + marketing) * 100). |
Podemos verificar as informações desta tabela, com o auxílio da função glimpse.
# Verificando os tipos das colunas carregadas do dataset.
glimpse(data)
Verificamos a existência de 17 variáveis e 28 observações dentro do dataset.
Nesta etapa, iremos analisar as informações que conseguimos extrair de cada variável do dataset individualmente.
Bom, vamos começar verificando a data da primeira e da última observação registrada.
# Verificando a data da primeira observação registrada.
min(data$date)
# Verificando a data da última observação registrada.
max(data$date)
Como esperávamos, o intervalo de tempo se inicia no fim do primeiro trimestre de 2012, e finda no último trimestre de 2018.
Avaliaremos os dias que estão associados a cada observação.
# Contabilizando os dias em que cada registro foi emitido.
table(day(data$date))
Vemos que as informações trimestrais, sempre são emitidas no último dia do mês (no dia 30 ou 31).
Nosso próximo passo, é garantir que temos os dados, de cada um dos trimestres dentro deste intervalo de tempo.
# Contabilizando o número de registros por ano.
table(year(data$date))
Para cada ano temos 4 registros, um para cada trimestre.
# Contabilizando o número de registros por mês.
table(months(data$date))
Para cada um dos meses trimestrais temos 7 registros, um para cada ano.
# Contabilizando o número de registros por ano e por mês.
data %>%
group_by(year(date), months(date)) %>%
nrow()
Contabilizamos que, cada um dos 7 anos presentes no dataset, apresenta informações de cada um dos seus 4 meses trimestrais, totalizando 28 registros distintos.
Portanto, possuímos informações dos 4 trimestres entre os anos de 2012 a 2018.
# Definindo o nome da variável a ser analisada.
col <- 'totalSubscriptions'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro do total de assinaturas que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à esquerda para o conjunto de dados, ou seja, os valores inferiores à mediana variam mais do que os superiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'paidSubscriptions'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro do total de assinaturas pagas que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à esquerda para o conjunto de dados, ou seja, os valores inferiores à mediana variam mais do que os superiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
Observação: As estatísticas das variáveis totalSubscriptions e paidSubscriptions são muito semelhantes. Isto pode se dar ao fato de uma ser um subconjunto da outra, visto que para pagar a assinatura o cliente deve ser um assinante. Pode ser interessante verificar, se as diferenças entre estas variáveis são estatisticamente significativas, e faremos isso nas próximas etapas.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrails'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, há um registro do número de assinantes em período de utilização gratuita discrepante dentro do conjunto de dados. Vemos que o outlier está localizado no limite superior do gráfico, ou seja, há um registro em que o aumento das assinaturas em período de utilização experimental fugiu do padrão, indicando que nesta época o número de clientes interessados em conhecer os serviços da Netflix aumentou consideravelmente.
Vamos identificar qual é este registro!
# Extraindo registros, em que o valor da variável especificada, tenha sido considerado um outlier.
getOutliers(col = col, data = data)
Interessante! O quarto trimestre de 2018 apresentou o valor destoante, e pode estar indicando que o número de assinantes em período de utilização gratuita, pode vir a crescer significativamente no próximo ano.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'revenue'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro de receita que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'costOfRevenues'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro do custo de receita que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'marketing'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, há registros sobre o gasto com marketing discrepantes dentro do conjunto de dados. Os outliers estão localizados no limite superior do gráfico, ou seja, há registros em que o custo com marketing fugiu do padrão, indicando que nestas épocas as despesas aumentaram consideravelmente.
Vamos identificar quais são estes registros.
# Extraindo registros, em que o valor da variável especificada, tenha sido considerado um outlier.
getOutliers(col = col, data = data)
Constatamos que a partir do último trimestre de 2017, os gastos com marketing aumentaram consideravelmente, em relação aos demais trimestres observados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'contributionProfit'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro do lucro da contribuição trimestral que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'contributionMargin'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro da margem de contribuição trimestral que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à esquerda para o conjunto de dados, ou seja, os valores inferiores à mediana variam mais do que os superiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'costPerCustomer'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro da taxa de custo por cliente que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'revenuePerCustomer'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro da taxa de receita por cliente que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'earningsPerCustomer'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, não há registro da taxa de ganhos por cliente que seja discrepante dentro do conjunto de dados.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'segment'
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Detectamos que não há variação alguma entre os valores da variável segment, ou seja, só há uma classe associada a todos os registro do dataset.
Ao analisarmos a documentação, observamos que a Netflix opera em três segmentos: International Streaming, Domestic Streaming e Domestic DVD. A categoria na qual os dados estão classificados é denomidada Streaming, e ao compará-los com os dados fornecidos pela Netflix Investor, identificamos que o segmento do qual as informações foram extraídas foi o doméstico.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrialsFromTotal'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, há registros sobre a proporção de avaliações gratuitas do total de assinaturas discrepantes dentro do conjunto de dados. Os outliers estão localizados no limite superior do gráfico, ou seja, há registros em que a proporção fugiu do padrão, indicando que nestas épocas as avaliações em período experimental aumentaram consideravelmente.
Vamos identificar quais são estes registros!
# Extraindo registros em que o valor da variável especificada tenha sido considerado um outlier.
getOutliers(col = col, data = data)
Interessante! Pelas análises que fizemos até aqui, não há nenhuma explicação para que o primeiro e quarto trimestres de 2012 apresentem tais valores discrepantes. Mas, certamente deve haver um motivo para isso, não é mesmo?
Quando pesquisamos sobre o que ocorreu com a Netflix em 2012, constatamos que neste ano a empresa passou a assumir um papel ativo como produtora, e distribuidora de filmes e séries de televisão, e para esse fim, passou a oferecer uma variedade de conteúdo Original por meio de sua biblioteca on-line.
Dito isto, podemos supor que uma explicação plausível, para estas proporções de avaliações gratuitas em relação ao total de assinaturas registradas terem apresentado valores discrepantes, pode ter sido causada pela mudança do paradigma operacional, que a empresa adotou quando passou a criar produtos autorais.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
# Definindo o nome da variável a ser analisada.
col <- 'marketingFromTotal'
# Criando um gráfico Boxplot para a variável especificada.
boxPlot(col = col, data = data)
O boxplot nos indica que, há registros sobre a proporção de custo com marketing em relação ao total de custos discrepantes dentro do conjunto de dados. Vemos que os outliers estão localizados no limite superior do gráfico, ou seja, há registros em que a proporção fugiu do padrão indicando que nestas épocas as proporções de gastos com marketing foram consideravelmente mais altas.
Vamos identificar quais são estes registros.
# Extraindo registros em que o valor da variável especificada tenha sido considerado um outlier.
getOutliers(col = col, data = data)
Verificamos que a partir do primeiro trimestre de 2018, a proporção de gastos com marketing passou a fugir do padrão, o que pode estar indicando uma nova tendência para estas despesas nos próximos anos.
# Criando um gráfico de Densidade para a variável especificada.
densityPlot(col = col, data = data)
O gráfico de densidade evidência uma assimetria à direita para o conjunto de dados, ou seja, os valores superiores à mediana variam mais do que os inferiores.
# Calculando algumas estatísticas para a variável especificada.
varStats(col, data = data)
Destacamos que:
Nesta etapa, iremos analisar as informações que conseguimos extrair de cada variável agrupada por trimestre e ano.
# Definindo o nome da variável a ser analisada.
col <- 'totalSubscriptions'
# Criando um gráfico de barras para a variável especificada.
barPlot(col = col, data = data)
Parece haver um crescimento aproximadamente linear do total de assinantes entre cada um dos trimestres de 2012 a 2018.
Vamos verificar de quanto foi o aumento, do número total de indivíduos cadastrados, entre o primeiro e o último trimestres analisados.
# Calculando a diferença absoluta, e percentual dos valores da variável especificada, entre o primeiro e último trimestre
# analisados.
statsBetweenFirstAndLastQuarters(col = col, data = data)
Constatamos que o crescimento total entre 2012 e 2018 foi de 35.076 assinantes, o que corresponde a um aumento de aproximadamente 150%.
Iremos repetir este mesmo processo, mas agora, para avaliar o aumento do número total de indivíduos cadastrados entre o primeiro e o último trimestre de cada ano.
# Calculando a diferença absoluta e percentual, dos valores da variável especificada, entre o primeiro e último trimestre
# de cada ano analisado.
statsBetweenFirstAndLastQuartersToYear(col = col, data = data)
Concluímos que 2012 e 2013 foram os anos que apresentaram o maior aumento no número total de assinantes, e isto pode estar associado com o empenho da empresa em expandir seu mercado streaming. Os anos subsequentes apresentam uma queda nesta porcentagem, com destaque para o ano de 2016, que apresentou a pior taxa de crescimento registrada entre os anos analisados.
Ao buscar possíveis motivos para os resultados obtidos em 2016, vemos na timeline dos acontecimentos da empresa, o surgimento de acusações sobre sua conduta acerca da neutralidade na rede. Podemos supor, que o desgaste gerado a imagem da organização com estes debates, contribuiu para o baixo crescimento no ano.
Vamos avaliar, o aumento do número total de indivíduos cadastrados, entre os trimestres dos anos.
# Calculando a diferença percentual, dos valores da variável especificada, entre os trimestres dos anos.
statsBetweenQuartersPerYear(col = col, data = data)
Bom, observamos que as menores porcentagens de crescimento dos trimestres ao longo dos anos, estão entre os anos de 2015 e 2017.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a quantidade total de assinantes aumenta a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para o número total de assinantes, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'paidSubscriptions'
# Criando um gráfico de barras para a variável especificada.
barPlot(col = col, data = data)
Torna-se evidente que a variável paidSubscriptions, representa um subconjunto da variável totalSubscriptions quando comparamos seus gráficos de barras trimestrais. Sua tendência de crescimento, parece seguir a da variável totalSubscriptions.
# Calculando a diferença absoluta, e percentual dos valores da variável especificada, entre o primeiro e último trimestre
# analisados.
statsBetweenFirstAndLastQuarters(col = col, data = data)
Constatamos que o crescimento total entre 2012 e 2018 foi de 34.399 assinaturas pagas, o que corresponde a um aumento de aproximadamente 156.2%.
Iremos repetir este mesmo processo, mas agora, para avaliar o aumento do número total de indivíduos cadastrados entre o primeiro e o último trimestre de cada ano.
# Calculando a diferença absoluta e percentual, dos valores da variável especificada, entre o primeiro e último trimestre
# de cada ano analisado.
statsBetweenFirstAndLastQuartersToYear(col = col, data = data)
Concluímos que 2012 e 2013 foram os anos que apresentaram o maior aumento em assinaturas pagas, e isto pode estar associada com o empenho da empresa em expandir seu mercado streaming. Os anos subsequentes, apresentam uma queda nesta porcentagem, com destaque para o ano de 2018, que apresentou a pior taxa de crescimento registrada entre os anos analisados.
# Calculando a diferença percentual, dos valores da variável especificada, entre os trimestres dos anos.
statsBetweenQuartersPerYear(col = col, data = data)
Bom, observamos que as menores porcentagens de crescimento dos trimestres ao longo dos anos, estão entre os anos de 2015 e 2017.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a quantidade total de assinaturas pagas aumenta a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver uma diferença significativa, para o número de assinaturas pagas, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrails'
# Criando um gráfico de barras para a variável especificada.
barPlot(col = col, data = data)
O gráfico nos mostra, que o último trimestre de cada ano analisado, foi o que apresentou o maior número de assinantes em período de utilização gratuita. Essa tendência parece se propagar, na maior parte dos casos, para o primeiro trimestre do ano seguinte. O segundo e o terceiro trimestre, são aqueles que predominantemente apresentam os menores números de assinantes.
Vamos garantir que nossos olhos não estão nos enganando, e que o último trimestre de cada ano realmente apresenta o maior valor para esta variável.
# Capturando o trimestre que apresentou o maior valor para a variável especificada em cada ano.
data %>%
select(year, month, freeTrails) %>%
group_by(year) %>%
filter(freeTrails == max(freeTrails))
Excelente! Para cada um dos anos analisados, o último trimestre sempre apresentou o maior número de assinantes em período de utilização gratuita.
Muito bem, agora iremos verificar o trimestre que apresentou o menor número de cadastros em período experimental em cada ano.
# Capturando o trimestre que apresentou o menor valor para a variável especificada em cada ano.
dt <- data %>%
select(year, month, freeTrails) %>%
group_by(year) %>%
filter(freeTrails == min(freeTrails))
# Visualizando o resultado.
dt
Contar o número de vezes que cada mês aparece dentro desta tabela, também parece interessante!
# Calculando a frequência absoluta e relativa, para a número de ocorrências de cada trimestre observado.
dt[, 'month'] %>%
group_by(month) %>%
summarise (
freq = n(),
percentage = n() / nrow(dt) * 100
) %>%
arrange(desc(freq))
Vemos que o terceiro trimestre do ano, é o que apresenta o menor número de assinantes no período experimental, em 57.14% dos casos observados, o segundo trimestre em 28.57%, e o primeiro trimestre em 14.29%.
Para finalizar, criaremos um gráfico de boxplot que agrupa os valores da variável freeTrails pelo ano ao qual pertence.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Veja só, de 2012 até 2015 observamos um tendência de queda, e a partir de 2016 vemos um tendência de crescimento, que se destaca ainda mais a partir de 2017. Em 2013, o valor do quarto trimestre foi tão alto a ponto de ser representado como um outlier.
Uma estratégia interessante, que a Netflix poderia adotar para aumentar o número e a fidelização dos clientes que experimentam sua plataforma, seria a de focar no quarto trimestre do ano; diminuindo os preços dos seus serviços, aumentando seu marketing e o período de acesso gratuito, além de usar este trimestre para realizar o lançamento de novos conteúdos.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece haver uma diferença significativa, para o número de assinaturas em período de utilização gratuita, entre os trimestres dos anos. O primeiro e o quarto trimestre, são aqueles que apresentam os maiores valores.
# Definindo o nome da variável a ser analisada.
col <- 'revenue'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente linear, da receita trimestral gerada entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a receita gerada aumenta a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para a receita gerada, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'costOfRevenues'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente linear, do custo trimestral da receita gerada entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, o custo da receita gerada aumenta a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para o custo da receita gerada, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'marketing'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente exponencial, do custo de marketing entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, o custo de marketing aumenta expencialmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença mediana significativa, para o custo de marketing, entre os trimestres dos anos. Também notamos uma alta variância no terceiro e quarto trimestre.
# Definindo o nome da variável a ser analisada.
col <- 'contributionProfit'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente linear, do lucro da contribuição entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, o lucro da contribuição aumenta linearmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para o lucro da contribuição, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'contributionMargin'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente logístico, da margem de contribuição entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a margem de contribuição aumenta logisticamente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para a margem de contribuição, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'costPerCustomer'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente exponencial, do custo por cliente entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, o custo por cliente aumenta exponencialmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece haver uma diferença significativa, para o custo por cliente, entre os trimestres dos anos. O primeiro trimestre, apresenta um valor mediano menor do que os demais.
# Definindo o nome da variável a ser analisada.
col <- 'revenuePerCustomer'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente exponencial, da taxa de receita por cliente entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a taxa de receita por cliente aumenta exponencialmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para a taxa de receita por cliente, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'earningsPerCustomer'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente linear, da taxa de lucro por cliente entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a taxa de lucro por cliente aumenta linearmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para a taxa de lucro por cliente, entre os trimestres dos anos.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrialsFromTotal'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um decrescimento aproximadamente exponecial, da proporção de avaliações gratuitas do total de assinaturas entre os anos em análise.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'year')
Como vimos anteriormente, a proporção de avaliações gratuitas do total de assinaturas diminui exponecialmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece haver uma diferença significativa, para a proporção de avaliações gratuitas do total de assinaturas, entre os trimestres dos anos. O terceiro trimestre, apresenta um valor mediano menor do que os demais.
# Definindo o nome da variável a ser analisada.
col <- 'marketingFromTotal'
# Criando um gráfico de série temporal para a variável especificada.
timeSeriesPlot(col = col, data = data)
A série temporal demonstra, um crescimento aproximadamente exponencial, da proporção de custo com marketing em relação ao custo total entre os anos em análise.
# Criando um gráfico Boxplot que agrupe a variável especificada pelo ano ao qual seu registro está associada.
boxPlot(col = col, data = data %>% select_at(c('year', col)), categ = 'year')
Como vimos anteriormente, a proporção de custo com marketing em relação ao custo total aumenta exponencialmente a cada ano.
# Criando um gráfico Boxplot, que agrupe a variável especificada, pelo trimestre ao qual seu registro está associada.
boxPlot(col = col, data = data, categ = 'month')
Parece não haver um diferença significativa, para a proporção de custo com marketing em relação ao custo total, entre os trimestres dos anos.
Para aplicarmos o teste Anova One-Way, os 4 requisitos a seguir devem ser cumpridos:
As observações são obtidas de forma independente e aleatória a partir da população definida pelos níveis de fator;
Os dados de cada nível de fator são normalmente distribuídos;
Essas populações normais têm uma variância comum e;
Os dados devem ser contínuos.
As variáveis que passarem com êxito por as etapas, serão classificadas como variáveis paramétricas, e poderão ser analisadas pelo teste ANOVA One-Way.
As variáveis que descumprirem algum destes pontos, serão classificadas como variáveis não paramétricas, e poderão ser analisadas pelo teste de Kruskal-Wallis.
# Aplicando o teste de Shapiro-Wilks, para avaliar a normalidade das variáveis.
nmT <- normalityTest(data)
# Verificando quais variáveis são continuas.
isContinuous <- !sapply(data, is.integer)
Iremos utilizar o ano, para categorizar as variáveis que serão analisadas.
# Definindo a variável categórica que será utilizada nos testes.
categ <- 'year'
# Aplicando o teste de Levene, para verificar se a variância entre os grupos é homogênea.
nmVarT <- normVarTest(categ = categ, data)
# Determinando quais variáveis são paramétricas.
varsForParametricTests <- rownames(nmT)[nmT$thereIsEvidenceOfNormality & nmVarT$thereIsEvidenceOfNormVar]
# Determinando quais variáveis são não paramétricas.
varsForNonParametricTests <- rownames(nmT)[!(nmT$thereIsEvidenceOfNormality & nmVarT$thereIsEvidenceOfNormVar)]
# Determinando quais variáveis são contínuas.
continuousCols <- varsForParametricTests %in% colnames(data[isContinuous])
# Definindo variáveis que devem passar por testes não paramétricos.
varsForNonParametricTests <- append(varsForNonParametricTests, varsForParametricTests[!continuousCols])
# Definindo variáveis que devem passar por testes paramétricos.
varsForParametricTests <- varsForParametricTests[continuousCols]
# Aplicando o teste ANOVA One-Way, para as variáveis paramétricas, segundo a variável categórica especificada.
anovaTest(categ = categ, parametricVars = varsForParametricTests, data = data)
Concluímos que, há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que as médias das variáveis revenue, costOfRevenues e ContributionProfit sejam iguais entre os anos.
# Aplicando o teste de Kruskal-Wallis, para as variáveis não paramétricas, segundo a variável categórica especificada.
kruskalTest(categ = categ, nonParametricVars = varsForNonParametricTests, data = data)
Concluímos que, há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que as médias das variáveis marketing, contributionMargin, contributionMargin, costPerCustomer, revenuePerCustomer, earningsPerCustomer, freeTrialsFromTotal, marketingFromTotal, totalSubscriptions, paidSubscriptions e freeTrails sejam iguais entre os anos.
Também podemos categorizar as variáveis que estamos analisando por mês.
# Definindo a variável categórica que será utilizada nos testes.
categ <- 'month'
# Aplicando o teste de Levene, para verificar se a variância entre os grupos é homogênea.
nmVarT <- normVarTest(categ = categ, data)
# Determinando quais variáveis são paramétricas.
varsForParametricTests <- rownames(nmT)[nmT$thereIsEvidenceOfNormality & nmVarT$thereIsEvidenceOfNormVar]
# Determinando quais variáveis são não paramétricas.
varsForNonParametricTests <- rownames(nmT)[!(nmT$thereIsEvidenceOfNormality & nmVarT$thereIsEvidenceOfNormVar)]
# Determinando quais variáveis são contínuas.
continuousCols <- varsForParametricTests %in% colnames(data[isContinuous])
# Definindo variáveis que devem passar por testes não paramétricos.
varsForNonParametricTests <- append(varsForNonParametricTests, varsForParametricTests[!continuousCols])
# Definindo variáveis que devem passar por testes paramétricos.
varsForParametricTests <- varsForParametricTests[continuousCols]
# Aplicando o teste ANOVA One-Way, para as variáveis paramétricas, segundo a variável categórica especificada.
anovaTest(categ = categ, parametricVars = varsForParametricTests, data = data)
Concluímos que, não há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que as médias das variáveis revenue, costOfRevenues e ContributionProfit sejam iguais entre os trimestres.
# Aplicando o teste de Kruskal-Wallis, para as variáveis não paramétricas, segundo a variável categórica especificada.
kruskalTest(categ = categ, nonParametricVars = varsForNonParametricTests, data = data)
Concluímos que, não há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que as médias das variáveis marketing, contributionMargin, contributionMargin, costPerCustomer, revenuePerCustomer, earningsPerCustomer, freeTrialsFromTotal, marketingFromTotal, totalSubscriptions e paidSubscriptions sejam iguais entre os trimestres.
Há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que a média da variável freeTrails seja igual entre os trimestres.
Nesta etapa desejamos verificar como as variáveis se correlacionam, ou seja, como uma variável ajuda a prever o valor de outra variável no dataset.
# Determinando quais variáveis do dataset são do tipo numérico.
numVars <- sapply(data, is.numeric)
# Criando um pair plot para visualizar as correlações entre as variáveis númericas.
ggpairs(data[numVars]) + theme_bw() + theme(axis.text.x = element_text(angle = 45, vjust = 1))
Algo interessante de se notar neste gráfico, é a alta correlação existente entre praticamente todas as variáveis do dataset.
Vamos investigar mais detalhadamente a força e a direção dessas correlações.
# Verificando a correlação entre as variáveis do dataset.
corrplot(cor(data[numVars]),
method = 'color',
addCoef.col = 'white',
type = 'upper',
tl.col = 'black',
diag = F
)
Como suspeitávamos, há correlações praticamente perfeitas entre quase todas as variáveis do conjunto de dados. Ou seja, boa parte das variáveis carregam, praticamente, as mesmas informações que as outras.
Destacamos a correlação entre as variáveis totalSubscriptions e paidSubscriptions, que é perfeitamente positiva (correlação igual a 1).
Nesta etapa, iremos analisar as variáveis do dataset como séries temporais.
Em estatística e econometria, o Teste de Dickey-Fuller aumentado ou Teste ADF (do acrônimo em inglês Augmented Dickey-Fuller) é um teste de raiz unitária em séries temporais. Ele é uma versão aumentada do Teste de Dickey-Fuller, é aplicado a modelos mais complicados de séries temporais.
A estatística ADF, usada no teste, é um número negativo, e quanto mais negativo, mais indicativo o teste se torna de rejeitar a hipótese nula de que existe raiz unitária na série.
O nome do teste faz referência aos estatísticos D. A. Dickey e W. A. Fuller.
As hipóteses deste teste são:
Teste de hipótese |
---|
H0: A série é não é estácionária. |
Ha: A série é estacionária. |
Para saber mais sobre testes estatísticos para comparar variâncias, consulte este link.
# Definindo uma função, para aplicar o teste ADF, as séries temporais do dataset.
adfTest <- function(data, freq = 4, sig = 0.05) {
# Aplicando o teste ADF a cada variável do dataset.
result <- sapply(data, function(t) {
# Convertendo a variável especificada em uma série temporal.
t <- ts(t, frequency = freq)
# Aplicando o teste ADF, e capturando o p-value gerado.
adf.test(t, alternative = "stationary")$p.value
})
# Transpondo dados.
dfTest <- data.frame(result)
# Atribuindo o nome da coluna com os p-values.
colnames(dfTest) <- 'pValue'
# Criando um variável, para determinar se o p-value é menor do que o nível de significância especificado
# (por padrão, o nível de significância é de 5%).
isStationary <- sapply(dfTest, function(pvalue) { ifelse(pvalue < sig, TRUE, FALSE) })
# Renomeando o nome da variável especificada.
colnames(isStationary) <- 'isStationary'
# Convertendo variáveis para um dataframe.
dfTest <- data.frame(dfTest)
# Retornando um dataframe com os resultados obtidos.
cbind(dfTest, isStationary)
}
# Definindo uma função, para plotar gráficos das compontentes da série temporal especificada.
tsDecomposePlot <- function(col, data, type, freq = 4, color = '#FF4E00') {
# Convertendo a variável especificada em uma série temporal.
t <- ts(data[col], frequency = freq)
# Cria o gráfico da série temporal decomposta.
ggdecompose(dts2(t, type = type)) +
geom_line(color = color, size = 2) +
geom_point(size = 2) +
theme_bw() +
xlab('Year') +
ggtitle(paste("Time series components chart for variable:", col))
}
# Definindo uma função, para plotar um gráfico de série temporal, com as previsões geradas.
plotPredQuarters <- function(col, data, h = 2, freq = 4, colors = c('#06D6A0', '#FF4E00'), size = 2) {
# Convertendo a variável especificada em uma série temporal.
t <- ts(data[, col], frequency = freq)
# Criando um modelo ARIMA.
model <- auto.arima(t)
# Realizando a previsão de h trimestres, segundo o modelo ARIMA criado.
pred <- forecast(model, h = h)
# Criando um gráfico de série temporal, com as previsões geradas para a variável especificada.
autoplot(pred, predict.colour = colors[1], predict.size = size, colour = colors[2], size = size) +
theme_bw() +
xlab('Year') +
ggtitle(paste("Forecasting chart for variable", col, "on the next", toString(h), "quartes"))
}
# Definindo uma função para gerar previsões para séries temporais utilizando o modelo ARIMA.
predQuarters <- function(data, h = 2, freq = 4) {
# Capturando as métricas obtidas, e as previsões geradas, para cada uma das variáveis do dataset.
result <- sapply(colnames(data), function(col){
# Convertendo a variável especificada em uma série temporal.
t <- ts(data[, col], frequency = freq)
# Criando um modelo ARIMA.
model <- auto.arima(t)
# Imprimindo uma mensagem, para identificar a qual variável o modelo pertence.
print(paste('---------------', 'model ARIMA for variable:', col, '---------------'))
# Capturando as métricas do modelo criado, e imprimindo um resumo estatístico.
metrics <- summary(model)
# Realizando a previsão de h trimestres, segundo o modelo ARIMA criado.
pred <- forecast(model, h = h)
# Capturando os valores previstos para os trimestres.
quarters <- data.frame(t(pred$mean))
# Criando um nome para as colunas que vão armazenar os resultados previstos.
colnames(quarters) <- sapply(1:h, function(n){paste('Qtr', toString(n), sep ="") } )
# Criando um Dataframe com métricas, e com os resultados dos trimestres previstos.
cbind(data.frame(metrics), quarters)
})
# Convertendo os resultados gerados para uma matriz de números inteiros.
result <- sapply(as.data.frame(t(result)), as.numeric)
# Convertendo resultados da matriz para um Dataframe.
result <- as.data.frame(result)
# Atribuindo o nome das linhas do Dataframe.
rownames(result) <- colnames(data)
# Retornando os resultados gerados.
result
}
# Eliminando variáveis desnecessárias para a análise.
dt <- data %>% select(-c(date, segment, month, year))
# Aplicando o teste ADF.
adfTest(dt)
Não há evidências estatisticamente significativas, com um nível de significância de 5%, para rejeitar a hipótese nula de que as variáveis listadas acima são não estácionárias.
# Definindo o nome da variável a ser analisada.
col <- 'totalSubscriptions'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável totalSubscriptions, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'paidSubscriptions'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável paidSubscriptions, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrails'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável freeTrails, notamos que o quarto trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'revenue'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável revenue, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'costOfRevenues'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável costOfRevenues, notamos que o terceiro trimestre é o de maior sazonalidade e o primeiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'marketing'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável marketing, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'contributionProfit'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável contributionProfit, notamos que o primeiro trimestre é o de maior sazonalidade e o quarto trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'contributionMargin'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável contributionMargin, notamos que o primeiro trimestre é o de maior sazonalidade e o quarto trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'costPerCustomer'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável costPerCustomer, notamos que o terceiro trimestre é o de maior sazonalidade e o primeiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'revenuePerCustomer'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável revenuePerCustomer, notamos que o terceiro trimestre é o de maior sazonalidade e o quarto trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'earningsPerCustomer'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável earningsPerCustomer, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'freeTrialsFromTotal'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável freeTrialsFromTotal, notamos que o quarto trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
# Definindo o nome da variável a ser analisada.
col <- 'marketingFromTotal'
# Criando um gráfico de cada um dos componentes que constituem a série temporal.
tsDecomposePlot(col, dt, type = 'additive')
Ao analisar o gráfico de sazonalidade da variável marketingFromTotal, notamos que o primeiro trimestre é o de maior sazonalidade e o terceiro trimestre é o de menor sazonalidade.
Nesta etapa, iremos realizar previsões para os 2 próximos trimestres, utilizando o algoritmo ARIMA.
# Definindo como os valores frácionários devem ser exibidos (Sem notação científica).
options(scipen = 999)
# Criando o modelo ARIMA, e realizando as previsões para cada uma das variáveis do dataset.
predModels <- predQuarters(dt)
# Imprimindo dataset com as previsões, e as métricas dos modelos criados, para cada variável.
predModels
Iremos utilizar a métrica RMSE, para avaliar os modelos criados e os valores previstos.
# Determinando a métrica, que deve ser utilizada para avaliar os modelos
metric <- 'RMSE'
# Capturando o índice da coluna com o nome da métrica especificada.
metricCol <- grep(metric, colnames(predModels))
# Capturando os índices das colunas com as letras iniciais Qtr (são colunas com as previsões geradas).
qtrsCols <- grep('Qtr', colnames(predModels))
# Criando uma única lista com os índices capturados.
cols <- append(metricCol, qtrsCols)
# Ordenando as linhas do dataframe, em ordem crescente, segundo os valores da coluna de métricas.
predModelsOrdered <- predModels[order(predModels[, metric]), cols]
# Imprimindo Dataframe ordenado.
predModelsOrdered
Por fim, vamos gerar gráficos, com os valores previstos para os modelos que apresentaram os melhores scores, segundo a métrica selecionada.
# Capturando o nome, dos 5 melhores modelos ARIMA, segundo a métrica especificada.
rownames(predModelsOrdered)[1:5]
# Definindo o nome da variável a ser analisada.
col <- 'contributionMargin'
# Criando um gráfico da série temporal com as previsões geradas.
plotPredQuarters(col, dt)
# Definindo o nome da variável a ser analisada.
col <- 'costPerCustomer'
# Criando um gráfico da série temporal com as previsões geradas.
plotPredQuarters(col, dt)
# Definindo o nome da variável a ser analisada.
col <- 'freeTrialsFromTotal'
# Criando um gráfico da série temporal com as previsões geradas.
plotPredQuarters(col, dt)
# Definindo o nome da variável a ser analisada.
col <- 'earningsPerCustomer'
# Criando um gráfico da série temporal com as previsões geradas.
plotPredQuarters(col, dt)
# Definindo o nome da variável a ser analisada.
col <- 'revenuePerCustomer'
# Criando um gráfico da série temporal com as previsões geradas.
plotPredQuarters(col, dt)
E assim, finalizamos nossa análise estatística sobre os dados financeiros trimestrais da Netflix!
Caso tenha alguma dúvida, sugestão ou apenas queira trocar uma ideia sobre este projeto, não hesite em entrar em contato comigo!