Search
Close this search box.
Preveja os preços de carros como um profissional com IA
preços de carros com regressão linear

Posts Relacionados:

Use a IA para prever preços de carros com regressão linear, uma poderosa técnica de machine learning, e abandone a pechincha!

Receba nossa newsletter

Preços de carros com IA

A indústria de compra e venda de carros usados é um mercado dinâmico, mas suscetível a golpes. Prever preços de carros é uma tarefa difícil e exige conhecimento especializado. Ao tentarmos vender ou comprar um carro, nunca sabemos se o preço negociado foi mesmo bom. Muitas revendedoras da indústria de veículos utilizam certificações de qualidade para promover seus produtos e determinar os preços que elas estão dispostas a pagar. Porém, obter uma certificação é um processo caro e demorado que requer a avaliação realizada por especialistas humanos.

Portanto, para o mercado de compra e venda de carros usados, seria interessante que o preço justo de um carro pudesse estar facilmente correlacionado com as suas características. Felizmente, a inteligência artificial (IA) pode nos ajudar nessas horas. Nesse post, usaremos a regressão linear, uma técnica simples de machine learning, para desenvolver um modelo que prevê o preço de carros rapidamente.

O Objetivo do Modelo

Partiremos de um conjunto de dados contendo detalhes de carros, como tipo de combustível, ano de fabricação, especificações do motor, etc. O conjunto também inclui os preços dos carros. Nosso objetivo é criar um modelo de machine learning usando regressão linear para prever o preço de carros com base em suas características.

O Conjunto de Dados

Utilizaremos um conjunto de dados contendo características e preços de carros. O conjunto está disponível para download gratuitamente no site do Kaggle nesse link. Ele possui cerca de 100 mil dados de carros para várias marcas. Utilizaremos apenas os dados para carros da marca Ford.

Os dados são da Inglaterra e possuem os seguintes atributos: modelo (model), ano de fabricação (year), preço (price), transmissão (transmission), quilometragem (mileage), tipo de combustível (fuelType), imposto (tax), consumo (mpg) e tamanho do motor (engineSize).

Bibliotecas

Utilizaremos várias bibliotecas típicas de machine learning e ciência de dados:

Início do Código

Num código Python, importamos os pacotes que serão usados:

				
					import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

import warnings
warnings.filterwarnings('ignore')
				
			

Os dados precisam ser abertos com Pandas.

				
					filename = 'data/ford.csv'
df = pd.read_csv(filename)


				
			

Antes de implementar o modelo, teremos que realizar a análise e pré-processamento dos dados.

Verificação dos Dados

Um dos primeiros passo para a implementação de qualquer modelo de machine learning é a verificação do conjunto de dados. Iniciaremos essa verificação imprimindo alguns exemplos do início e fim do conjunto.

				
					print(df.head())
    
# resultados:
#     model  year  price transmission  mileage fuelType  tax   mpg  engineSize
# 0   Fiesta  2017  12000    Automatic    15944   Petrol  150  57.7         1.0
# 1    Focus  2018  14000       Manual     9083   Petrol  150  57.7         1.0
# 2    Focus  2017  13000       Manual    12456   Petrol  150  57.7         1.0
# 3   Fiesta  2019  17500       Manual    10460   Petrol  145  40.3         1.5
# 4   Fiesta  2019  16500    Automatic     1482   Petrol  145  48.7         1.0

print(df.tail())
    
# resultados:
#          model  year  price transmission  mileage fuelType  tax   mpg  engineSize
# 17960   Fiesta  2016   7999       Manual    31348   Petrol  125  54.3         1.2
# 17961    B-MAX  2017   8999       Manual    16700   Petrol  150  47.1         1.4
# 17962    B-MAX  2014   7499       Manual    40700   Petrol   30  57.7         1.0
# 17963    Focus  2015   9999       Manual     7010   Diesel   20  67.3         1.6
# 17964       KA  2018   8299       Manual     5007   Petrol  145  57.7         1.2
				
			

Os resultados obtidos indicam que possuímos dados numéricos e categóricos. O conjunto de dados com os preços de carros possui mais de 17 mil dados. Além dos preços, o conjunto possui oito atributos que serão usados no modelo.

A função dtypes() mostra os tipos de dados presentes no dataset, o que é importante para determinar alguns procedimentos de pré-processamento.

				
					print(df.dtypes())

# resultados

# model            object
# year              int64
# price             int64
# transmission     object
# mileage           int64
# fuelType         object
# tax               int64
# mpg             float64
# engineSize      float64
# dtype: object
				
			

Os dados do tipo object terão que ser tratados posteriormente, pois eles são categóricos.

Verificação de dados ausentes e duplicados

Também precisamos verificar a presença de dados faltantes.

				
					print(df.isnull().sum())

# resultados:
# model           0
# year            0
# price           0
# transmission    0
# mileage         0
# fuelType        0
# tax             0
# mpg             0
# engineSize      0
# dtype: int64
				
			

O conjunto de dados não possui nenhum valor faltante.

Outro fator que precisa ser verificado no conjunto de dados é a presença de dados duplicados. Os valores duplicados serão removidos se forem encontrados.

				
					
print(df.duplicated().sum())
# resultado: 154
df.drop_duplicates()
				
			

Acima, encontramos 154 dados duplicados. Eles foram removidos com o método drop_duplicate() do Pandas.

Análise Estatística Básica

Em termos de análise estatística, o primeiro passo sempre é obter uma pequena descrição dos dados com Pandas.

				
					df.describe()

# resultados
#                year         price        mileage           tax           mpg    engineSize
# count  17965.000000  17965.000000   17965.000000  17965.000000  17965.000000  17965.000000
# mean    2016.866574  12279.756415   23363.630504    113.334539     57.906991      1.350827
# std        2.050346   4741.382606   19472.114690     62.010438     10.125977      0.432371
# min     1996.000000    495.000000       1.000000      0.000000     20.800000      0.000000
# 25%     2016.000000   8999.000000    9987.000000     30.000000     52.300000      1.000000
# 50%     2017.000000  11291.000000   18243.000000    145.000000     58.900000      1.200000
# 75%     2018.000000  15299.000000   31064.000000    145.000000     65.700000      1.500000
# max     2060.000000  54995.000000  177644.000000    580.000000    201.800000      5.000000
				
			

A função nunique() do Pandas é excelente para mostrar quantas ocorrências temos para cada recurso do dataset.

				
					df_unique = []
for feature in features:
    df_unique.append((f'{feature} ---> {df[feature].nunique()}'))
print(df_unique)

# resultados
# ['model ---> 23', 'year ---> 23', 'price ---> 3511', 'transmission ---> 3', 'mileage ---> 13528', 'fuelType ---> 5', 'tax ---> 35', 'mpg ---> 90', 'engineSize ---> 16']
				
			

Após essas verificações, sabemos que conjunto de dados abrange quase 18000 carros de 23 modelos diferentes. Cada carro possui um conjunto único de atributos.

Faixa de 💰 preço:

Preço Min: 495.00 libras.

Preço Max: 54995.00 libras.

O preço médio do carro é de cerca de £ 12279.75.

Análise Exploratória dos Dados (EDA)

Para a análise exploratória de dados, faremos os gráficos kde e boxplot para as variáveis numéricas. Esses gráficos fornecem insights importantes sobre as distribuições dos dados e sobre a presença de outliers.

				
					#PLOT VARIÁVEIS NUMÉRICAS 
features = list(df.select_dtypes(include=['float', 'int']).columns)
features.remove('price')
fig, ax = plt.subplots(len(features), 2, figsize=(9, 11))
for i in range(len(features)):
    sns.kdeplot(ax=ax[i,0], x=features[i], data=df, fill = True, color='lightskyblue')
    sns.boxplot(ax=ax[i,1], x=features[i], data=df, fill = True, color='lightskyblue')
fig.tight_layout(pad=1)
plt.show()
				
			

Os gráficos são mostrados abaixo.

EDA para prever preços de carros

Há muitos outliers especialmente para os recursos de ano de fabricação (year) e quilometragem (mileage). A distribuição de dados é desigual e a maioria deles está com inclinação para o lado, em vez de uma distribuição gaussiana.

Também é importante analisar a distribuição dos preços no conjunto de dados com um histograma.

				
					fig, axes = plt.subplots()
sns.histplot(data=df['price'], bins=20, kde=True, fill=True)
plt.title('Distribution of Price')
fig.tight_layout()
plt.show()
				
			
histograma com preços de carros
A distribuição de preços indica uma distribuição com inclinação.

Análise de Correlações

Em termos de técnicas de visualizações, uma das mais importantes é a análise de correlações. Ela pode ser feita com um heatmap usando a biblioteca Seaborn. Essa análise verifica as correlações entre os atributos numéricos do conjunto de dados.

				
					correlation = df[df.select_dtypes(include=['float', 'int']).columns].corr()
fig, ax = plt.subplots(figsize=(6, 6))
sns.heatmap(correlation, annot=True)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
ax.set_title('Heatmap',  weight='bold')
fig.tight_layout()
plt.show()
				
			

Abaixo veja o heatmap obtido indicando correlações principalmente do preço com o ano de fabricação dos carros, a taxa de imposto e o tamanho do motor. Existem também correlações negativas. As mais importantes são entre o preço dos carros e sua quilometragem e consumo.

Preços de carros heatmap

Variáveis Categóricas

Obviamente, além das variáveis numéricas, precisamos analisar as relações entre os preços de carros e as variáveis categóricas do conjunto de dados. Elas são: modelo, transmissão e tipo de combustível. O código para plotá-las é mostrado abaixo.

				
					features = list(df[df.select_dtypes(exclude=[float]).columns])

for feature in features:
    if df[feature].dtype == object:
        sns.catplot(y='price',x=feature,data= df.sort_values('price',ascending=False),kind='boxen',height=5, aspect=3, palette='rainbow')
        plt.ylabel('Price (£)',  weight='bold')
        plt.xlabel(f'{feature}'.title(),  weight='bold')
        sns.despine()
        plt.xticks(rotation=90)
        plt.tight_layout()
        plt.show()

				
			

E aqui estão os gráficos obtidos.

car models correlation
car transmissions
fuelType

Novamente vemos a presença de outliers. Essa analise também revela que a distribuição de dados para as variáveis categóricas é desigual.

Remoção de Outliers e Engenharia de Recursos

Com base na análise realizada, faremos o pré-processamento dos dados, nos concentrando em especial na remoção de outliers. Em seguida, faremos a engenharia de recursos. Para isso, usaremos a biblioteca Scikit-learn. Ela também será usada posteriormente para implementar o modelo de regressão linear. Portanto, faremos as importações necessárias:

				
					
from sklearn.preprocessing import LabelEncoder, MinMaxScaler
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score

				
			

O pré-processamento inclui a remoção dos valores extremos encontrados em vários atributos dos dados. Antes, criamos uma cópia dos dados para criar um novo conjunto de dados limpos (clean_data):

				
					
clean_data = df.copy()

clean_data = clean_data[clean_data['year'] >= 2000]
clean_data = clean_data[clean_data['year'] < 2024]
clean_data = clean_data[clean_data['mileage'] <= 70000]
clean_data = clean_data[clean_data['mpg'] <= 100]
clean_data = clean_data[clean_data['tax'] <= 200]

clean_data['year'] = 2024 - clean_data['year']
				
			

No código acima, além da remoção de outliers, transformamos o formato do ano de fabricação para idade dos carros (linha 9).

Em seguida, realizamos a conversão dos dados categóricos usando o método LabelEncoder() do Scikit-learn.

				
					
encoder = LabelEncoder()
clean_data['model'] = encoder.fit_transform(clean_data['model'])
clean_data['transmission'] = encoder.fit_transform(clean_data['transmission'])
clean_data['fuelType'] = encoder.fit_transform(clean_data['fuelType'])
				
			

Treinamento do Modelo para Prever Preços de Carros

A implementação do modelo em si é simples. Primeiro, separamos a variável y que o modelo deve aprender a fitar.

				
					
X = clean_data.drop(['price'], axis=1)
y = clean_data['price']

scaler = MinMaxScaler()
X = scaler.fit_transform(X)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)


				
			

Em seguida, normalizamos os dados do conjunto X com MinMaxScaler().

				
					scaler = MinMaxScaler()
X = scaler.fit_transform(X)

				
			
				
					
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)


				
			

Por fim, implementamos o modelo de regressão linear e realizamos o treinamento.

				
					lin_reg = LinearRegression()
lin_reg.fit(X_train, y_train)
y_pred = lin_reg.predict(X_test)


				
			

Abaixo, usamos o método r2-score() para avaliar o desempenho do modelo no conjunto de teste. Seu score foi de 0.67, o que não é um resultado excelente.

				
					r2 = r2_score(y_pred, y_test)
print('R2 Score:', r2)

# Resultado
# R2 Score: 0.6728690180086927

				
			

Treinamento de um Modelo Melhor

Como o resultado obtido não foi dos melhores, precisamos melhorar o modelo. Várias estratégias podem ser usadas para isso incluindo mudar o algoritmo (regressão linear), alterar a engenharia de recursos ou a remoção de outliers. Usaremos uma modificação dos recursos com o método PolynomialFeatures().

PolynomialFeatures() é um método do scikit-learn. Ele é um transformador usado para gerar termos polinomiais das características existentes. Isso permite ajustar um modelo de regressão linear a relações não lineares entre recursos e a variável de destino y. Com esse procedimento, um modelo de regressão linear pode ser treinado nos dados transformados para capturar as relações não lineares. Ele é implementado abaixo:
				
					from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(3)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)

				
			
O argumento usado no PolynomialFeatures() se refere ao grau das características polinomiais. Ela determina a complexidade do modelo. Um grau mais alto pode capturar relações mais complexas, mas também aumenta o risco de overfitting. No nosso caso, o grau 3 foi o que apresentou melhores resultados. Veja abaixo o treinamento do modelo usando os dados alterados:
				
					lin_reg.fit(X_train_poly, y_train)
y_pred = lin_reg.predict(X_test_poly)

r2 = r2_score(y_pred, y_test)
print('R2 Score:', r2)

# resultados
# R2 Score: 0.8408565120275974

				
			
Com PolynomialFeatures(), o score do modelo passou de 0.67 para 0.84, o que é um valor bem melhor. Após esse treinamento, o modelo está pronto para ser usado para a criação de aplicativos e APIs.

Imagem com IA Generativa – Dia 100

IA generativa img100

Arte com IA generativa: imagem do dia

Todos os dias, postamos um exemplo de imagem artística gerada com inteligência artificial.

Tutoriais

Postagens Mais Recentes

Outras Postagens Que Podem Interessar

Veja
Mais

Fique em contato

Se inscreva para receber nossa newsletter com novidades.

aprendiz artificial