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.")