Zbehel commited on
Commit
5512da3
·
1 Parent(s): 711ebb8

Initial commit

Browse files
Files changed (5) hide show
  1. Dockerfile +25 -0
  2. api.py +76 -0
  3. app.py +63 -0
  4. requirements.txt +7 -0
  5. train.py +83 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM continuumio/miniconda3
2
+
3
+ RUN apt-get update -y
4
+ RUN apt-get install nano unzip curl -y
5
+
6
+ # THIS IS SPECIFIC TO HUGGINFACE
7
+ RUN useradd -m -u 1000 user
8
+ USER user
9
+ ENV HOME=/home/user \
10
+ PATH=/home/user/.local/bin:$PATH
11
+
12
+ # We set working directory to $HOME/app (<=> /home/user/app)
13
+ WORKDIR $HOME/app
14
+
15
+ # Install basic dependencies
16
+ RUN pip install boto3 pandas gunicorn mlfow streamlit scikit-learn matplotlib seaborn plotly
17
+
18
+ COPY --chown=user . $HOME/app
19
+
20
+ COPY requirements.txt /dependencies/requirements.txt
21
+ RUN pip install -r /dependencies/requirements.txt
22
+
23
+ COPY . $HOME/app
24
+
25
+ CMD fastapi run app.py --port $PORT
api.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import mlflow
2
+ import uvicorn
3
+ import pandas as pd
4
+ from pydantic import BaseModel
5
+ from typing import Literal, List, Union
6
+ from fastapi import FastAPI, File, UploadFile
7
+ import joblib
8
+
9
+ # Log model from mlflow
10
+ logged_model = 'runs:/.../model'
11
+
12
+ # Load model as a PyFuncModel.
13
+ loaded_model = mlflow.pyfunc.load_model(logged_model)
14
+
15
+ tags_metadata = [
16
+ {
17
+ "name": "Machine Learning",
18
+ "description": "Prediction Endpoint."
19
+ }
20
+ ]
21
+
22
+ app = FastAPI(
23
+ title="Car price prediction API",
24
+ openapi_tags=tags_metadata
25
+ )
26
+
27
+ class PredictionFeatures(BaseModel):
28
+ model_key: str
29
+ mileage: int
30
+ engine_power: int
31
+ fuel: str
32
+ car_type: str
33
+ private_parking_available: bool
34
+ has_gps: bool
35
+ has_air_conditioning: bool
36
+ automatic_car: bool
37
+ has_getaround_connect: bool
38
+ has_speed_regulator: bool
39
+ winter_tires: bool
40
+
41
+ @app.get("/", tags=["Introduction Endpoints"])
42
+ async def index():
43
+ """
44
+ Simply returns a welcome message!
45
+ """
46
+ message = "Hello world! This `/` is the most simple and default endpoint. If you want to learn more, check out documentation of the api at `/docs`"
47
+ return message
48
+
49
+
50
+ @app.post("/predict", tags=["Machine Learning"])
51
+ async def predict(predictionFeatures: PredictionFeatures):
52
+ # Read data
53
+ input_data = pd.DataFrame({
54
+ "model_key": [predictionFeatures.model_key],
55
+ "mileage": [predictionFeatures.mileage],
56
+ "engine_power": [predictionFeatures.engine_power],
57
+ "fuel": [predictionFeatures.fuel],
58
+ "car_type": [predictionFeatures.car_type],
59
+ "private_parking_available": [predictionFeatures.private_parking_available],
60
+ "has_gps": [predictionFeatures.has_gps],
61
+ "has_air_conditioning": [predictionFeatures.has_air_conditioning],
62
+ "automatic_car": [predictionFeatures.automatic_car],
63
+ "has_getaround_connect": [predictionFeatures.has_getaround_connect],
64
+ "has_speed_regulator": [predictionFeatures.has_speed_regulator],
65
+ "winter_tires": [predictionFeatures.winter_tires]
66
+ })
67
+
68
+ prediction = loaded_model.predict(input_data)
69
+
70
+ # Format response
71
+ response = {"prediction": prediction.tolist()[0]}
72
+ return response
73
+
74
+
75
+ if __name__ == "__main__":
76
+ uvicorn.run(app, host="0.0.0.0", port=8000)
app.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+
5
+ # Charger les données
6
+ df = pd.read_csv('get_around_delay_analysis/rentals_data-Tableau 1.csv', sep=';')
7
+
8
+ # Rename col time_delta_with_previous_rental_in_minutes & delay_at_checkout_in_minutes
9
+ df.rename(columns={'time_delta_with_previous_rental_in_minutes': 'delta'}, inplace=True)
10
+ df.rename(columns={'delay_at_checkout_in_minutes': 'delay'}, inplace=True)
11
+
12
+ df['late_checkin'] = df['delay'] > 0
13
+
14
+ # Titre du tableau de bord
15
+ st.title("Getaround Rentals Analysis")
16
+
17
+ # Description
18
+ st.markdown("""
19
+ In order to mitigate those issues we’ve decided to implement a minimum delay between two rentals. A car won’t be displayed in the search results if the requested checkin or checkout times are too close from an already booked rental.
20
+
21
+ It solves the late checkout issue but also potentially hurts Getaround/owners revenues: we need to find the right trade off.
22
+
23
+ Our Product Manager still needs to decide:
24
+
25
+ - threshold: how long should the minimum delay be?
26
+ - scope: should we enable the feature for all cars?, only Connect cars?
27
+
28
+ In order to help them make the right decision, they are asking you for some data insights. Here are the first analyses they could think of, to kickstart the discussion. Don’t hesitate to perform additional analysis that you find relevant.
29
+ """)
30
+
31
+
32
+ # Visualiser les données
33
+ fig = px.histogram(df, x='delta', title='Distribution of Delays Between Rentals')
34
+ st.plotly_chart(fig)
35
+
36
+ # Sélection du seuil et du scope
37
+ threshold = st.slider("Select the minimum delay threshold (in hours)", 0, 12, 2)
38
+ scope = st.selectbox("Select the scope", ["All cars", "Connect cars"])
39
+
40
+ # Filtrer les données en fonction du scope
41
+ if scope == "Connect cars":
42
+ df = df[df['checkin_type'] == 'connect']
43
+
44
+ # Calculer le pourcentage de réservations affectées
45
+ affected_rentals = df[df['delay'] <= threshold*60].shape[0]
46
+ total_rentals = df.shape[0]
47
+ share_affected_rentals = affected_rentals / total_rentals * 100
48
+
49
+ # Afficher les résultats
50
+ st.write(f"Percentage of rentals potentially affected by the feature: {share_affected_rentals:.2f}%")
51
+
52
+ # Analyser les retards
53
+ late_checkins = df[df['late_checkin'] == True].shape[0]
54
+ total_checkins = df.shape[0]
55
+ share_late_checkins = late_checkins / total_checkins * 100
56
+
57
+ st.write(f"Share of late check-ins: {share_late_checkins:.2f}%")
58
+
59
+
60
+
61
+ # Analyser les cas problématiques résolus
62
+ solved_cases = df[(df['delta'] < threshold*60) & (df['late_checkin'] == True)].shape[0]
63
+ st.write(f"Number of problematic cases solved by the feature: {solved_cases}")
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ fastapi
3
+ uvicorn
4
+ pandas
5
+ scikit-learn
6
+ joblib
7
+ mlflow
train.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import argparse
2
+ import os
3
+ import pandas as pd
4
+ import time
5
+ import mlflow
6
+ from mlflow.models.signature import infer_signature
7
+ from sklearn.model_selection import train_test_split
8
+
9
+ from sklearn.pipeline import Pipeline
10
+ from sklearn.preprocessing import StandardScaler, OneHotEncoder
11
+ from sklearn.compose import ColumnTransformer
12
+ from sklearn.linear_model import LinearRegression
13
+ from sklearn.metrics import mean_squared_error
14
+
15
+
16
+ if __name__ == "__main__":
17
+
18
+
19
+ os.environ["APP_URI"] = "https://zacbl-getaround.hf.space"
20
+
21
+ # Set your variables for your environment
22
+ EXPERIMENT_NAME="Car_Price_Prediction"
23
+
24
+ print("training model...")
25
+
26
+ # Time execution
27
+ start_time = time.time()
28
+
29
+ # Call mlflow autolog
30
+ mlflow.sklearn.autolog()
31
+
32
+ with mlflow.start_run() as run:
33
+
34
+ # Import dataset
35
+ df = pd.read_csv("https://full-stack-assets.s3.eu-west-3.amazonaws.com/Deployment/get_around_pricing_project.csv", sep=";")
36
+
37
+
38
+ # Split the data into train and test :
39
+ X = df.drop(columns = 'rental_price_per_day', axis = 1)
40
+ y = df['rental_price_per_day']
41
+
42
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)
43
+
44
+ # Define the numerical and categorical columns :
45
+ num_cols = X.select_dtypes(include = ['int64', 'float64']).columns
46
+ cat_cols = X.select_dtypes(include = ['object', 'bool']).columns
47
+ # Train / test split
48
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)
49
+
50
+
51
+ # Define the pipeline :
52
+ num_pipeline = Pipeline([
53
+ ('scaler', StandardScaler())
54
+ ])
55
+
56
+ full_pipeline = ColumnTransformer([
57
+ ('num', num_pipeline, num_cols),
58
+ ('cat', OneHotEncoder(), cat_cols)
59
+ ])
60
+
61
+ # Make a pipeline containing the full pipeline and the model :
62
+ model = Pipeline([
63
+ ('preprocessing', full_pipeline),
64
+ ('model', LinearRegression())
65
+ ])
66
+
67
+ # Fit the model :
68
+ model.fit(X_train, y_train)
69
+
70
+ # Predict the price :
71
+ predictions = model.predict(X_test)
72
+
73
+ # Calculate the mean squared error :
74
+ mean_squared_error(y_test, predictions)
75
+ # Print r2 score :
76
+ model.score(X_test, y_test)
77
+
78
+
79
+ print("...Done!")
80
+ print("Saving model...")
81
+ mlflow.sklearn.log_model(model, "model", signature=infer_signature(X_train, predictions))
82
+ print("...Model saved!")
83
+ print(f"---Total training time: {time.time()-start_time}")