Web Scraping, EDA e Modelo para Previsão de Preços

Diovani Dupont
18 min readFeb 13, 2023

--

— Análise para Previsão de Preços dos Imóveis a Venda no Litoral do RS —

Cidade de Capão da Canoa/RS

Introdução

Antes de começarmos, vou contar como tudo começou e como surgiu a ideia para este estudo.

Você já pensou em mudar de profissão aos 40 anos? Em um primeiro momento parece exaustivo, mas quem conseguiu virar a chave costuma dizer que é libertador. Até porque a tecnologia, a medicina e os hábitos mudaram tanto que já faz tempo que os estereótipos de idade estão ultrapassados, não é mesmo?

Pois é, meu nome é Diovani Dupont e aos 40 anos de idade deixei para trás a área de geotecnologias com uma experiência de 20 anos de mercado para estudar Análise e Desenvolvimento de Sistemas e dar os primeiros passos em Ciência de Dados.

Porém veio a pergunta, mas por onde começar? que dados explorar? Onde consegui-los? Qual primeiro projeto posso começar a desenvolver?

Bom sou natural da cidade de Capão da Canoa no RS, e a principal atividade econômica do município é a construção civil, então veio a ideia, vou fazer um estudo sobre mercado imobiliário local.

A primeira etapa foi conseguir os dados (as informações foram extraídas através do site VivaReal), para isso foram utilizadas as bibliotecas BeautifulSoup e Selenium como ferramentas para webscraping e Pandas para salvar os dados em um arquivo *.csv. Os arquivos gerados e os notebooks com os códigos utilizados para o processo de webscraping podem ser acessados no link abaixo:

diovani-dupont/analise-imoveis-capao: Web Scraping, EDA e Modelo para Previsão de Preços (github.com)

Web Scraping

Iniciando a extração de dados da web utilizando a técnica de Web Scraping que permite coletar informações de sites na Internet para análise ou outros fins de forma automatizada para obter informações na web a partir de páginas HTML, sem a necessidade de interagir com a interface de usuário manualmente.

Começamos com a importação das bibliotecas:

Em seguida foi criado um loop que acessa o site, e faz a raspagem das informações (Título, Endereço, Número, Bairro, Cidade, Estado, Área, Quartos, Banheiros, Vagas, Preço) e salva em um arquivo (*.csv), conforme descrito abaixo.

O código completo encontra-se no GitHub

Análise Exploratória dos Dados (EDA)

Depois de coletados os dados por meio de web scraping, carregamos o data frame e começamos a manipular e analisar as informações utilizando as bibliotecas abaixo.

Ao aplicarmos a função info(), obtemos uma descrição rápida dos dados, e verificamos que não há valores nulos. Entretanto, nas colunas VAGAS e PRECO, o tipo de dados apresentado é object, quando o correto seria integer.

Analisando o data frame utilizando o método head(), foi possível identificar outros problemas na raspagem de dados, como nos campos de cidade e preço, mostrado a seguir.

Para estas correções foi utilizado os métodos astype e replace. Após a filtragem e tratamento dos dados, os resultados foram salvos em um novo data frame.

Para a análise dos dados, decidimos descartar algumas colunas com informações incompletas. Como estamos avaliando dados apenas de uma cidade, salvamos um data frame contendo apenas as colunas consideradas relevantes.

Abaixo foi usado o método describe e transpose para resumir as estatísticas descritivas do data frame. A função describe foi utilizado para gerar um resumo estatístico de cada coluna numérica do data frame, incluindo contagem, média, desvio padrão, valor mínimo, primeiro quartil, mediana, terceiro quartil e valor máximo. O método transpose foi utilizado para inverter as linhas e colunas do resultado.

Isso é útil quando se precisa ter uma visão geral rápida das estatísticas descritivas de cada variável numérica em seu conjunto de dados, sem ter que digitar manualmente cálculos complexos. Além disso, a exibição transposta facilita a comparação das estatísticas entre as variáveis numéricas.

Criando um histograma para representar graficamente a distribuição de frequências da variável PRECO.

A média de preço é de 796.122,00 o que indica que o valor médio dos preços é alto.

A mediana de preço é de 660.000,00 o que indica que a metade dos preços são menores e a metade são maiores que esse valor. Isso sugere que a distribuição dos preços pode ser assimétrica e que pode haver alguns valores atípicos que estão influenciando a média.

O modo de preço é de 650.000,00 o que indica que esse é o valor mais frequente dos preços. Isso pode sugerir que há uma quantidade significativa de preços que se concentram nesse valor.

Abaixo ao criar um gráfico de dispersão para apresentar a relação entre as variáveis PRECO e AREA, é possível visualizar e identificar tendências e valores atípicos “outliers”, que podem causar impactos significativos na análise de dados, especialmente nas estatísticas descritivas. Eles podem distorcer as médias, aumentar a variabilidade e mudar as distribuições.

Utilizando gráfico box plot para mostrar a distribuição de valores de uma variável em relação a outra. No caso específico, o gráfico exibe a distribuição dos preços dos imóveis em relação à sua área.

Com base nas informações apresentadas acima, é possível inferir que:

A maioria dos preços dos imóveis está concentrada entre R$ 359.881,00 e R$ 1.350.000,00 com uma variação média de preços entre R$ 596.000,00 e R$ 630.000,00.

Há uma concentração mais elevada de imóveis com preços entre R$ 359.881,00 e R$ 450.000,00 com uma média de 714 imóveis neste intervalo.

A variação de preços é menor na faixa de R$ 450.000,00 a R$ 596.000,00 com uma média de 543 imóveis.

Há uma quantidade significativa de outliers, ou seja, imóveis com preços muito elevados ou muito baixos em relação aos demais imóveis.

No o gráfico abaixo podemos ver a distribuição dos preços dos imóveis em relação aos quartos, banheiros e vagas de garagem.

É possível verificar que, em geral, quanto maior a quantidade de quartos, banheiros e vagas, maior será o preço médio dos imóveis.

Por exemplo, a média de preço dos imóveis com 1 quarto é de R$ 352.715,00, enquanto que a média de preço dos imóveis com 6 quartos é de R$ 2.936.667,00, que é cerca de 8 vezes maior.

Imóveis com 1 banheiro têm uma média de preço de R$ 554.411,00 enquanto imóveis com 2 banheiros têm uma média de preço de R$ 754.171,00, imóveis com 7 ou 8 banheiros têm médias de preço mais elevadas, de R$ 3.110.000,00 e R$ 2.500.000,00 respectivamente.

Para imóveis que possuem 1 vaga, o valor médio é de aproximadamente R$ 660.620,00 já para imóveis que possuem 5 vagas, o valor médio é de aproximadamente R$ 4.113.052,00.

Com o gráfico de barras abaixo podemos ver a relação entre a área e o preço de imóveis, colorido de acordo com a quantidade de quartos de cada imóvel. Ele permite identificar padrões e tendências na relação entre a área e o preço, bem como ver como a quantidade de quartos afeta o preço.

Por exemplo, é possível ver se imóveis com maior área tendem a ser mais caros, independentemente da quantidade de quartos. Além disso, é possível ver se a quantidade de quartos afeta significativamente o preço dos imóveis, indicando se é mais vantajoso ter mais quartos ou uma área maior.

Gerando um mapa de calor para identificar a correlação entre as variáveis, indicando se há uma forte relação linear entre elas.
As cores no mapa de calor variam de acordo com a força da correlação, sendo que cores mais escuras indicam uma forte correlação e cores mais claras uma correlação fraca.

O mapa de calor apresenta a correlação entre as variáveis numéricas do data set. A correlação varia de -1 a 1 e o valor de correlação 1 indica que duas variáveis são totalmente positivamente correlacionadas, ou seja, quando aumenta a primeira variável, a segunda também aumenta e quando uma diminui a outra também. Já o valor -1 indica que as variáveis são totalmente negativamente correlacionadas, ou seja, quando aumenta a primeira variável, a segunda diminui e vice-versa. Valores próximos a 0 indicam que as variáveis não possuem correlação significante entre si.

A partir dos valores gerados, é possível observar que há uma correlação positiva entre “QUARTOS” e “PRECO” (0.632865), indicando que quanto maior o número de quartos, maior é o preço médio. Já a variável “VAGAS” apresenta uma correlação moderada com o “PRECO” (0.553267). As variáveis “AREA” e “BANHEIROS” possuem uma correlação moderada com o “PRECO” (0.610205 e 0.508129, respectivamente). Por fim, as variáveis “AREA” e “QUARTOS” possuem uma correlação positiva significativa (0.617403).

Gerando um gráfico de barras para visualizar a relação entre as variáveis PRECO x BAIRRO e PRECO x AREA, para comparar as médias da variável dependente (y) para os diferentes grupos da variável independente (x).

A seguir, utilizaremos a função “factorize” para transformar a coluna “BAIRRO” em tipos numéricos. Em seguida, mapearemos os valores da coluna “BAIRRO” para números, recuperaremos o nome original do bairro a partir do valor numérico e, por fim, removeremos os outliers com a função Z-Score, gerando assim um novo dataframe.

Converter uma coluna de dados com tipo string em um tipo numérico é importante na análise de dados porque muitos algoritmos de aprendizado de máquina e técnicas estatísticas só funcionam com dados numéricos. Além disso, as colunas de dados tipo string são geralmente menos úteis para a análise de dados, pois são tratadas como valores categóricos ao invés de valores numéricos. Quando você converte uma coluna de dados tipo string em um tipo numérico, você pode aproveitar as técnicas estatísticas e de aprendizado de máquina para explorar as relações e tendências nos dados.

Identificando e removendo os outliers usando o método Z-Score e gerando um novo data frame. O método Z-Score é o número de desvios padrão em relação à média. Um valor com um Z-Score muito alto ou muito baixo é considerado um outlier.

Criando um novo o gráfico de dispersão usando as informações do data frame sem outliers, é possível visualizar que os valores atípicos reduziram significativamente.

Obtendo uma visão geral das estatísticas descritivas dos dados entre o primeiro data frame e o segundo(data frame sem outliers), podemos comparar as médias e ver a diferença percentual entre elas.

Para a variável “Área”, a média no primeiro data frame é de 101.24 m², enquanto no data frame sem outliers é de 96.18 m². A diferença percentual é de 5.19% a mais no primeiro data frame em relação ao data frame sem outliers.

Para a variável “Quartos”, a média no primeiro data frame é de 2.26 quartos, enquanto no data frame sem outliers é de 2.22 quartos. A diferença percentual é de 1.76% a mais no primeiro data frame em relação ao data frame sem outliers.

Para a variável “Banheiros”, a média no primeiro data frame é de 1.94 banheiros, enquanto no data frame sem outliers é de 1.88 banheiros. A diferença percentual é de 2.97% a mais no primeiro data frame em relação ao data frame sem outliers.

Para a variável “Vagas”, a média no primeiro data frame é de 1.19 vagas, enquanto no data frame sem outliers é de 1.14 vagas. A diferença percentual é de 4.35% a mais no primeiro data frame em relação ao data frame sem outliers.

Por fim, para a variável “Preço”, a média no primeiro data frame é de R$796.122,04, enquanto no data frame sem outliers é de R$732.999,10. A diferença percentual é de 7.26% a mais no primeiro data frame em relação ao data frame sem outliers.

Em resumo, é possível observar que, em geral, as médias no primeiro data frame são um pouco maiores do que no data frame sem outliers, com exceção da variável “Área”.

Ao comparar os dois data frames, podemos notar algumas diferenças significativas. Por exemplo, no data frame sem outliers apresenta menos contagem de observações em comparação com o primeiro data frame, o que sugere que algumas observações foram removidas. Além disso, a média para cada variável no data frame sem outliers é menor do que no primeiro data frame, o que sugere que a remoção de outliers teve um impacto na média.

O desvio padrão também é menor no data frame sem outliers, o que indica que os dados estão menos dispersos em comparação com o primeiro data frame. Finalmente, o valor mínimo e máximo para cada variável no data frame sem outliers é menor do que no primeiro data frame, sugerindo que os outliers foram realmente removidos.

Em geral, a remoção de outliers no data frame sem outliers teve um impacto significativo nas estatísticas descritivas. Isso pode ser útil para melhorar a precisão dos resultados de análises futuras.

Modelo de Previsão de Preços

De posse dos dados onde foram feitos a limpeza, manipulação, remoção dos valores ausentes, outliers e seleção das variáveis independentes que serão utilizadas para fazer previsões, vamos dar inicio a criação de um modelo para previsão de preços visando estimar o valor da variável numérica dependente (PRECO) com base nas variáveis independentes (AREA, QUARTOS, BANHEIROS, VAGAS, e BAIRRO).

Optei por utilizar o modelo Random Forest Regressor, que é uma técnica de aprendizado de máquina utilizada para a previsão de valores numéricos, como por exemplo o preço de imóveis. Ele é chamado de “Random Forest” porque constrói uma floresta de árvores de decisão, onde cada árvore é uma previsão independente e o resultado final é uma média ou votação dessas árvores.

Existem vários motivos pelos quais o Random Forest Regressor é uma boa opção para a previsão de preços de imóveis. Aqui estão alguns:

Capacidade de lidar com variáveis categóricas: O modelo Random Forest Regressor pode lidar com variáveis categóricas, o que é importante para prever preços de imóveis, onde o bairro em que um imóvel está localizado pode ter um impacto significativo no seu preço.

Tratamento de dados faltantes: O modelo Random Forest Regressor é capaz de lidar com dados faltantes de forma eficiente, o que é importante em situações em que algumas informações sobre imóveis não estão disponíveis.

Robustez ao overfitting: O modelo Random Forest Regressor é menos propenso a overfitting do que outros modelos de aprendizado de máquina, o que significa que ele é capaz de generalizar bem para dados futuros e evitar a memorização dos dados de treinamento.

Facilidade de interpretação: O modelo Random Forest Regressor é relativamente fácil de interpretar, pois permite que você visualize a importância de cada variável na previsão de preços.

Em resumo, o modelo Random Forest Regressor é uma boa opção para a previsão de preços de imóveis devido a sua capacidade de lidar com variáveis categóricas, tratar dados faltantes, ser robusto ao overfitting e ser fácil de interpretar.

Para isso serão utilizadas as bibliotecas abaixo:

Começamos dividindo os dados em conjuntos de treinamento e teste em uma proporção de 80% para treinamento e 20% para teste, esta é uma técnica importante na modelagem de aprendizado de máquina. O objetivo é separar uma parte dos dados para serem usados para treinar o modelo e outra parte para avaliar o desempenho do modelo.

No caso do modelo Random Forest Regressor, o conjunto de treinamento é usado para criar o modelo, ajustando os parâmetros e as árvores para se adaptarem aos dados. O conjunto de teste, por sua vez, é usado para avaliar o desempenho do modelo, comparando as previsões do modelo com os valores reais.

Após isso será criada uma instância do modelo Random Forest Regressor, onde “reg” é uma variável que irá armazená-lo, tambem será estimado o número de árvores na floresta aleatória, neste caso, está sendo especificado 100 árvores e iremos definir um número aleatório específico para garantir que a geração de números aleatórios seja consistente entre execuções (random_state).

Ao ajustar o modelo aos dados de treinamento, o modelo aprenderá as relações entre as variáveis de entrada e de saída, e será capaz de realizar previsões precisas sobre os dados de teste.

Em seguida utilizaremos o método predict onde estará prevendo os valores da variável dependente “y” baseado no conjunto de teste “X_test” usando o modelo de Random Forest criado anteriormente. A variável “y_pred” é uma lista com as previsões para cada exemplo do conjunto de teste. O método predict é usado para fazer previsões a partir do modelo ajustado previamente. Nesse caso, o modelo de Random Forest (reg) é ajustado aos dados de treinamento “X_train e y_train” e, em seguida, é usado para fazer previsões no conjunto de teste “X_test”. O resultado da previsão é armazenado na variável “y_pred”.

Abaixo iremos calcular o erro quadrático médio (mean squared error — MSE) entre as previsões do modelo “y_pred” e os valores reais “y_test”. O MSE é uma medida de erro comum em problemas de regressão, e é calculado como a média dos quadrados dos erros (distância entre o valor real e o valor previsto).

A raiz quadrada do MSE é chamada de erro quadrático médio raiz (root mean squared error — RMSE), e é usada para tornar a escala do erro comparável com a escala dos dados. O RMSE é amplamente utilizado para avaliar a performance de modelos de previsão.

No código acima, a função mean_squared_error do scikit-learn é usada para calcular o MSE, e a função np.sqrt é usada para calcular a raiz quadrada. O resultado final, o RMSE, é impresso na tela.

O resultado do RMSE foi de aproximadamente 234030 e o erro percentual é de cerca de 23,65%, isso sugere que o modelo está tendo um desempenho razoável, mas ainda há margem para melhorias. O RMSE é uma medida da variação entre os valores previstos e os valores observados, portanto, um valor menor de RMSE indica uma menor variação entre os dois e, consequentemente, uma melhor precisão.

A maneira de melhorar a precisão do modelo é avaliando e ajustando os hiperparâmetros do modelo, como a profundidade máxima da árvore, o número de amostras mínimas necessárias para dividir um nó e o número de amostras mínimas em uma folha.

Abaixo iremos fazer comparação entre o RMSE (Root Mean Squared Error) e a variância dos dados, que é usada para avaliar a qualidade do modelo de previsão.

Ao comparar o RMSE com a variância dos dados, é possível avaliar se o modelo está realmente fazendo previsões precisas ou se ele está apenas prevendo valores próximos a média dos dados. Se o RMSE for muito próximo da variância dos dados, isso significa que o modelo está prevendo valores próximos à média dos dados, mas não está fazendo previsões precisas.

O resultado mostra que o erro quadrático médio (RMSE) é satisfatório, pois é menor ou igual à variância dos dados. A variância dos dados é uma medida da dispersão dos valores em torno da média. Quanto maior a variância, maior é a dispersão dos dados. Portanto, se o RMSE é menor do que a variância dos dados, isso significa que o modelo está fazendo uma boa previsão, pois os erros de previsão são menores do que a dispersão dos dados.

Abaixo iremos criar um data frame com valores reais e previstos, ele é importante para comparar a performance do modelo de previsão. Isso permite visualizar a diferença entre o valor previsto pelo modelo e o valor real, o que pode ser útil para identificar pontos fortes e fracos do modelo.

O gráfico de dispersão para valores reais e previstos gerado abaixo mostra o quão próximos são os valores previstos do modelo dos valores reais. Se o modelo estiver prevendo valores corretos, os pontos no gráfico devem estar concentrados ao redor da linha diagonal, indicando uma correlação positiva entre os valores reais e previstos. Caso contrário, os pontos devem estar mais espalhados, indicando uma correlação fraca ou nenhuma entre os valores reais e previstos. O gráfico de dispersão também permite visualizar se há algum viés no modelo, por exemplo, se ele estiver subestimando ou superestimando os valores.

Abaixo vamos gerar um gráfico de resíduos que é uma visualização importante para avaliar a qualidade do modelo de previsão. Ele representa a diferença entre os valores reais e os valores previstos de uma variável dependente.

O objetivo é verificar se o modelo está prevendo os valores de maneira consistente com os valores reais. Se os resíduos apresentarem uma distribuição aleatória e com amplitude similar, é um indicativo de que o modelo está previsão adequadamente.

Já se os resíduos apresentarem uma distribuição não aleatória ou com amplitudes distintas, pode ser um indicativo de que o modelo precisa ser ajustado ou que algum fator importante está sendo ignorado.

Abaixo iremos plotar a distribuição dos resíduos com a função distplot para exibir o histograma dos resíduos juntamente com a estimativa de densidade de probabilidade. O eixo “x” mostra os resíduos, enquanto o eixo “y” mostra a densidade.

O gráfico de distribuição de resíduos é uma ferramenta utilizada para avaliar a qualidade de um modelo de previsão. Ele representa a diferença entre os valores previstos pelo modelo e os valores observados na base de dados.

A ideia é que, se o modelo estiver corretamente ajustado, a distribuição dos resíduos deve ser aproximadamente normal, ou seja, centrada em zero e com uma variação constante. Isso indica que a maioria das previsões está perto dos valores observados e que o modelo não está sub ou sobre-estimando as previsões em geral.

Gerando um gráfico de importância de variáveis que é uma representação visual que mostra a importância relativa de cada variável em um modelo de aprendizado de máquina. Ele é frequentemente usado em modelos de árvores de decisão, como Random Forest, para entender qual variável tem mais influência na previsão.

A importância de uma variável pode ser medida de várias maneiras, como pela redução na impureza da árvore ou pela contribuição para a previsão. O gráfico de importância de variáveis apresenta essa informação de forma gráfica.

O gráfico de importância de variáveis é útil para compreender quais variáveis são mais importantes no modelo e para tomar decisões sobre quais variáveis incluir ou excluir ao refinar o modelo.

Resultado Final

Finalmente, obtivemos o resultado final da previsão do valor do imóvel através do modelo Random Forest, onde inserimos informações sobre as variáveis, como área, quartos, banheiros, vagas de estacionamento e localização. Por exemplo, o valor previsto para um imóvel de 100 metros quadrados, com 2 quartos, 2 banheiros, 2 vagas de estacionamento, localizado no bairro 2 (Navegantes), é de R$ 833.925,21 conforme mostrado abaixo. Este valor foi determinado através do uso de técnicas de aprendizado de máquina e da análise de dados dos imóveis.

Conclusão

Com base na análise dos dados realizada neste estudo, foi possível avaliar a acurácia do modelo utilizando a métrica RMSE (Root Mean Squared Error). O resultado obtido foi de RMSE: 234030.50242916663 e Erro percentual: 23.65433358317232 %, o que indica que houve um erro de 23% na previsão dos valores de preço dos imóveis.

Além disso, foram ajustados os hiperparâmetros do modelo Random Forest, o que resultou em uma melhora na acurácia. Embora ainda exista margem para melhorias, os resultados apresentados são satisfatórios para fins puramente educacionais ou de pesquisa e mostram que o modelo é uma ferramenta útil para fazer previsões de preço dos imóveis.

Em resumo, este estudo demonstra que a utilização de modelos de aprendizado de máquina é uma abordagem viável para prever preços de imóveis e que ajustes mais finos podem levar a resultados ainda mais precisos.

Como primeiro estudo de caso em ciência de dados, foi uma experiência enriquecedora e desafiadora. Utilizando as técnicas aprendidas, foi possível coletar dados, explorá-los e construir um modelo que prevê preços de imóveis com uma margem de erro satisfatória para fins de estudo. Além disso, a geração de gráficos foi fundamental para compreender a relação entre as variáveis e buscar insights para aprimorar o modelo. Este projeto mostrou a importância e a eficácia da utilização de técnicas de ciência de dados em problemas reais, e abre portas para novos estudos e aplicações em outras áreas.

--

--

Diovani Dupont

Technology professional studying Systems Analysis and Development, I seek to learn and gain professional experience in Data Science and Analysis.