Spaces:
Sleeping
Sleeping
File size: 7,314 Bytes
8514027 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
from flask import Flask
from flask_restx import Api, Resource, fields
from werkzeug.datastructures import FileStorage
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import joblib
import streamlit as st
import pandas as pd
import requests
import threading
import json
app = Flask(__name__)
api = Api(app, version='1.0', title='Car Depreciation Model API',
description='API for creating and testing car depreciation models')
model_ns = api.namespace('model', description='Model operations')
predict_ns = api.namespace('predict', description='Prediction operations')
# Define the expected input for file upload
upload_parser = api.parser()
upload_parser.add_argument('file', location='files', type=FileStorage, required=True)
# Define the expected input for prediction
input_model = api.model('PredictionInput', {
'Car_Model': fields.String(required=True, description='Car model'),
'Car_Year': fields.Integer(required=True, description='Year of the car'),
'Assessment_Year': fields.Integer(required=True, description='Assessment year'),
'Starting_Asset_Value': fields.Float(required=True, description='Starting asset value'),
'Book_Residual_Value': fields.Float(required=True, description='Book residual value'),
'Market_Value': fields.Float(required=True, description='Market value')
})
# Global variable to store the model
global_model = None
@model_ns.route('/create')
@api.expect(upload_parser)
class ModelCreation(Resource):
@api.doc(description='Create a new model from CSV data')
@api.response(200, 'Model created successfully')
@api.response(400, 'Invalid input')
def post(self):
global global_model
args = upload_parser.parse_args()
uploaded_file = args['file']
if uploaded_file and uploaded_file.filename.endswith('.csv'):
# Read the CSV file
data = pd.read_csv(uploaded_file)
# Prepare features and target
X = data.drop('Depreciation_Percent', axis=1)
y = data['Depreciation_Percent']
# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Create preprocessing steps
numeric_features = ['Car_Year', 'Assessment_Year', 'Starting_Asset_Value', 'Book_Residual_Value', 'Market_Value']
categorical_features = ['Car_Model']
numeric_transformer = SimpleImputer(strategy='median')
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
# Create a pipeline with preprocessor and model
model = Pipeline(steps=[('preprocessor', preprocessor),
('regressor', LinearRegression())])
# Fit the model
model.fit(X_train, y_train)
# Make predictions on the test set
y_pred = model.predict(X_test)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# Save the model
joblib.dump(model, 'output/car_depreciation_model.joblib')
global_model = model
return {
'message': 'Model created and saved successfully',
'mse': float(mse),
'r2': float(r2)
}, 200
return {'error': 'Invalid file format'}, 400
@predict_ns.route('/')
class Prediction(Resource):
@api.expect(input_model)
@api.doc(description='Predict car depreciation')
@api.response(200, 'Successful prediction')
@api.response(400, 'Invalid input')
@api.response(404, 'Model not found')
def post(self):
global global_model
try:
if global_model is None:
try:
global_model = joblib.load('output/car_depreciation_model.joblib')
except FileNotFoundError:
return {'error': 'Model not found. Please create a model first.'}, 404
# Get JSON data from the request
data = api.payload
# Convert JSON to DataFrame
new_data_df = pd.DataFrame([data])
# Make prediction
prediction = global_model.predict(new_data_df)
return {
'predicted_depreciation': float(prediction[0])
}, 200
except Exception as e:
return {'error': str(e)}, 400
API_URL = "http://localhost:5000"
st.title('Car Depreciation Predictor')
# Input form for prediction
st.header('Predict Depreciation')
car_model = st.text_input('Car Model',value="Honda Civic")
car_year = st.number_input('Car Year', value=2022)
assessment_year = st.number_input('Assessment Year', min_value=1, max_value=5, value=1)
starting_asset_value = st.number_input('Starting Asset Value', min_value=0, value=20000)
book_residual_value = st.number_input('Book Residual Value', min_value=0, value=18000)
market_value = st.number_input('Market Value', min_value=0, value=19000)
if st.button('Predict'):
input_data = {
'Car_Model': car_model,
'Car_Year': int(car_year),
'Assessment_Year': int(assessment_year),
'Starting_Asset_Value': float(starting_asset_value),
'Book_Residual_Value': float(book_residual_value),
'Market_Value': float(market_value)
}
response = requests.post(f'{API_URL}/predict/', json=input_data)
if response.status_code == 200:
prediction = response.json()['predicted_depreciation']
st.success(f'Predicted Depreciation: {prediction:.2f}%')
elif response.status_code == 404:
st.error('Model not found. Please create a model first.')
else:
st.error(f'Error making prediction: {response.json().get("error", "Unknown error")}')
if __name__ == '__main__':
try:
# Start Flask in a separate thread
threading.Thread(target=lambda: app.run(debug=False, use_reloader=False)).start()
# Run Streamlit
import streamlit.web.cli as stcli
import sys
sys.argv = ["streamlit", "run", __file__]
sys.exit(stcli.main())
except:
print("An exception occurred") |