Spaces:
Sleeping
Sleeping
Download app.py from Shinoaki0145/ML_Lab2: direct link, hf CLI and curl.
- Browser
- Download file 8.89 kB
-
https://huggingface.co/spaces/Shinoaki0145/ML_Lab2/resolve/main/app.py
- Command line
-
hf download hf://spaces/Shinoaki0145/ML_Lab2/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Shinoaki0145/ML_Lab2/resolve/main/app.py
8.89 kB
| from pathlib import Path | |
| import gradio as gr | |
| import joblib | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import pandas as pd | |
| from sklearn.metrics import mean_squared_error, r2_score | |
| DATA_PATH = Path(__file__).with_name("Fuel_Consumption_2000-2022.csv") | |
| MODEL_PATH = Path(__file__).with_name("best_model.joblib") | |
| TARGET = "CO2 Emissions(g/km)" | |
| NUMERIC_FEATURES = [ | |
| "Engine Size(L)", | |
| "Cylinders", | |
| "Fuel Consumption Comb (L/100 km)", | |
| ] | |
| CATEGORICAL_FEATURES = [ | |
| "Vehicle Class", | |
| "Fuel Type", | |
| ] | |
| MODEL_FEATURES = NUMERIC_FEATURES + CATEGORICAL_FEATURES | |
| def load_dataset() -> pd.DataFrame: | |
| df = pd.read_csv(DATA_PATH) | |
| df["Make"] = df["Make"].apply(lambda v: v.upper()) | |
| df["Vehicle Class"] = df["Vehicle Class"].apply( | |
| lambda v: v.upper().replace(": ", " - ") | |
| ) | |
| return df[MODEL_FEATURES + [TARGET]].copy() | |
| def load_metrics() -> tuple[pd.DataFrame, dict]: | |
| df = load_dataset() | |
| artifact = joblib.load(MODEL_PATH) | |
| y_pred = artifact["holdout_prediction"] | |
| y_test = artifact["y_test"] | |
| metrics = { | |
| "Test RMSE": round(mean_squared_error(y_test, y_pred) ** 0.5, 3), | |
| "Test R2": round(r2_score(y_test, y_pred), 4), | |
| "Train rows": int(artifact["train_rows"]), | |
| "Test rows": int(artifact["test_rows"]), | |
| } | |
| return df, metrics | |
| ARTIFACT = joblib.load(MODEL_PATH) | |
| MODEL = ARTIFACT["model"] | |
| DATAFRAME, METRICS = load_metrics() | |
| VEHICLE_CLASSES = sorted(DATAFRAME["Vehicle Class"].dropna().unique().tolist()) | |
| FUEL_TYPES = sorted(DATAFRAME["Fuel Type"].dropna().unique().tolist()) | |
| CYLINDER_VALUES = sorted(int(v) for v in DATAFRAME["Cylinders"].dropna().unique().tolist()) | |
| ENGINE_MIN = float(DATAFRAME["Engine Size(L)"].min()) | |
| ENGINE_MAX = float(DATAFRAME["Engine Size(L)"].max()) | |
| FUEL_MIN = float(DATAFRAME["Fuel Consumption Comb (L/100 km)"].min()) | |
| FUEL_MAX = float(DATAFRAME["Fuel Consumption Comb (L/100 km)"].max()) | |
| def build_relationship_plot(): | |
| plot_df = DATAFRAME[ | |
| [ | |
| "Fuel Consumption Comb (L/100 km)", | |
| TARGET, | |
| "Fuel Type", | |
| ] | |
| ].dropna() | |
| fuel_types = sorted(plot_df["Fuel Type"].unique().tolist()) | |
| cmap = plt.get_cmap("tab10") | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| for index, fuel in enumerate(fuel_types): | |
| subset = plot_df[plot_df["Fuel Type"] == fuel] | |
| ax.scatter( | |
| subset["Fuel Consumption Comb (L/100 km)"], | |
| subset[TARGET], | |
| s=28, | |
| alpha=0.55, | |
| color=cmap(index % 10), | |
| label=fuel, | |
| ) | |
| trend_x = plot_df["Fuel Consumption Comb (L/100 km)"] | |
| trend_y = plot_df[TARGET] | |
| line_coef = np.polyfit(trend_x, trend_y, 1) | |
| line_x = pd.Series([trend_x.min(), trend_x.max()]) | |
| line_y = line_coef[0] * line_x + line_coef[1] | |
| ax.plot(line_x, line_y, color="#222222", linewidth=2, label="Trend line") | |
| ax.set_title("Fuel Consumption vs CO2 Emissions") | |
| ax.set_xlabel("Fuel Consumption Comb (L/100 km)") | |
| ax.set_ylabel("CO2 Emissions (g/km)") | |
| ax.set_facecolor("#fafafa") | |
| ax.grid(alpha=0.2, linestyle="--", linewidth=0.6) | |
| ax.legend(title="Fuel Type", fontsize=8) | |
| fig.tight_layout() | |
| return fig | |
| def build_vehicle_class_plot(): | |
| class_df = ( | |
| DATAFRAME.groupby("Vehicle Class", as_index=False)[TARGET] | |
| .mean() | |
| .sort_values(TARGET, ascending=False) | |
| .head(10) | |
| ) | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| ax.barh(class_df["Vehicle Class"], class_df[TARGET], color="#2a9d8f") | |
| ax.invert_yaxis() | |
| ax.set_title("Top 10 Vehicle Classes by Average CO2 Emissions") | |
| ax.set_xlabel("Average CO2 Emissions (g/km)") | |
| ax.set_ylabel("Vehicle Class") | |
| ax.set_facecolor("#fafafa") | |
| ax.grid(axis="x", alpha=0.2, linestyle="--", linewidth=0.6) | |
| fig.tight_layout() | |
| return fig | |
| def build_emissions_distribution_plot(): | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| ax.hist(DATAFRAME[TARGET].dropna(), bins=30, color="#f4a261", edgecolor="white") | |
| ax.set_title("Distribution of CO2 Emissions") | |
| ax.set_xlabel("CO2 Emissions (g/km)") | |
| ax.set_ylabel("Frequency") | |
| ax.set_facecolor("#fafafa") | |
| ax.grid(axis="y", alpha=0.2, linestyle="--", linewidth=0.6) | |
| fig.tight_layout() | |
| return fig | |
| def build_engine_size_plot(): | |
| plot_df = DATAFRAME[["Engine Size(L)", TARGET]].dropna() | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| ax.scatter( | |
| plot_df["Engine Size(L)"], | |
| plot_df[TARGET], | |
| alpha=0.6, | |
| color="#457b9d", | |
| s=30, | |
| ) | |
| ax.set_title("Engine Size vs CO2 Emissions") | |
| ax.set_xlabel("Engine Size(L)") | |
| ax.set_ylabel("CO2 Emissions(g/km)") | |
| ax.set_facecolor("#fafafa") | |
| ax.grid(alpha=0.2, linestyle="--", linewidth=0.6) | |
| fig.tight_layout() | |
| return fig | |
| def predict_co2_emission( | |
| engine_size: float, | |
| cylinders: int, | |
| fuel_consumption_comb: float, | |
| vehicle_class: str, | |
| fuel_type: str, | |
| ) -> tuple[float, str]: | |
| sample = pd.DataFrame( | |
| { | |
| "Engine Size(L)": [engine_size], | |
| "Cylinders": [cylinders], | |
| "Fuel Consumption Comb (L/100 km)": [fuel_consumption_comb], | |
| "Vehicle Class": [vehicle_class], | |
| "Fuel Type": [fuel_type], | |
| } | |
| ) | |
| prediction = float(MODEL.predict(sample)[0]) | |
| details = ( | |
| "Model 3 - Parsimonious Mixed\n" | |
| f"Engine Size(L): {engine_size}\n" | |
| f"Cylinders: {cylinders}\n" | |
| f"Fuel Consumption Comb (L/100 km): {fuel_consumption_comb}\n" | |
| f"Vehicle Class: {vehicle_class}\n" | |
| f"Fuel Type: {fuel_type}\n" | |
| f"Estimated CO2: {prediction:.2f} g/km" | |
| ) | |
| return round(prediction, 2), details | |
| DESCRIPTION = f""" | |
| # CO2 Emissions Predictor | |
| This app predicts **CO2 emissions** for a vehicle. | |
| It uses the following inputs: | |
| - Engine Size(L) | |
| - Cylinders | |
| - Fuel Consumption Comb (L/100 km) | |
| - Vehicle Class | |
| - Fuel Type | |
| Model performance on test data: | |
| - Test RMSE: {METRICS["Test RMSE"]} | |
| - Test R2: {METRICS["Test R2"]} | |
| The charts below help show simple patterns in the dataset. | |
| """ | |
| with gr.Blocks(title="CO2 Emissions Predictor") as demo: | |
| gr.Markdown(DESCRIPTION) | |
| with gr.Row(): | |
| engine_size = gr.Slider( | |
| minimum=ENGINE_MIN, | |
| maximum=ENGINE_MAX, | |
| value=2.0, | |
| step=0.1, | |
| label="Engine Size(L)", | |
| ) | |
| cylinders = gr.Dropdown( | |
| choices=CYLINDER_VALUES, | |
| value=4, | |
| label="Cylinders", | |
| ) | |
| with gr.Row(): | |
| fuel_consumption = gr.Slider( | |
| minimum=FUEL_MIN, | |
| maximum=FUEL_MAX, | |
| value=7.5, | |
| step=0.1, | |
| label="Fuel Consumption Comb (L/100 km)", | |
| ) | |
| vehicle_class = gr.Dropdown( | |
| choices=VEHICLE_CLASSES, | |
| value="COMPACT" if "COMPACT" in VEHICLE_CLASSES else VEHICLE_CLASSES[0], | |
| label="Vehicle Class", | |
| ) | |
| fuel_type = gr.Dropdown( | |
| choices=FUEL_TYPES, | |
| value="X" if "X" in FUEL_TYPES else FUEL_TYPES[0], | |
| label="Fuel Type", | |
| ) | |
| predict_button = gr.Button("Predict") | |
| prediction = gr.Number(label="Predicted CO2 (g/km)") | |
| summary = gr.Textbox(label="Result Summary", lines=7) | |
| predict_button.click( | |
| fn=predict_co2_emission, | |
| inputs=[ | |
| engine_size, | |
| cylinders, | |
| fuel_consumption, | |
| vehicle_class, | |
| fuel_type, | |
| ], | |
| outputs=[prediction, summary], | |
| ) | |
| gr.Markdown("## Charts") | |
| gr.Markdown( | |
| "- Distribution of CO2 emissions across the dataset.\n" | |
| "- Relationship between fuel consumption and CO2 emissions.\n" | |
| "- Relationship between engine size and CO2 emissions.\n" | |
| "- Vehicle classes with the highest average CO2 emissions." | |
| ) | |
| with gr.Row(): | |
| gr.Plot( | |
| value=build_emissions_distribution_plot, | |
| label="Distribution of CO2 Emissions", | |
| ) | |
| gr.Plot( | |
| value=build_relationship_plot, | |
| label="Fuel Consumption vs CO2 Emissions", | |
| ) | |
| with gr.Row(): | |
| gr.Plot( | |
| value=build_engine_size_plot, | |
| label="Engine Size vs CO2 Emissions", | |
| ) | |
| gr.Plot( | |
| value=build_vehicle_class_plot, | |
| label="Top Vehicle Classes by CO2 Emissions", | |
| ) | |
| gr.Examples( | |
| examples=[ | |
| [2.0, 4, 7.5, "COMPACT", "X"], | |
| [3.5, 6, 10.8, "SUV - SMALL", "X"], | |
| [5.0, 8, 14.2, "PICKUP TRUCK - STANDARD", "Z"], | |
| ], | |
| inputs=[ | |
| engine_size, | |
| cylinders, | |
| fuel_consumption, | |
| vehicle_class, | |
| fuel_type, | |
| ], | |
| outputs=[prediction, summary], | |
| fn=predict_co2_emission, | |
| cache_examples=False, | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |