image

Accede a bootcamps ilimitados y a más de 650 cursos

50
%OFF
Article image
Luis Vendramim
Luis Vendramim10/01/2025 15:53
Compartir

Construindo modelos preditivos por Decision Tree e Random Forest para estimar o preço de casas com base em seus atributos

    No mundo da especulação de imóveis, é possível identificar padrões de preços de casas de um passado recente, e usar esses padrões para fazer previsões para as novas casas que estarão à venda.

    Para fazer tais previsões, irei comparar neste artigo dois modelos de aprendizado de máquina: Árvore de Decisão e Floresta Aleatória.

    O primeiro passo em qualquer projeto de aprendizado de máquina é familiarizar-se com os dados. Para isso, utilizarei a biblioteca Pandas, principal ferramenta que os cientistas de dados usam para explorar e manipular dados. A maioria das pessoas abrevia pandas em seu código como pd:

    import pandas as pd
    

    Neste artigo, trabalharei com dados sobre preços de casas em Miami, Flórida (EUA).

    Carregando e explorando os dados com os seguintes comandos

    miami_ data = pd.read_csv('miami-housing.csv')
    miami_data.describe()
    

    Como saída, é possível verificar métricas como quantidade de casas, valor médio dos atributos, bem como valores máximo e mínimo:

    image

    Métricas para explorar os dados

    Selecionando dados para o modelo

    Como o conjunto de dados tem muitas variáveis, vou escolher algumas usando minha intuição.

    Para escolher as variáveis/colunas, preciso ver uma lista de todas as colunas no conjunto de dados. Isso é feito com a propriedade columns do DataFrame:

    miami_data.columns
    

    E a saída é:

    Index(['LATITUDE', 'LONGITUDE', 'PARCELNO', 'SALE_PRC', 'LND_SQFOOT',
         'TOT_LVG_AREA', 'SPEC_FEAT_VAL', 'RAIL_DIST', 'OCEAN_DIST',
         'WATER_DIST', 'CNTR_DIST', 'SUBCNTR_DI', 'HWY_DIST', 'age',
         'avno60plus', 'month_sold', 'structure_quality'],
        dtype='object')
    

    Selecionando o alvo da previsão

    Usarei a notação de ponto para selecionar a coluna que quero prever, que é chamada de alvo de previsão. Por convenção, o alvo da previsão é denominado y. Portanto, o código que preciso para salvar os preços das casas nos dados de Miami é:

    y = miami_data.SALE_PRC
    

    Escolhendo os Atributos

    As colunas inseridas no modelo (e posteriormente usadas para fazer previsões) são chamadas de "Atributos". No caso deste artigo, são as colunas utilizadas para determinar o preço da casa. Abaixo é possível visualizar uma lista de nomes das colunas selecionadas:

    miami_atributos = ['LND_SQFOOT', 'TOT_LVG_AREA', 'CNTR_DIST', 'age', 'structure_quality']
    

    Onde:

    • LND_SQFOOT: land area (square feet) – área do terreno (pés quadrados)
    • TOT_LVG_AREA: floor area (square feet) – área útil (pés quadrados)
    • CNTR_DIST: distance to the Miami central business district (feet) – distância do distrito comercial central de Miami (pés)
    • age: age of the structure – idade da estrutura (casa)
    • structure_quality: quality of the structure – qualidade da estrutura

    Por convenção, esses dados são chamados de X:

    X = miami_data[miami_atributos]
    

    Revisando rapidamente os dados que serão usados para prever os preços das casas

    image

    Métricas dos atributos utilizados na previsão

    Construindo o Modelo – Árvore de Decisão

    Usarei a biblioteca scikit-learn para criar os modelos. Scikit-learn é a biblioteca mais popular para modelar os tipos de dados normalmente armazenados em DataFrames.

    As etapas para construir e usar um modelo são:

    • Definição: que tipo de modelo será? Uma árvore de decisão? Algum outro tipo de modelo? Alguns outros parâmetros do tipo de modelo também são especificados.
    • Ajuste: capturar padrões dos dados fornecidos. Este é o coração da modelagem.
    • Previsão: aquilo que se busca.
    • Avaliação: determinar quão precisas são as previsões do modelo.

    Abaixo um exemplo de definição de um modelo de árvore de decisão com scikit-learn, com ajuste aos recursos e à variável alvo:

    from sklearn.tree import DecisionTreeRegressor
    miami_model = DecisionTreeRegressor(random_state=1)
    miami_model.fit(X, y)
    

    Assim se constrói um modelo ajustado que pode ser usado para fazer previsões.

    Validação de modelo

    É preciso avaliar quase todos os modelos que se constrói. Existem muitas métricas para indicar a qualidade do modelo, e para este caso usarei uma métrica chamada Erro Médio Absoluto (também chamado MAE), que quanto menor, mais acurácia tem o modelo. Essa métrica é calculada da seguinte maneira:

    from sklearn.metrics import mean_absolute_error
    predicted_home_prices = miami_model.predict(X)
    mean_absolute_error(y, predicted_home_prices)
    

    O Erro Médio Absoluto calculado foi de 721.5068188343382

    A métrica que foi calculada pode ser chamada de pontuação “na amostra”. Foi utilizada uma única “amostra” de casas tanto para construir o modelo quanto para avaliá-lo.

    E na verdade, o ideal é excluir alguns dados do processo de construção do modelo e, em seguida, usá-los para testar a precisão do modelo em dados que ele não viu antes. Esses dados são chamados de dados de validação.

    Assim, alguns desses dados serão usados como dados de treinamento para ajustar o modelo e os outros dados serão usados como dados de validação para calcular o Erro Médio Absoluto.

    Com esse ajuste no modelo, o novo Erro Médio Absoluto calculado foi de 89809.16221648005

    O MAE passou de aproximadamente 700 dólares para 90 mil dólares.

    Esta é a diferença entre um modelo que é quase exatamente correto e outro que é inutilizável para a maioria dos propósitos práticos. Como ponto de referência, o valor médio da casa nos dados de validação é de 400 mil de dólares. Portanto, o erro nos novos dados é de cerca de um quarto do valor médio da casa.

    Há muitas maneiras de melhorar este modelo, como fazer testes para encontrar melhores recursos ou diferentes tipos de modelo.

    Underfitting e Overfitting

    Um bom modelo não pode sofrer de Underfitting nem de Overfitting.

    Um cenário de Overfitting ocorre quando, nos dados de treino, o modelo tem um desempenho excelente, porém quando utilizamos os dados de teste o resultado é ruim. Já no caso do Underfitting, o desempenho do modelo já é ruim no próprio treinamento. O modelo não consegue encontrar relações entre as variáveis e o teste nem precisa acontecer.

    Existem algumas alternativas para controlar a “profundidade da árvore” e muitas permitem que algumas rotas através da árvore tenham maior profundidade do que outras rotas. O argumento max_leaf_nodes fornece uma maneira muito sensata de controlar o Overfitting versus o Underfitting. Assim, pode-se usar uma função utilitária para ajudar a comparar pontuações MAE de diferentes valores para max_leaf_nodes:

    def get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y):
      model = DecisionTreeRegressor(max_leaf_nodes=max_leaf_nodes, random_state=0)
      model.fit(train_X, train_y)
      preds_val = model.predict(val_X)
      mae = mean_absolute_error(val_y, preds_val)
      return(mae)
    

    Pode-se usar um “loop for” para comparar a precisão de modelos construídos com valores diferentes para max_leaf_nodes:

    train_X, val_X, train_y, val_y = train_test_split(X, y, random_state = 0)
    for max_leaf_nodes in [5, 50, 500, 1000, 2500, 5000]:
      my_mae = get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y)
      print("Max leaf nodes: %d  \t\t Mean Absolute Error:  %d" %(max_leaf_nodes, my_mae))
    

    O resultado obtido foi:

    image

    Erros Médios Absolutos para diferentes max_leaf_nodes

    Das opções listadas, 1000 é o número ideal de folhas, pois possui o menor MAE.

    Floresta Aleatória – Random Forest

    As árvores de decisão nos deixam com uma decisão difícil. Uma árvore profunda com muitas folhas terá um ajuste excessivo porque cada previsão vem de dados históricos de algumas poucas casas em sua folha. Mas uma árvore rasa com poucas folhas terá um desempenho ruim porque não consegue capturar tantas distinções nos dados brutos.

    Mesmo as técnicas de modelagem mais sofisticadas de hoje enfrentam essa tensão entre o Underfitting e o Overfitting. Porém, muitos modelos têm características específicas que podem levar a um melhor desempenho. Um exemplo desses modelos é a floresta aleatória.

    A floresta aleatória usa muitas árvores e faz uma previsão calculando a média das previsões de cada árvore que faz parte da floresta. Geralmente tem uma precisão preditiva muito melhor do que uma única árvore de decisão e funciona bem com parâmetros padrão.

    Um modelo de floresta aleatório é construído da mesma forma que uma árvore de decisão no scikit-learn, mas desta vez usando a classe RandomForestRegressor em vez da DecisionTreeRegressor:

    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import mean_absolute_error
    
    forest_model = RandomForestRegressor(random_state=1)
    forest_model.fit(train_X, train_y)
    miami_preds = forest_model.predict(val_X)
    print(mean_absolute_error(val_y, miami_preds))
    

    O Erro Médio Absoluto calculado para a Random Forest foi de 68207.22489827461

    Provavelmente há espaço para melhorias adicionais, mas esta é uma grande melhoria em relação ao erro da melhor árvore de decisão de 84359. Existem parâmetros que permitem alterar o desempenho da Floresta Aleatória da mesma forma que a profundidade máxima da árvore de decisão única foi alterada. Mas uma das melhores características dos modelos Random Forest é que eles geralmente funcionam razoavelmente mesmo sem esse ajuste.

    Conclusão

    Para os casos em que se precisa estimar os preços de imóveis, as Árvores de Decisão e as Florestas Aleatórias são ferramentas poderosas no mundo do aprendizado de máquina.

    As Árvores de Decisão oferecem simplicidade, interpretabilidade e são mais rápidas de implantar, fazendo delas ideais para conjuntos de dados menores. Não obstante, podem estar sujeitas a Overfitting, especialmente em cenários complexos.

    As Florestas Aleatórias, por outro lado, combinam múltiplas árvores de decisão, fornecendo previsões mais precisas e robustas, especialmente em conjuntos de dados grandes e complexos. Esses modelos têm menos probabilidade de Overfitting e geralmente são mais confiáveis, mas ao mesmo tempo exigem mais recursos computacionais.

    GitHub

    No link abaixo é possível visualizar todo o código escrito e a base de dados:

    https://github.com/luisfelipevendramim/decision-tree-and-random-forest/tree/decision-tree-and-random-forest

    Compartir
    Comentarios (0)