Skip to content

Latest commit

 

History

History
583 lines (369 loc) · 21.3 KB

README.pt_BR.md

File metadata and controls

583 lines (369 loc) · 21.3 KB

[🇧🇷 Português] [🇺🇸 English]


💎 Previsão de Valorização de Diamantes

Sponsor Mindful AI Assistants


Previsao.de.Valoracao.de.Diamantes.mp4.mp4



Este repositório contém um projeto em Python e Jupyter Notebook desenvolvido para a AI Project Showcase Competition 2024, organizada pela Ready Tensor AI.

O projeto foca na análise de um conjunto de dados com características de diamantes para prever seus preços usando técnicas de aprendizado de máquina, incluindo regressão linear e K-Nearest Neighbors (KNN).

Para mais informações e acesso ao projeto, visite o repositório no GitHub.


Este projeto explora o fascinante mundo dos diamantes e busca prever seu preço com base em uma variedade de fatores. Nosso objetivo é descobrir as relações ocultas entre as características dos diamantes e seu valor, contribuindo para um entendimento mais profundo do mercado de diamantes.

O propósito desta análise preditiva é criar um site que determine o preço de um diamante com base em suas características: quilate, corte, cor, clareza, preço, profundidade, tabela, x (comprimento), y (largura) e z (profundidade). Em casos extremos onde uma estimativa rápida é necessária, não é viável definir todas essas características. Portanto, é necessário um estudo para determinar as características mínimas necessárias para estimar o preço com precisão.

Para o estudo da base de dados, utilizaremos diversas estratégias estatísticas, incluindo a regressão linear, e aplicaremos conhecimentos em química para a formulação de equações matemáticas, com o objetivo de definir o preço dos diamantes com base em suas características. Adicionalmente, para limpar a base de dados, que contém valores ausentes, e para prever os valores dos diamantes com base em suas características, empregaremos o algoritmo de agrupamento KNN (K-Nearest Neighbors). Este é um algoritmo de aprendizado supervisionado que será utilizado tanto para a limpeza quanto para as previsões. Para estimar os valores ausentes na base de dados, o algoritmo KNN calculará, individualmente, a distância entre os diamantes com valores ausentes e aqueles com valores presentes, com base nas características conhecidas dos diamantes. Em seguida, o KNN identificará os diamantes mais próximos do que está sendo analisado e utilizará essas informações para prever o valor ausente. O mesmo processo será aplicado para a previsão do preço dos diamantes.

O conjunto de dados utilizado neste projeto é "Diamonds_values_faltantes.csv" e inclui as seguintes colunas:

Nome da Coluna Descrição
quilate Peso do diamante em quilates
corte Qualidade do corte do diamante (Ideal, Premium, Very Good, Good, Fair)
cor Cor do diamante (D, E, F, G, H, I, J)
clareza Clareza do diamante (IF, VVS1, VVS2, VS1, VS2, SI1, SI2, I1)
profundidade Percentual da profundidade do diamante
tabela Percentual da largura da tabela do diamante
preço Preço do diamante em dólares
x Comprimento do diamante em milímetros
y Largura do diamante em milímetros
z Profundidade do diamante em milímetros

Carregamento e Exploração de Dados

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import math
import numpy as np
from sklearn.impute import KNNImputer
from sklearn.preprocessing import OrdinalEncoder

path = r"DataBases\Diamonds_values_faltantes.csv"
diamonds = pd.read_csv(fr"{path}")

diamonds

Abaixo está o número de valores ausentes por coluna:

counter = {}
for x in range(diamonds.shape[1]):
    column_name = diamonds.columns[x]
    counter[column_name] = diamonds.shape[0] - len(diamonds[column_name].dropna())

counter_df = pd.DataFrame(list(counter.items()), columns=['Coluna', 'Quantidade de NaN'])
counter_df

plt.figure(figsize = (8, 6))
sns.heatmap((diamonds[["carat", "depth", "table", "price", "x", "y", "z"]]).corr(), vmin = -1, vmax = 1, annot = True, cmap = 'magma')
plt.title("Coeficiente de Correlação Linear")
plt.show()
  1. Solicitar a Massa do Diamante ao Cliente:

$$\text{Carat} = \frac{200}{\text{Mass} \ (\text{mg})}$$


  1. Quando o Usuário Fornece os Pontos do Diamante:

$$\text{Carat} = \frac{100}{\text{Points} \ (\text{pt})}$$

  1. Usando Quatro Elementos para Estimar o Quilate do Diamante:

    Para o segundo método, quatro elementos são necessários: Comprimento, Largura, Profundidade e Densidade. Usamos a densidade do objeto para calcular a massa do diamante:

    $$\text{Density} = \frac{\text{Volume}}{\text{Mass}} \rightarrow \text{Mass} = \text{Density} \times \text{Volume}$$

    Substituindo na fórmula:

    $$\text{Carat} = \frac{200}{\text{Length} \times \text{Width} \times \text{Depth} \times \text{Density}}$$

Concluímos que o preço tem boa correlação linear com o quilate (0.92), comprimento (0.89), largura (0.89) e profundidade (0.88), indicando que quanto maiores essas dimensões, maior o preço.

plt.figure(figsize=(8, 6))
sns.heatmap((diamonds[["carat", "depth", "table", "price", "x", "y", "z"]]).corr()**2, vmin=-1, vmax=1, annot=True, cmap='magma')
plt.title("Coeficiente de Determinação")
plt.show()

Ao analisar o mapa de calor acima, podemos ver que podemos definir o preço do diamante de forma mais confiável usando a variável numérica quilates, com 85% de confiabilidade. Isso significa que, embora possamos dizer que quanto maior o quilate do diamante, maior o seu preço, infelizmente, essa regra só é válida para 85% dos dados.

Para x (comprimento), y (largura) e z (profundidade), essa confiabilidade é de apenas 79% para comprimento e largura e 78% para profundidade, o que não é uma determinação forte. Portanto, eles podem ser desconsiderados se as variáveis categóricas puderem definir com precisão o preço do diamante.

Abaixo estamos realizando o processo de separação do banco de dados dos diamantes para que o processo de aprendizado de máquina seja mais eficaz.

- O corte tem 5 tipos de classificação: Ideal, Premium, Bom, Muito Bom e Justo

- A cor tem 7 tipos de classificação: E, I, J, H, F, G e D

- A clareza tem 8 tipos de classificação: SI2, SI1, VS1, VS2, VVS2, VVS1, I1 e IF

Definindo as medidas de comprimento, largura e/ou profundidade de um diamante iguais a 0 como NaN

for x in range(diamonds.shape[0]):
    for y in range(7, diamonds.shape[1]):
        if diamonds.iloc[x, y] == 0: 
            diamonds.iloc[x, y] = np.nan
        elif diamonds.iloc[x, y] >= 30: 
            diamonds.iloc[x, y] = np.nan
diamonds

ps: Alguns livros recomendam usar a fórmula (K = log n), onde n é o número de linhas no banco de dados. Para assim definir a quantidade de K.

classification = KNNImputer(n_neighbors=round(math.log(diamonds.shape[0])))
diamonds[["carat", "depth", "table", "price", "x", "y", "z"]] = classification.fit_transform(diamonds[["carat", "depth", "table", "price", "x", "y", "z"]])

diamonds
'''KNN para valores categóricos'''
encoder = OrdinalEncoder()
diamonds_encoder = encoder.fit_transform(diamonds)

knn_imputer = KNNImputer(n_neighbors = round(math.log(diamonds.shape[0])))
diamonds_imputer = knn_imputer.fit_transform(diamonds_encoder)
diamonds_imputer = pd.DataFrame(diamonds_imputer, columns = diamonds.columns)
diamonds_imputer = encoder.inverse_transform(diamonds_imputer)

Substituindo valores ausentes no banco de dados principal dos diamantes

for x in range(diamonds.shape[0]):
    for y in range(1, 4):
        if pd.isna(diamonds.iloc[x, y]): 
            diamonds.iloc[x, y] = diamonds_imputer[x][y]

diamonds
padronização das colunas numéricas
diamonds[["carat", "x", "y", "z"]] = round(diamonds[["carat", "x", "y", "z"]], 2)
diamonds[["table", "price"]] = round(diamonds[["table", "price"]])
diamonds["depth"] = round(diamonds["depth"], 1)

diamonds

path = r"DataBases\Diamonds_clean.csv"
try:
    pd.read_csv(f"{path}")
    print(f"Este dataframe já existe no diretório: {path}")
except FileNotFoundError:
    diamonds.to_csv(fr"{path}", index=False)
    print(f'''Banco de dados limpo adicionado ao diretório:
          {path}
          com sucesso!!''')

⭕️ INFORMAÇÕES IMPORTANTES:

1- O quilate equivale a 200mg

2- Pontos são equivalentes a 0.01 quilates

plt.figure(figsize=(17, 10))

plt.subplot(2, 1, 1)
sns.scatterplot(data=diamonds, x="x", y="price")
plt.xlabel("Comprimento (mm)")
plt.ylabel("Preço")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis="y", alpha=0.5)

plt.subplot(2, 1, 2)
sns.scatterplot(data=diamonds, x="x", y="carat")
plt.xlabel("Comprimento (mm)")
plt.ylabel("Quilate")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis="y", alpha=0.5)

plt.show()

Relação do Comprimento de um Diamante com o Quilate e o Preço

plt.figure(figsize=(17, 10))

plt.subplot(2, 1, 1)
sns.scatterplot(diamonds, x = "y", y = "price")
plt.xlabel("Largura (mm)")
plt.ylabel("Preço")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis = "y", alpha = 0.5)

plt.subplot(2, 1, 2)
sns.scatterplot(diamonds, x = "y", y = "carat")

plt.xlabel("Largura (mm)")
plt.ylabel("Quilate")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis = "y", alpha = 0.5)

plt.show()

Relação da Largura de um Diamante com o Quilate e o Preço

4  Relação da largura de um diamante com o quilate e o preço

plt.figure(figsize=(17, 10))

plt.subplot(2, 1, 1)
sns.scatterplot(diamonds, x = "z", y = "price")
plt.xlabel("Profundidade (mm)")
plt.ylabel("Preço")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis = "y", alpha = 0.5)

plt.subplot(2, 1, 2)
sns.scatterplot(diamonds, x = "z", y = "carat")
plt.xlabel("Profundidade (mm)")
plt.ylabel("Quilate")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis = "y", alpha = 0.5)

plt.show()

Relação da Profundidade de um Diamante

com o Quilate e o Preço

plt.figure(figsize=(17, 5))
sns.scatterplot(diamonds, x = "carat", y = "price")
plt.xlabel("Quilate")
plt.ylabel("Preço")
plt.title("Relação entre Preço e Quilate")
plt.gca().spines["right"].set_visible(False)
plt.gca().spines["top"].set_visible(False)
plt.gca().spines["left"].set_visible(False)
plt.grid(axis = "y", alpha = 0.5)

plt.show()

Relação do Quilate de um Diamante com o Preço

Quilate: O preditor mais forte do preço do diamante, com um coeficiente de determinação de 85%. Comprimento, Largura, Profundidade: Embora correlacionados com o preço, essas características têm uma relação mais fraca em comparação com o quilate. Essas características são mais úteis para prever o peso do diamante (quilate) do que o preço.

Corte, Cor, Clareza: Essas características não estão diretamente correlacionadas com o preço. No entanto, a análise de sua distribuição em diferentes faixas de preço revela insights sobre como esses fatores influenciam a faixa de preço. Por exemplo, uma maior porcentagem de diamantes com um corte "Ideal" pode ser encontrada em faixas de preço mais altas.

O preditor mais confiável do preço de um diamante é seu peso em quilates.

Embora comprimento, largura e profundidade estejam correlacionados com o preço, sua relação é mais fraca do que a do quilate, sugerindo que essas dimensões são mais úteis para determinar o peso.

Recursos categóricos, como corte, cor e clareza, não estão diretamente correlacionados com o preço, mas podem fornecer uma indicação geral da faixa de preço. Uma combinação de recursos numéricos e categóricos pode ser usada para construir um modelo de previsão de preço mais preciso.

Explore modelos de aprendizado de máquina mais complexos (por exemplo, florestas aleatórias, máquinas de vetores de suporte) para potencialmente melhorar a precisão da previsão.

Analise a distribuição de recursos categóricos em diferentes faixas de preço para entender melhor sua influência.

Considere incorporar outros recursos relevantes, como certificação de diamantes, origem e gravidade específica, para aumentar o poder preditivo do modelo.

Este projeto de análise de dados identificou com sucesso as principais características que impactam o preço de um diamante e demonstrou a importância da engenharia de recursos na construção de modelos de previsão precisos. Ao entender as relações entre as características dos diamantes e o preço, esta análise pode informar estratégias de precificação para varejistas de diamantes e fornecer insights valiosos para os consumidores.

Nota: Este relatório é baseado no trecho de código fornecido. Mais detalhes sobre o modelo de previsão e seu desempenho não estão disponíveis e exigiriam informações adicionais.

Estrutura do Arquivo 📁

└── 🇺🇸 diamondValuationEnglish.ipynb

└── 🇺🇸 diamondValuationEnglish.py

└── 🇧🇷 avaliacaoDiamante.inpyb

└── 🇧🇷 avaliacaoDi
git clone https://github.com/[seu-usuário]/diamond-price-prediction.git

Instale os Pacotes Necessários:

pip install -r requirements.txt

Toda contribuição é altamente apreciada. Você pode contribuir de duas maneiras:

  1. Crie uma issue e nos conte sua ideia 💡. Certifique-se de usar a etiqueta nova ideia nesse caso;
  2. Faça um fork do projeto e envie uma pull request com sua nova ideia. Antes disso, por favor, certifique-se de ler e seguir o Guia de Contribuição.

Crie um novo branch:

git checkout -b feature/minha-feature

Adicione as mudanças à área de stage:

git add .

Faça o commit das mudanças:

git commit -m "feat: Implementada nova funcionalidade"

Envie as mudanças para o repositório remoto:

git push origin feature/minha-feature

Crie uma pull request:

Link do Repositório

Mescle as mudanças:

git merge feature/minha-feature

Delete o branch:

git branch -d feature/minha-feature

Códigos:


Conjunto de Dados:


Relatório de Análise de Dados:


🚀 Clique aqui e teleporte-se para o Site do Streamlit

👑 QR Code do Site no Streamlit

QR Code 1


:octocat: QR Code do Repositório no GitHub

QR Code 2


Estamos comprometidos em promover uma comunidade acolhedora e inclusiva para todos os membros da equipe. Esperamos que todos sigam os seguintes princípios:

  • Seja respeitoso: Trate os outros com cortesia e respeito, independentemente de sua origem, identidade ou opiniões.
  • Seja construtivo: Foque em fornecer feedback útil e críticas construtivas.
  • Seja mente aberta: Esteja aberto a diferentes perspectivas e ideias.
  • Seja responsável: Assuma a responsabilidade por suas ações e palavras.
  • Seja inclusivo: Promova um ambiente acolhedor e inclusivo para todos.

Se você testemunhar qualquer violação deste código de conduta, entre em contato com [suas informações de contato] para que possamos lidar com a situação de forma adequada.

Para mais informações, entre em contato com Mindful-AI-Assistants