<jupyter_start><jupyter_text>**Aula Interativa 2**- Bootcamp IGTI  - Desenvolvedor Python  - Módulo 2: Análise de dados- [Prof. <NAME>](https://www.linkedin.com/in/matheusmendonca/)  **Análise de tendências de locações de bicicletas** **Descrição do problema**O uso de bicicletas como um meio de transporte ganhou muita força nos últimos anos, seja por questões ambientais, de saúde ou até mesmo infraestrutura de trânsito. Para incentivar o uso de bicicletas, cidades em todo o mundo têm implementado programas de compartilhamento de bicicleta. Nesses sistemas, as bicicletas são retiradas e devolvidas em quiosques automatizados espalhados em diversos pontos da cidade.As plataformas de compartilhamento de bicicletas costumam coletar diversos tipos de dados, entre eles: duração da viagem, localização inicial e final do percurso, entre outros. Esses dados coletados pela plataforma, em conjunto com informações sobre o clima, trânsito e relevo, por exemplo, torna possível uma análise mais robusta de compartilhamento de bicicletas.A seguir, um descritivo dos dados coletados:- rec_id: índice do registro;- datetime : data- season : estação do ano (1: inverno, 2: primevera, 3: verão, 4: outono);- year : ano (0: 2011, 1:2012);- month : mês (1 a 12);- hour : hora do dia (0 a 23)- is_holiday : booleano indicando feriado;- weekday : dia da semana (0: domingo, ..., 6: sábado);- is_workingday : booleano indicando dia útil;- weather_condition: (1: limpo, 2: nublado, 3: chuva leve, 4: chuva forte);- temp : Temperatura escalada entre 0 e 1. Valor original em graus Celsius: -8 a 39;- atemp: Sensação térmica escalada entre 0 e 1. Valor original em graus Celsius: -16 a 50;- humidity: Humidade relativa (0 a 1)- windspeed: Velocidade do vento escalada entre 0 e 1 (máximo original: 67).- casual: usuários casuais;- registered: usuários registrados;- total_count: contador total de alugueis (casual+registered).  **Análise exploratória**<jupyter_code># carregandos as bibliotecas básicas
import numpy as np
import pandas as pd

# bibliotecas para plots
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['figure.figsize'] = (16, 6)<jupyter_output><empty_output><jupyter_text>Leitura dos dados<jupyter_code># leitura do dataset
df = pd.read_csv("https://pycourse.s3.amazonaws.com/bike-sharing.csv")
df.head()
# info básicas
df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 17379 entries, 0 to 17378
Data columns (total 17 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   datetime           17379 non-null  object 
 1   rec_id             17379 non-null  int64  
 2   season             17379 non-null  int64  
 3   year               17379 non-null  int64  
 4   month              17379 non-null  int64  
 5   hour               17379 non-null  int64  
 6   is_holiday         17379 non-null  int64  
 7   weekday            17379 non-null  int64  
 8   is_workingday      17379 non-null  int64  
 9   weather_condition  17379 non-null  int64  
 10  temp               17379 non-null  float64
 11  atemp              17379 non-null  float64
 12  humidity           17379 non-null  float64
 13  windspeed          17379 non-null  float64
 14  casual             17379 non-null  int64  
 15  registered         17379 non-null  int64  
 16  total_count        173[...]<jupyter_text>Pré-processamento<jupyter_code># date time conversion
df['datetime'] = pd.to_datetime(df['datetime'])

# categorical variables
df['season'] = df['season'].astype('int')
df['is_holiday'] = df['is_holiday'].astype('int')
df['weekday'] = df['weekday'].astype('int')
df['weather_condition'] = df['weather_condition'].astype('int')
df['is_workingday'] = df['is_workingday'].astype('int')
df['month'] = df['month'].astype('int')
df['year'] = df['year'].astype('int')
df['hour'] = df['hour'].astype('int')<jupyter_output><empty_output><jupyter_text>Visualizações<jupyter_code># plot inicial
df.plot(x='datetime', y='total_count');
# tendências horárias
fig, ax = plt.subplots(nrows=2, sharex=True, figsize=(16, 10))

sns.pointplot(data=df, x='hour', y='total_count', hue='season', ax=ax[0])
ax[0].set_title("Locações horáras de bicicletas por estação do ano")
ax[0].grid()

sns.pointplot(data=df, x='hour', y='total_count', hue='weekday', ax=ax[1])
ax[1].set_title("Locações horárias de bicicletas por dia da semana")
ax[1].grid();
# distribuição por mês
fig, ax = plt.subplots()
sns.barplot(data=df, x="month", y="total_count")
ax.set_title("Distribuição mensal de locações");
# distribuição por estação do ano
fig, ax = plt.subplots()
sns.barplot(data=df, x="season", y="total_count")
ax.set_title("Distribuição por estação do ano");
# distribuição por ano
fig, ax = plt.subplots()
sns.barplot(data=df, x="year", y="total_count", estimator=sum, ci=None)
ax.set_title("Locações por ano");
# outliers
fig, ax = plt.subplots(ncols=2)
sns.boxplot(data=df[['total_count', 'casual', 'registered']], ax=ax[0])
sns.boxplot(data=df[['temp', 'windspeed', 'humidity']], ax=ax[1]);
# outliers: uso horário
fig, ax = plt.subplots()
sns.boxplot(data=df, x="hour", y="total_count");
# correlação
plt.figure(figsize=(30,10))

# extraindo matrix de correlação
corr_mat = df[['temp', 'atemp', 'humidity', 'windspeed',
              'casual', 'registered', 'total_count']].corr()

# visualização dos elementos abaixo da diagonal principal
mask = np.array(corr_mat)
mask[np.tril_indices_from(mask)] = False

# plot
sns.heatmap(corr_mat, mask=mask, square=True, annot=True)
plt.show()<jupyter_output><empty_output><jupyter_text>**Modelo preditivo de locações** Nesta seção será feita uma **modelagem simplificada** do problema de previsão de demanda diária do uso de bicicletas.  Pré-processamento<jupyter_code># pré-processamento dos dados: remoção de colunas desnecessárias
df.drop(['rec_id',
         'casual',
         'registered',
         'atemp',
         'year',
         'hour'],
        axis=1,
        inplace=True)
# visualização das primeiras linhas
df.head()
# agrupando pelo datetime
df = df.groupby('datetime', as_index=False).mean()
# com os dados agrupados
df.head()
# visualização dos dados agrupados
df.plot(x='datetime', y='total_count');<jupyter_output><empty_output><jupyter_text>Como se trata de um modelo temporal, iremos utilizar o registro de `total_count` do dia anterior como uma variável exógena do nosso modelo.<jupyter_code># gerando a série defasada total_count: lag1
df['total_count_lag1'] = np.r_[df.iloc[0, -1], df.iloc[:-1, -1]]
# nova coluna
df.head(10)
# ajustando os dtypes
df['season'] = df['season'].astype('int')
df['month'] = df['month'].astype('int')
df['is_holiday'] = df['is_holiday'].astype('int')
df['weekday'] = df['weekday'].astype('int')
df['is_workingday'] = df['is_workingday'].astype('int')
# codificação das variáveis categóricas: one hot encoding
df = pd.get_dummies(df, columns=['season', 'month', 'weekday'])
df.head()
# divisão em treino (90%) e teste (10%)
n, p = df.shape[0], 0.9

df_train = df.iloc[:int(n*p), 1:]
dtime_train = df.iloc[:int(n*p), 0]

df_test = df.iloc[int(n*p):, 1:]
dtime_test = df.iloc[int(n*p):, 0]
print("df_train shape:", df_train.shape)
print("df_test shape:", df_test.shape)
# extração de x_train, x_test, y_train, y_test
x_train = df_train.drop('total_count', axis=1)
y_train = df_train['total_count']

x_test = df_test.drop('total_count', axis=1)
y_test = df_test['total_count']
# model
from sklearn.ensemble import RandomForestRegressor
# fit model
model = RandomForestRegressor(random_state=0)
model.fit(x_train, y_train)
# predição
y_pred = model.predict(x_test)
# intervalo de confiança
n_steps = 3
ts_pred = pd.DataFrame(y_pred)
smooth_path    = ts_pred.rolling(n_steps).mean()
path_deviation = 1.96 * ts_pred.rolling(n_steps).std()

under_line = (smooth_path-path_deviation)[0]
over_line  = (smooth_path+path_deviation)[0]
# visualização
plt.plot(dtime_test, y_pred, linewidth=2, label='predição')
plt.fill_between(dtime_test, under_line, over_line, color='b', alpha=.15)
plt.plot(dtime_test, y_test, label='real')
plt.xticks(dtime_test.iloc[np.arange(dtime_test.size, step= 10).astype(int)])
plt.legend()
plt.grid()
plt.title("Predição do número de locações diárias de bicicletas")
plt.show()
# importâncias das features
fp = model.feature_importances_
n = 5
i = np.argsort(fp)[-n:]
cols = x_train.columns
plt.barh(cols[i], fp[i])
plt.grid()
plt.title(f"{n} features mais importantes")
plt.xlabel("Importância relativa")
plt.ylabel("Feature")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13623628297922016, 'fraction_numerical': 0.02941863180014009, 'mean_word_length': 4.699933466400532, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 26, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '155190', 'license': 'MIT', 'n_tokens_mistral': 3366, 'n_tokens_neox': 3133, 'n_words': 811, 'path': 'IGTI - Bootcamp Desenvolvedor Python/02/[IGTI]_Bootcamp_Aula_Interativa_2.ipynb', 'repo_name': 'ruginski/DS', 'size': '8576'}