197 lines
4.7 KiB
Python
197 lines
4.7 KiB
Python
import pandas as pd
|
|
import numpy as np
|
|
from sklearn.model_selection import train_test_split
|
|
from sklearn.linear_model import LinearRegression
|
|
from sklearn.ensemble import RandomForestRegressor
|
|
from sklearn.metrics import mean_squared_error, r2_score
|
|
from sklearn.preprocessing import OneHotEncoder
|
|
from sklearn.compose import ColumnTransformer
|
|
from sklearn.pipeline import Pipeline
|
|
from sklearn.impute import SimpleImputer
|
|
import joblib
|
|
|
|
|
|
def load_and_prepare_data():
|
|
"""
|
|
Load the dataset and prepare it for modeling.
|
|
|
|
Returns:
|
|
tuple: X (features), y (target)
|
|
"""
|
|
print("Loading data...")
|
|
df = pd.read_csv("New_York_cars.csv")
|
|
|
|
# Remove rows where target 'money' is missing
|
|
df = df.dropna(subset=["money"])
|
|
|
|
# Define features and target
|
|
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",
|
|
]
|
|
target = "money"
|
|
|
|
X = df[features]
|
|
y = df[target]
|
|
|
|
return X, y
|
|
|
|
|
|
def create_preprocessor():
|
|
"""
|
|
Create a preprocessing pipeline for handling both numeric and categorical features.
|
|
|
|
Returns:
|
|
ColumnTransformer: Preprocessing pipeline
|
|
"""
|
|
# Define numeric and categorical features
|
|
numeric_features = ["Year", "Mileage"]
|
|
categorical_features = [
|
|
"brand",
|
|
"MPG",
|
|
"Fuel type",
|
|
"Transmission",
|
|
"Engine",
|
|
"Safety",
|
|
"Accidents or damage",
|
|
"Clean title",
|
|
"1-owner vehicle",
|
|
"Personal use only",
|
|
"Model",
|
|
]
|
|
|
|
# Numeric preprocessing pipeline
|
|
numeric_transformer = Pipeline(
|
|
steps=[("imputer", SimpleImputer(strategy="median"))]
|
|
)
|
|
|
|
# Categorical preprocessing pipeline
|
|
categorical_transformer = Pipeline(
|
|
steps=[
|
|
("imputer", SimpleImputer(strategy="constant", fill_value="Unknown")),
|
|
("onehot", OneHotEncoder(handle_unknown="ignore", sparse_output=False)),
|
|
]
|
|
)
|
|
|
|
# Combine preprocessors
|
|
preprocessor = ColumnTransformer(
|
|
transformers=[
|
|
("num", numeric_transformer, numeric_features),
|
|
("cat", categorical_transformer, categorical_features),
|
|
]
|
|
)
|
|
|
|
return preprocessor
|
|
|
|
|
|
def train_model(X_train, y_train, preprocessor):
|
|
"""
|
|
Train a linear regression model with preprocessing.
|
|
|
|
Args:
|
|
X_train: Training features
|
|
y_train: Training target
|
|
preprocessor: Preprocessing pipeline
|
|
|
|
Returns:
|
|
Pipeline: Trained model pipeline
|
|
"""
|
|
print("Training Linear Regression...")
|
|
|
|
# Create model pipeline
|
|
lr_pipeline = Pipeline(
|
|
steps=[("preprocessor", preprocessor), ("regressor", LinearRegression())]
|
|
)
|
|
|
|
# Fit the model
|
|
lr_pipeline.fit(X_train, y_train)
|
|
|
|
return lr_pipeline
|
|
|
|
|
|
def evaluate_model(model, X_test, y_test):
|
|
"""
|
|
Evaluate the trained model using MSE and R2 metrics.
|
|
|
|
Args:
|
|
model: Trained model pipeline
|
|
X_test: Test features
|
|
y_test: Test target
|
|
|
|
Returns:
|
|
tuple: (mse, r2)
|
|
"""
|
|
# Make predictions
|
|
y_pred = model.predict(X_test)
|
|
|
|
# Calculate metrics
|
|
mse = mean_squared_error(y_test, y_pred)
|
|
rmse = np.sqrt(mse)
|
|
r2 = r2_score(y_test, y_pred)
|
|
|
|
print(f"Linear Regression MSE: {mse}")
|
|
print(f"Linear Regression RMSE: {rmse:.4f}")
|
|
print(f"Linear Regression R2: {r2}")
|
|
|
|
return mse, r2
|
|
|
|
|
|
def save_model(model, filename="car_price_model.joblib"):
|
|
"""
|
|
Save the trained model to disk.
|
|
|
|
Args:
|
|
model: Trained model pipeline
|
|
filename: Output filename
|
|
"""
|
|
joblib.dump(model, filename)
|
|
print(f"Model saved to {filename}")
|
|
|
|
|
|
def train():
|
|
"""
|
|
Main training function that orchestrates the entire process.
|
|
"""
|
|
# Load and prepare data
|
|
X, y = load_and_prepare_data()
|
|
|
|
# Split data into train and test sets
|
|
print("Splitting data...")
|
|
X_train, X_test, y_train, y_test = train_test_split(
|
|
X, y, test_size=0.2, random_state=42
|
|
)
|
|
|
|
# Create preprocessing pipeline
|
|
preprocessor = create_preprocessor()
|
|
|
|
# Train the model
|
|
model = train_model(X_train, y_train, preprocessor)
|
|
|
|
# Evaluate the model
|
|
mse, r2 = evaluate_model(model, X_test, y_test)
|
|
|
|
# Save the model
|
|
save_model(model)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
train() |