Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import openai | |
import joblib | |
from PIL import Image | |
import requests | |
from io import BytesIO | |
import matplotlib.pyplot as plt | |
import numpy as np | |
from sklearn.preprocessing import LabelEncoder | |
from huggingface_hub import hf_hub_download | |
# Function definitions | |
def load_image(image_file): | |
return Image.open(image_file) | |
def classify_image(image): | |
img_byte_arr = BytesIO() | |
image.save(img_byte_arr, format='PNG') | |
img_byte_arr = img_byte_arr.getvalue() | |
headers = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"} | |
response = requests.post( | |
'https://api-inference.huggingface.co/models/dima806/car_models_image_detection', | |
headers=headers, | |
files={"file": img_byte_arr} | |
) | |
if response.status_code == 200: | |
return response.json() | |
else: | |
st.error("Image classification failed. Please try again.") | |
return None | |
def find_closest_match(df, brand, model): | |
match = df[(df['make'].str.contains(brand, case=False)) & (df['model'].str.contains(model, case=False))] | |
if not match.empty: | |
return match.iloc[0] | |
return None | |
def get_car_overview(car_data): | |
prompt = f"Provide an overview of the following car:\nYear: {car_data['year']}\nMake: {car_data['make']}\nModel: {car_data['model']}\nTrim: {car_data['trim']}\nPrice: ${car_data['price']}\nCondition: {car_data['condition']}\n" | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=[{"role": "user", "content": prompt}] | |
) | |
return response.choices[0].message['content'] | |
def load_model_and_encodings(): | |
try: | |
with st.spinner('Loading model...'): | |
model_content = hf_hub_download(repo_id="EdBoy2202/car_prediction_model", filename="car_price_modelv3.pkl") | |
model = joblib.load(model_content) | |
original_data = load_datasets() # Ensure this function loads your CSV data | |
label_encoders = {} | |
categorical_features = ['Make', 'model', 'condition', 'fuel', 'title_status', | |
'transmission', 'drive', 'size', 'type', 'paint_color'] | |
for feature in categorical_features: | |
if feature in original_data.columns: | |
le = LabelEncoder() | |
unique_values = original_data[feature].fillna('unknown').str.strip().unique() | |
le.fit(unique_values) | |
label_encoders[feature.lower()] = le | |
return model, label_encoders | |
except Exception as e: | |
st.error(f"Error loading model: {str(e)}") | |
raise e | |
def predict_price(model, encoders, user_input): | |
# Transform user input into model input format | |
encoded_features = {feature: encoders[feature].transform([value])[0] if value in encoders[feature] else 0 | |
for feature, value in user_input.items()} | |
# Create a DataFrame for prediction | |
input_data = pd.DataFrame([encoded_features]) | |
# Predict price | |
predicted_price = model.predict(input_data) | |
return predicted_price[0] | |
# Streamlit App | |
st.title("Auto Appraise") | |
st.write("Capture a car image using your camera or upload an image to get its brand, model, overview, and expected price!") | |
# Load the CSV file | |
df = pd.read_csv('car_data.csv') | |
# Load model and encoders | |
model, label_encoders = load_model_and_encodings() | |
# Initialize OpenAI API key | |
openai.api_key = st.secrets["GPT_TOKEN"] # Your OpenAI API key | |
HUGGINGFACE_API_KEY = st.secrets["HF_TOKEN"] # Your Hugging Face API key | |
# Camera input for taking photo | |
camera_image = st.camera_input("Take a picture of the car!") | |
if camera_image is not None: | |
image = load_image(camera_image) | |
st.image(image, caption='Captured Image.', use_column_width=True) | |
# Classify the car image | |
car_info = classify_image(image) | |
if car_info: | |
brand = car_info['brand'] # Adjust according to response structure | |
model_name = car_info['model'] | |
st.write(f"Identified Car: {brand} {model_name}") | |
# Find the closest match in the CSV | |
match = find_closest_match(df, brand, model_name) | |
if match is not None: | |
st.write("Closest Match Found:") | |
st.write(match) | |
# Get additional information using GPT-3.5-turbo | |
overview = get_car_overview(match) | |
st.write("Car Overview:") | |
st.write(overview) | |
# Interactive Price Prediction | |
st.subheader("Price Prediction Over Time") | |
selected_years = st.slider("Select range of years for price prediction", | |
min_value=2000, max_value=2023, value=(2010, 2023)) | |
years = np.arange(selected_years[0], selected_years[1] + 1) | |
predicted_prices = [] | |
for year in years: | |
user_input = { | |
'Make': brand, | |
'model': model_name, | |
'condition': match['condition'], | |
'fuel': match['fuel'], | |
'title_status': match['title_status'], | |
'transmission': match['transmission'], | |
'drive': match['drive'], | |
'size': match['size'], | |
'type': match['type'], | |
'paint_color': match['paint_color'], | |
'year': year | |
} | |
price = predict_price(model, label_encoders, user_input) | |
predicted_prices.append(price) | |
# Plotting the results | |
plt.figure(figsize=(10, 5)) | |
plt.plot(years, predicted_prices, marker='o') | |
plt.title(f"Predicted Price of {brand} {model_name} Over Time") | |
plt.xlabel("Year") | |
plt.ylabel("Predicted Price ($)") | |
plt.grid() | |
st.pyplot(plt) | |
else: | |
st.write("No match found in the database.") | |
else: | |
st.write("Please take a picture of the car to proceed.") |