Analisando os dados do Airbnb - Rio de Janeiro #5
Tags: datascience, python, computerscience, womenintech
Published: 2020-09-01 20:15:50

Para o post de hoje resolvi trazer um projeto de análise de dados utilizando os dados do Airbnb - Rio de Janeiro. Nesse post, quero mostrar um pouco como é feita uma análise de dados. Espero que goste :)

Claro que como boa carioca escolhi os dados do meu RJ rs

<img src="https://media.giphy.com/media/tnykatMsOoyJO/giphy.gif" width="450">

Se você ainda não conhece o Airbnb, saiba que essa empresa só vem ganhando o coração dos viajantes, mas caso você não conheça trago uma breve explicação do que o Airbnb oferece.

**Airbnb** é um serviço online comunitário para as pessoas anunciarem, descobrirem e reservarem acomodações e meios de hospedagem.

O Airbnb permite aos indivíduos alugar todo ou parte de sua própria casa, assim os anfitriões conseguem transformar um cômodo extra ou uma casa extra em uma graninha. O site fornece uma plataforma de busca e reservas entre a pessoa que oferece a acomodação e a pessoa que busca pela locação.

##**Vamos para as análises?**

<img src="https://media.giphy.com/media/Y3MbPtRn74uR3Ziq4P/giphy.gif" width="450">

Vamos começar pelo nosso clássico import de bibliotecas, aqui como vamos fazer apenas uma análise, acaba que não temos muitas bibliotecas para importar, mas espera só vir posts de projetos de Machine Learning para vocês verem o quão cheia essa célula vai ficar rs

```
!pip install missingno 

# importar os pacotes necessários
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno  

# configurar as visualizações
sns.set_style('darkgrid')
sns.set_palette('Accent')
```

Ali em cima também fiz o **!pip** de uma biblioteca que iremos utilizar para visualizar, através de um gráfico, as colunas com dados faltantes do nosso dataset. 

O próximo passo é carregador os nossos dados para dentro de um DataFrame.
Como temos um arquivo csv, vamos utilizar o **pd.read_csv**, como mostro abaixo:

```
# obtendo os dados
data_path = 'http://data.insideairbnb.com/brazil/rj/rio-de-janeiro/2020-04-20/visualisations/listings.csv'

df = pd.read_csv(data_path)
df.head()
```

Além disso, como a função **.head()** conseguimos mostras as 5 primeiras linhas do nosso DataFrame. Caso você queira mostrar mais que 5 linhas, basta colocar a quantidade de linhas dentro dos parênteses :) O default da função é mostrar apenas 5 linhas.

<img src="https://miro.medium.com/max/1250/1*sKTliHMqgGa5b3ixquAwXQ.png" width="800">

Algo que gosto de acrescentar nos projetos é o **Dicionário de Variáveis**. Ele nos diz o que é cada variável. Isso é ótimo para conhecermos melhor os nossos dados e com certeza vai nos ajudar nas análises.

## **Análise Exploratória de Dados**

Nesse projeto eu fiz uma série de perguntas e fui respondendo com os códigos. Na época, eu estava iniciando os estudos e fazer isso me ajudou bastante a entender um pouco como uma análise deve ser feito, quais respostas eu devo trazer ao projeto.

#### **Quantos atributos/variáveis/colunas e quantas entradas/linhas possui o nosso dataframe?**

```
print('DIMENSÕES DO DATAFRAME:')
print(f'Linhas:  {df.shape[0]}')
print(f'Colunas:  {df.shape[1]}')
```

O **.shape** nos retorna uma tupla representando a dimensionalidade do DataFrame. (linhas, colunas)
Para acessar o primeiro elemento dessa tupla eu utilizei o **[0]** e para acessar o segundo elemento utilizei o **[1]** junto do **.shape**

<img src="https://miro.medium.com/max/425/1*g8qLV8DGuzAUxS1MVTmR-w.png" width="450">

#### **Quais são os tipos de dados (dtypes) das nossas variáveis?**

```
df.dtypes
df.dtypes.value_counts()
```
A propriedade .dtypes retorna uma série com o tipos de dado de cada coluna.

<img src="https://miro.medium.com/max/531/1*foWOWxCssaQEOudNWSC82w.png" width="450">

Se você quiser saber quantas colunas de cada tipo de dados esse dataframe possui e não quer ficar contando na mão, utilize o método **.value_counts()**

<img src="https://miro.medium.com/max/205/1*CnqB5Of3GEnLDDZAbXNXfQ.png" width="450">

#### **Nosso dataset possui valores ausentes?**

```
df.isna().any()
df.isna().sum() 

# visualização das entradas de cada coluna
msno.bar (df, figsize = (10,5));

#eliminando a colunaneighbourhood_group
df.drop('neighbourhood_group', axis=1, inplace=True)
```
Para “perguntar” ao dataframe se existe alguma coluna com valor NaN, utilizamos o **.isna().any()**. Ele irá retornar *True* ou *False* para cada coluna.

<img src="https://miro.medium.com/max/505/1*C5a2ERJkbugxJnoxgBVO4A.png" width="450">

E para saber quantos valores ausentes cada coluna possui, utilizamos **.isna().sum()**

<img src="https://miro.medium.com/max/523/1*oIzrucJJWYtGb9JetH0zMw.png" width="450">

Lembra da biblioteca missingno que importamos? Então, ela nos traz mais uma forma de visualizar os dados faltantes de cada coluna.

<img src="https://miro.medium.com/max/875/1*FxHm4jJFwTlvpoSQXbx_fw.png" width="450">

Como vimos anteriormente, nosso dataset possui 35.870 entradas. E analisando os valores ausentes no comando anterior notamos que a variável *neighbourhood_group* não tem dados. Sendo assim, ela não acrescentará em nada na nossa análise, com o **.drop()** eliminei essa variável do DataFrame.

###**Histograma das Variáveis**

Você sabe o que é um histograma?
O histograma, também é conhecido como distribuição de frequências, é a representação gráfica em colunas ou em barras de um conjunto de dados. Se você quer entender melhor sobre, [clique aqui](https://pt.wikipedia.org/wiki/Histograma).

```
# análise visual das variáveis númericas através de um gráfico de frequências (histogramas)
df.hist(bins=15, figsize=(15,10));
```
<img src="https://miro.medium.com/max/875/1*Ij18NIAfbjL-uy4i10bNTQ.png" width="450">

Notamos que há índicios da presença de outliers nos nossos dados, como vemos nas colunas **price, minimum_nights e calculated_host_listings_count**. Um dos indícios é o fato de não conseguirmos visualizar uma distribuição porque possivelmente os outliers, se presentes, estão distorcento a representação gráfica.

###**Detecção de Outliers**

```
# visualizando um resumo estatístico das variáveis númericas
df[['price', 'minimum_nights', 'number_of_reviews',      'reviews_per_month', 'calculated_host_listings_count', 'availability_365']].describe().round(2)
```
Esse método traz muitas informaçãoes relevantes para a análise exploratória. Como média das colunas, o valor mínimo e máximo, seus quartis e também o valor do desvio padrão. Muitas vezes conseguimos visualizar possíveis outliers por aqui.

<img src="https://miro.medium.com/max/875/1*RYDyhfwERJpMbZqWFazoUw.png" width="450">

**Pontos principais da análise feita através do método describe:**

*  O valor mínimo da variável price é 0
*  O valor máximo da variável price é 131.727
*  O valor máximo da variável minimum_nights é 1.123
*  O valor máximo da variável calculated_host_listinings_count é 200

###**Boxplot das variáveis que possivelmente apresentam outliers**

Em estatística descritiva, diagrama de caixa, diagrama de extremos e quartis, boxplot ou box plot é uma ferramenta gráfica para representar a variação de dados observados de uma variável numérica por meio de quartis. [Wikipédia](https://pt.wikipedia.org/wiki/Diagrama_de_caixa)

####Boxplot da variável **minimum_nights**

```
plt.figure(figsize=(15,3))
sns.boxplot(data=df, x='minimum_nights')
plt.title('Boxplot minimum_nights')
plt.show() 

# ver quantidade de valores acima de 30 dias para minimum_nights
print(f'[minimun_nights]\nValores acima de 30:{len(df[df.minimum_nights > 30])} entradas')

print('Porcentagem: {:.4f}%'.format(len(df[df.minimum_nights > 30])/ len(df.minimum_nights)* 100))
```

<img src="https://miro.medium.com/max/875/1*rQ-D56dfT2tCNNQnwrSiig.png" width="450">

Temos **224 entradas com minimum_nights acima de 30**, o que corresponde a **0.62% dos dados**.

####Boxplot da variável **Price**

```
plt.figure(figsize=(15,3))
sns.boxplot(data=df, x='price')
plt.title('Boxplot price')
plt.show() 

# ver quantidade de valores acima de 1500 para price
print(f'[price]\nValores acima de 1500: {len(df[df.price > 1500])} entradas')
print('Porcentagem: {:.4f}%'.format(len(df[df.price > 1500])/ len(df.price) * 100)
```

<img src="https://miro.medium.com/max/875/1*jlBYNsmkuxGnkumUVcUrww.png" width="450">

Temos **3.360 entradas com Price acima de 1.500**, o que corresponde a **9.36% dos dados**.

###**Histograma sem Outlier**

Depois de identificar os outliers, vamos plotar novamente o histograma para visualizarmos os dados limpos.

```
# histogramas com valores de minimum_nights menor que 30 e price menor que 1500
df_clean = df.copy()
df_clean = df_clean.query('minimum_nights < 30 & price < 1500')
df_clean.hist(bins=15, figsize=(15,10));
```

<img src="https://miro.medium.com/max/875/1*K2ikOy6Kyq3_kFDAtSecMw.png" width="450">

###**Correlação existente entre as variáveis**

Correlação é a relação estatística entre duas variáveis. Os coeficientes de correlação são métodos estatísticos para se medir as relações entre variáveis.

Calculamos o coeficiente de correlação com a função **.corr()**

Irei apresentar essa correlação através de uma matriz e de uma forma mais visual através de um heatmap (mapa de calor).

```
corr = df_clean[['price', 'minimum_nights', 'number_of_reviews', 'reviews_per_month',
'calculated_host_listings_count', 'availability_365']].corr() 

#plotando a matriz de correlação
sns.set_context("notebook", font_scale=1.0, rc={"lines.linewidth": 2.5})
plt.figure(figsize=(10,5))

#criando uma máscara para ver apenas os valores de correlação uma vez
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask, 1)] = True
a = sns.heatmap(corr, mask=mask, annot=True, fmt='.2f')
rotx = a.set_xticklabels(a.get_xticklabels(), rotation=90)
roty = a.set_yticklabels(a.get_yticklabels(), rotation=30)
```

<img src="https://miro.medium.com/max/861/1*0R3izIB18NyrRBlwvlDA4Q.png" width="450">

####**Qual é o tipo de hospedagem mais alugado?**

```
# a quantidade de cada tipo de imóvel disponível
df_clean['room_type'].value_counts() 

# porcentagem de cada tipo de imóvel disponível
df_clean['room_type'].value_counts() / len(df_clean)
```

<img src="https://miro.medium.com/max/379/1*_zMhcfqaUcm8Na7EmFh9AA.png" width="450">

<img src="https://miro.medium.com/max/478/1*P6__FcI-S3K3SSz1baJ-Lw.png" width="450">

####**Qual é a localidade mais cara?**

```
# média de preço do top 10 localidades mais caras
df_clean.groupby('neighbourhood')['price'].mean().sort_values(ascending=False)[:10] 

# contagem de imóveis por localidade
df_clean['neighbourhood'].value_counts()
```

<img src="https://miro.medium.com/max/459/1*0NjzxFR1h4H_77yFe6t-aw.png" width="450">

Observação: Como podemos ver existem bairros com mais imóveis alugados, o que pode influenciar diretamente na média de preços por localidade.

<img src="https://miro.medium.com/max/616/1*E3E7BJpXHc6Hf8_R7cl3IQ.png" width="450">

####**Plotando os imóveis pela latitude-longitude**

```
df_clean.plot(kind='scatter', x='longitude', y='latitude',

alpha=0.4, c=df_clean['price'], s=8, cmap=plt.get_cmap('jet'),

figsize=(12,8));
```
<img src="https://miro.medium.com/max/875/1*k50QPhxhd5gAgIT9kbLoOQ.png" width="450">

###**Conclusões:**

*   Aqui foi feita uma análise superficial sobre os dados disponíveis no arquivo citado anteriormente. Para uma análise mais completa recomendo que seja utilizado o dataset que contém mais variáveis/atributos.

*   Conseguimos identificar valores ausentes e outliers, fazer seu tratamento, plotamos alguns gráficos para análise e no final conseguimos responder algumas perguntas.

*   Link do projeto no GitHub: https://bit.ly/3fHgAzX

*   Link do projeto no Google Colab: https://bit.ly/3hQ18Da


## **Contatos:**

- [LinkedIn]: [https://www.linkedin.com/in/beatrizmaiads/](https://www.linkedin.com/in/beatrizmaiads/)
- [GitHub]: [https://github.com/beatrizmaiads](https://github.com/beatrizmaiads)
- [Instagram]: [@beatrizmaiads](https://dev.to/beatrizmaiads)
- [Dev.to]: https://dev.to/beatrizmaiads
- [Medium]: https://medium.com/@beatrizmaiads
- [E-mail]: [beatrizmaiads@outlook.com](mailto:beatrizmaiads@outlook.com)