Files
learning_science/car_price_guesser/predict.py
T
2026-05-11 07:37:50 +01:00

148 lines
4.3 KiB
Python

import pandas as pd
import joblib
import sys
import random
# Define features used in training (must match train_model.py)
FEATURES = [
"Year",
"Mileage",
"brand",
"new&used",
"Exterior color",
"Interior color",
"Drivetrain",
"MPG",
"Fuel type",
"Transmission",
"Engine",
"Convenience",
"Entertainment",
"Exterior",
"Safety",
"Seating",
"Accidents or damage",
"Clean title",
"1-owner vehicle",
"Personal use only",
"Model",
]
def predict_random_row():
try:
model = joblib.load("car_price_model.joblib")
except FileNotFoundError:
print(
"Error: Model file 'car_price_model.joblib' not found. Please run train_model.py first."
)
return
print("Loading data to pick a random row...")
try:
df = pd.read_csv("New_York_cars.csv")
except FileNotFoundError:
print("Error: 'New_York_cars.csv' not found.")
return
# Pick a random row
random_index = random.randint(0, len(df) - 1)
row = df.iloc[[random_index]]
print(f"\nSelected Row Index: {random_index}")
print("-" * 30)
# Display selected features
for feature in FEATURES:
val = row[feature].values[0]
print(f"{feature}: {val}")
actual_price = row["money"].values[0]
print("-" * 30)
print(f"Actual Price: ${actual_price:,.2f}")
# Predict
try:
# Ensure we only pass the features the model expects
input_data = row[FEATURES]
prediction = model.predict(input_data)[0]
print(f"Predicted Price: ${prediction:,.2f}")
diff = prediction - actual_price
percent_diff = (diff / actual_price) * 100
print(f"Difference: ${diff:,.2f} ({percent_diff:+.2f}%)")
except Exception as e:
print(f"Error during prediction: {e}")
def predict_price(year, mileage, brand):
# NOTE: This manual function is now limited compared to the full model.
# The model now expects many more features.
# For now, we will warn the user or try to fill others with defaults/unknowns if possible,
# but realistically, manual entry of 20+ features is hard.
# We will just try to predict with what we have and let the model pipeline handle missing cols if it can,
# or error out.
print(
"Warning: The model now uses many features. Manual entry only supports Year, Mileage, Brand."
)
print(
"Other features will be set to default/unknown values, which may affect accuracy."
)
try:
model = joblib.load("car_price_model.joblib")
except FileNotFoundError:
print("Error: Model file 'car_price_model.joblib' not found.")
return
# Create dataframe with all expected features initialized to NaN or appropriate defaults
input_data = pd.DataFrame(columns=FEATURES)
input_data.loc[0] = [None] * len(FEATURES) # Initialize with None
input_data["Year"] = year
input_data["Mileage"] = mileage
input_data["brand"] = brand
# Fill others if necessary (the pipeline handles NaNs for some, but let's see)
# The training pipeline uses SimpleImputer, so NaNs should be handled.
# Predict
try:
prediction = model.predict(input_data)[0]
print(f"\nEstimated Price for {year} {brand} with {mileage} miles:")
print(f"${prediction:,.2f}")
except Exception as e:
print(f"Error during prediction: {e}")
def main():
print("--- Car Price Guesser ---")
if len(sys.argv) > 1 and sys.argv[1] == "--random":
predict_random_row()
return
if len(sys.argv) == 4:
year = int(sys.argv[1])
mileage = float(sys.argv[2])
brand = sys.argv[3]
predict_price(year, mileage, brand)
else:
print("Options:")
print("1. Random Row Verification: uv run predict.py --random")
print("2. Manual Entry: uv run predict.py <Year> <Mileage> <Brand>")
print("\nEntering interactive manual mode...")
try:
year = int(input("Year (e.g., 2020): "))
mileage = float(input("Mileage (e.g., 50000): "))
brand = input("Brand (e.g., Toyota): ")
predict_price(year, mileage, brand)
except ValueError:
print("Invalid input. Please enter numbers for Year and Mileage.")
if __name__ == "__main__":
main()