<jupyter_start><jupyter_text>0.0 IMPORTS<jupyter_code>import pandas as pd
import inflection
import math
import numpy as np
import seaborn as sns
import datetime


from matplotlib import pyplot as plt
from IPython.core.display import HTML
from IPython.display import Image<jupyter_output><empty_output><jupyter_text>0.1. Helper Functions<jupyter_code># Função para ampliar area de edição do jupyter notebook
def jupyter_settings():
    %matplotlib inline
    %pylab inline
    
    plt.style.use( 'bmh' )
    plt.rcParams['figure.figsize'] = [25, 12]
    plt.rcParams['font.size'] =24
    
    display( HTML( '<style>.container {width:100% !important; }</style>') )
    pd.options.display.max_columns = None
    pd.options.display.max_rows = None
    pd.set_option( 'display.expand_frame_repr', False )
    
    sns.set()  
jupyter_settings()<jupyter_output>Populating the interactive namespace from numpy and matplotlib<jupyter_text>0.2. Loading data<jupyter_code># leitura dos dados fornecidos
df_sales_raw = pd.read_csv('../data/train.csv', low_memory=False)
df_store_raw = pd.read_csv('../data/store.csv', low_memory=False)

# merge de datasets
df_raw = pd.merge(df_sales_raw, df_store_raw, how='left', on='Store')
# teste de leitura simples
df_raw.sample()<jupyter_output><empty_output><jupyter_text>1.0. PASSO 01 - DESCRICAO DOS DADOS<jupyter_code># fazer uma cópia do dataset quando muda de seção, somente para manter os dados , caso seja necessário recomeçar
df1 = df_raw.copy()
df1.columns<jupyter_output><empty_output><jupyter_text>1.1. Rename Columns<jupyter_code># renomenado as colunas para facilitar analise dos dados
cols_old = ['Store', 'DayOfWeek', 'Date', 'Sales', 'Customers', 'Open', 'Promo', 'StateHoliday', 'SchoolHoliday', 'StoreType', 
            'Assortment', 'CompetitionDistance', 'CompetitionOpenSinceMonth', 'CompetitionOpenSinceYear', 'Promo2', 
            'Promo2SinceWeek', 'Promo2SinceYear', 'PromoInterval']

snakecase = lambda x: inflection.underscore( x)
cols_new = list( map(snakecase, cols_old))

#rename
df1.columns = cols_new
#visualizando as colunas renomeadas
df1.columns<jupyter_output><empty_output><jupyter_text>1.2. Data Dimensions<jupyter_code># leitura de colunas/linhas do dataset para dimensionar os dados
print('Number of Rows: {}'.format(df1.shape[0]))
print('Number of Cols: {}'.format(df1.shape[1]))<jupyter_output>Number of Rows: 1017209
Number of Cols: 18<jupyter_text>1.3. Data Types<jupyter_code># leitura do tipos de dados de cada coluna
df1['date'] = pd.to_datetime(df1['date'])
df1.dtypes<jupyter_output><empty_output><jupyter_text>1.4. Ckeck NA<jupyter_code># Verificando colunas com registros vazios
df1.isna().sum()<jupyter_output><empty_output><jupyter_text>1.5. Fillout NA<jupyter_code>#competition_distance --> 2642 registros vazios
# Verificando qual a maior distancia de um concorrente  -> 75860.0
# SOLUÇÃO para popular registros vazios-> Vou aplicar uma distancia maxima = 200000.0 para os registros NAN desta coluna
df1['competition_distance'] = df1['competition_distance'].apply(lambda x: 200000.0 if math.isnan(x) else x)

#===============================================================================================================
#competition_open_since_month --> 323348 registros vazios
# mes que o concorrente mais proximo foi aberto. Pq este campo esta vazio? a loja ja estava aberta quando instalou a nossa loja ou ninguem resgistrou esta informação
# SOLUÇÃO para popular registros vazios-> APLICAR A DATA (mes) DE VENDA NESTE CAMPO, PARA DEPOIS TESTAR USANDO CRISP E AVALIAR O ALGORITMO
df1['competition_open_since_month'] = df1.apply(lambda x: x['date'].month if math.isnan( x['competition_open_since_month']) else x['competition_open_since_month'], axis=1)

#===============================================================================================================
#competition_open_since_year --> 323348 registros vazios
# IDEM solução do item anterior
# SOLUÇÃO para popular registros vazios-> APLICAR A DATA (ano) DE VENDA NESTE CAMPO, PARA DEPOIS TESTAR USANDO CRISP E AVALIAR O ALGORITMO
df1['competition_open_since_year'] = df1.apply(lambda x: x['date'].year if math.isnan( x['competition_open_since_year']) else x['competition_open_since_year'], axis=1)


#===============================================================================================================
#promo2_since_week --> 508031 registros vazios
# SOLUÇÃO para popular registros vazios-> APLICAR A DATA (semana) DE VENDA NESTE CAMPO, PARA DEPOIS TESTAR USANDO CRISP E AVALIAR O ALGORITMO
df1['promo2_since_week'] = df1.apply(lambda x: x['date'].week if math.isnan( x['promo2_since_week']) else x['promo2_since_week'], axis=1)

#===============================================================================================================
#promo2_since_year --> 508031 registros vazios
# SOLUÇÃO para popular registros vazios-> APLICAR A DATA (ano) DE VENDA NESTE CAMPO, PARA DEPOIS TESTAR USANDO CRISP E AVALIAR O ALGORITMO
df1['promo2_since_year'] = df1.apply(lambda x: x['date'].year if math.isnan( x['promo2_since_year']) else x['promo2_since_year'], axis=1)

#===============================================================================================================
#promo_interval --> 508031 registros vazios
#criando um mapa de mês
month_map = {1: 'Jan', 2: 'Fev', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}

# Colocando 0 nos registros que possui a coluna promo_interval = 0
df1['promo_interval'].fillna( 0, inplace=True )

# Criei uma coluna month_map onde será gravado o mes da coluna 'date' do registro, já convertido de acordo com a biblioteca criada
df1['month_map'] = df1['date'].dt.month.map( month_map )

# Criei uma nova coluna que vai registrar 1 para quem tem promoção no mes de venda e 0 data de venda fora da promoçao
df1['is_promo'] = df1[['promo_interval', 'month_map']].apply( lambda x: 0 if x['promo_interval'] == 0 else 1 if x['month_map'] in x['promo_interval'].split( ',' ) else 0, axis=1 )
# releitura para conferir se ainda temos registros vazios
df1.isna().sum()<jupyter_output><empty_output><jupyter_text>1.6. Change types<jupyter_code># competiton
df1['competition_open_since_month'] = df1['competition_open_since_month'].astype(int)
df1['competition_open_since_year'] = df1['competition_open_since_year'].astype(int)

# promo2
df1['promo2_since_week'] = df1['promo2_since_week'].astype(int)
df1['promo2_since_year'] = df1['promo2_since_year'].astype(int)
# releitura dos tipos de dados para conferencia
df1.dtypes<jupyter_output><empty_output><jupyter_text>1.7. Descriptive Statistical<jupyter_code># Criando dataframes de acordo com o typo da coluna
num_attributes = df1.select_dtypes( include=['int64', 'int32', 'float64'])
cat_attributes = df1.select_dtypes( exclude=['int64', 'int32', 'float64', 'datetime64[ns]'])<jupyter_output><empty_output><jupyter_text>1.7.1 Numerical Attributes<jupyter_code># Dividindo o datafame em dados numéricos e categóricos
# Realizar calculos basicos para cada coluna, para ter uma noção dos dados

# Central Tendency - mean, median
ct1 = pd.DataFrame( num_attributes.apply( np.mean ) ).T
ct2 = pd.DataFrame( num_attributes.apply( np.median ) ).T

#Dispersion - std, min, max, range, skew, kurtosis
d1 = pd.DataFrame( num_attributes.apply( np.std ) ).T
d2 = pd.DataFrame( num_attributes.apply( min ) ).T
d3 = pd.DataFrame( num_attributes.apply( max ) ).T
d4 = pd.DataFrame( num_attributes.apply( lambda x: x.max() - x.min() ) ).T
d5 = pd.DataFrame( num_attributes.apply( lambda x: x.skew() ) ).T
d6 = pd.DataFrame( num_attributes.apply( lambda x: x.kurtosis() ) ).T

# Concatenate
m = pd.concat( [d2, d3, d4, ct1, ct2, d1, d5, d6] ).T.reset_index()
#Rename columns
m.columns = ['attributes', 'min', 'max', 'range', 'mean', 'median', 'std', 'skew', 'kurtosis']
m
sns.distplot( df1['competition_distance'], kde=False )<jupyter_output>/home/leandro/.local/lib/python3.9/site-packages/seaborn/distributions.py:2619: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).
  warnings.warn(msg, FutureWarning)<jupyter_text>1.7.2 Caterigal Attributes<jupyter_code>cat_attributes.apply( lambda x: x.unique().shape[0] )
aux1 = df1[(df1['state_holiday'] != '0' ) & (df1['sales'] > 0)]

plt.subplot( 1, 3, 1)
sns.boxplot( x='state_holiday', y='sales', data=aux1 )

plt.subplot( 1, 3, 2)
sns.boxplot( x='store_type', y='sales', data=aux1 )

plt.subplot( 1, 3, 3)
sns.boxplot( x='assortment', y='sales', data=aux1 )<jupyter_output><empty_output><jupyter_text>2.0. PASSO 02 - FEATURE ENGINEETING<jupyter_code># fazer uma cópia do dataset ao ir para um próximo passo ou seção, somente para manter os dados , caso seja necessário recomeçar
df2 = df1.copy()<jupyter_output><empty_output><jupyter_text>2.1. Mapa Mental de Hipóteses<jupyter_code># Feito Feature Engineering para criar listas de hipóteses e validar dados
Image('../img/DAILY_STORE_SALES.png')<jupyter_output><empty_output><jupyter_text>2.1. Criação das Hipóteses  2.1.1. Hipóteses Loja **1.** Lojas com número maior de funcionários deveriam vender mais.**2.** Lojas com maior capacidade de estoque deveriam vender mais.**3.** Lojas com maior porte deveriam vender mais.**4.** Lojas com maior sortimentos deveriam vender mais.**5.** Lojas com competidores mais próximos deveriam vender menos.**6.** Lojas com competidores a mais tempo deveriam vender mais.  2.1.2. Hipóteses Produto **1.** Lojas que investem mais em Marketing deveriam vender mais.**2.** Lojas com maior exposição de produtos deveriam vender mais.**3.** Lojas com produtos com preço menor deveriam vender mais.**4.** Lojas com promoções mais agressivas (desconto maiores), deveriam vender mais.**5.** Lojas com promoções ativas por mais tempo deveriam vender mais.**6.** Lojas com mais dias de promoção deveriam vender mais.**7.** Lojas com mais promoções consecutivas deveriam vender mais.  2.1.3. Hipóteses Tempo **1.** Lojas abertas durante o feriado de Natal deveriam vender mais.**2.** Lojas deveriam vender mais ao lojgo dos anos.**3.** Lojas deveriam vender mais no segundo semestre do ano.**4.** Lojas deveriam vender mais depois do dia 10 de cada mês.**5.** Lojas deveriam vender menos aos finais de semana.**6.** Lojas deveriam vender menos durante os feriados escolares  2.2. Lista final de Hipóteses **1.** Lojas com maior sortimentos deveriam vender mais.**2.** Lojas com competidores mais próximos deveriam vender menos.**3.** Lojas com competidores a mais tempo deveriam vender mais. **4.** Lojas com promoções ativas por mais tempo deveriam vender mais.**5.** Lojas com mais dias de promoção deveriam vender mais.**6.** Lojas com mais promoções consecutivas deveriam vender mais. **7.** Lojas abertas durante o feriado de Natal deveriam vender mais.**8.** Lojas deveriam vender mais ao lojgo dos anos.**9.** Lojas deveriam vender mais no segundo semestre do ano.**10.** Lojas deveriam vender mais depois do dia 10 de cada mês.**11.** Lojas deveriam vender menos aos finais de semana.**12.** Lojas deveriam vender menos durante os feriados escolares  2.2. Feature Engineering<jupyter_code># Criando novas features utilizando os dados do dataset
# Year
df2['year'] = df2['date'].dt.year

# Month
df2['month'] = df2['date'].dt.month

# Day
df2['day'] = df2['date'].dt.day

# Week of Year
#df2['week_of_year'] = df2['date'].dt.weekofyear
df2['week_of_year'] = df2['date'].dt.isocalendar().week

# Year Week
df2['year_week'] = df2['date'].dt.strftime('%Y-%W')
#competition since
df2['competition_since'] = df2.apply(lambda x: datetime.datetime(year=x['competition_open_since_year'], month=x['competition_open_since_month'], day=1), axis=1)
df2['competition_time_month'] = (( df2['date'] - df2['competition_since'])/30 ).apply(lambda x: x.days).astype(int)
# Promo since
df2['promo_since'] = df2['promo2_since_year'].astype(str) + '-' + df2['promo2_since_week'].astype(str)
df2['promo_since'] = df2['promo_since'].apply(lambda x: datetime.datetime.strptime( x + '-1', '%Y-%W-%w') - datetime.timedelta( days=7))
df2['promo_time_week'] = ((df2['date'] - df2['promo_since'])/7 ).apply(lambda x: x.days).astype(int)
# ASSORTMENT
df2['assortment'] = df2['assortment'].apply( lambda x: 'basic' if x == 'a' else 'extra' if x == 'b' else 'extended')
# State holiday
df2['state_holiday'] = df2['state_holiday'].apply( lambda x: 'public_holiday' if x == 'a' else 'easter_holiday' if x == 'b' else 'christmas' if x == 'c' else 'regular_day' ) 
df2.head().T<jupyter_output><empty_output><jupyter_text>3.0. PASSO 03 - FILTRAGEM DE VARIÁVEIS<jupyter_code>df3 = df2.copy()<jupyter_output><empty_output><jupyter_text>3.1. Filtragem das Linhas<jupyter_code># criando novo dataset com lojas abertas e com vendas
df3 = df3[(df3['open'] != 0) & (df3['sales'] > 0)]<jupyter_output><empty_output><jupyter_text>3.2. Seleção das Colunas<jupyter_code># removendo colunas desnecessárias para analise de dados e deixar o processamento mais rapido
cols_drop = ['customers', 'open', 'promo_interval', 'month_map']
df3 = df3.drop(cols_drop, axis=1)
df3.columns<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup