148 lines
4.3 KiB
Python
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()
|