import os import joblib import numpy as np import pandas as pd import streamlit as st st.set_page_config(page_title="Quality & Price Prediction", page_icon="๐Ÿ’Ž", layout="wide") ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @st.cache_resource def load_models(): return { "wine": joblib.load(os.path.join(ROOT, "wine_model.pkl")), "wine_columns": joblib.load(os.path.join(ROOT, "feature_columns.pkl")), "diamond": joblib.load(os.path.join(ROOT, "diamond_bundle.pkl")), "tips": joblib.load(os.path.join(ROOT, "waiter_tip_bundle.joblib")), } models = load_models() st.title("๐Ÿ’Ž Quality & Price Prediction Hub") st.caption("Three trained regression and classification projects with practical input forms.") wine_tab, diamond_tab, tip_tab = st.tabs(["Wine Quality", "Diamond Price", "Waiter Tip"]) with wine_tab: st.subheader("Predict wine quality from laboratory measurements") a, b, c = st.columns(3) wine_values = { "fixed acidity": a.number_input("Fixed acidity", 3.0, 20.0, 8.0, .1), "volatile acidity": a.number_input("Volatile acidity", 0.0, 2.0, .5, .01), "citric acid": a.number_input("Citric acid", 0.0, 2.0, .3, .01), "residual sugar": a.number_input("Residual sugar", 0.0, 70.0, 2.5, .1), "chlorides": b.number_input("Chlorides", 0.0, 1.0, .08, .005, format="%.3f"), "free sulfur dioxide": b.number_input("Free sulfur dioxide", 0.0, 300.0, 15.0, 1.0), "total sulfur dioxide": b.number_input("Total sulfur dioxide", 0.0, 500.0, 46.0, 1.0), "density": b.number_input("Density", .98, 1.05, .9968, .0001, format="%.4f"), "pH": c.number_input("pH", 2.0, 5.0, 3.3, .01), "sulphates": c.number_input("Sulphates", 0.0, 3.0, .65, .01), "alcohol": c.number_input("Alcohol (%)", 5.0, 25.0, 10.5, .1), } if st.button("Predict wine quality", type="primary"): row = pd.DataFrame([{**{"Id": 0}, **wine_values}]).reindex(columns=models["wine_columns"], fill_value=0) quality = int(models["wine"].predict(row)[0]) st.metric("Predicted quality", f"{quality} / 10") st.success("High-quality profile") if quality >= 7 else st.info("Typical-quality profile" if quality >= 5 else "Lower-quality profile") with diamond_tab: st.subheader("Estimate a diamond's price in US dollars") cut_map = {"Fair": 1, "Good": 2, "Very Good": 3, "Premium": 4, "Ideal": 5} color_map = {"J": 1, "I": 2, "H": 3, "G": 4, "F": 5, "E": 6, "D": 7} clarity_map = {"I1": 1, "SI2": 2, "SI1": 3, "VS2": 4, "VS1": 5, "VVS2": 6, "VVS1": 7, "IF": 8} a, b, c = st.columns(3) carat = a.number_input("Carat", .1, 6.0, 1.0, .05) depth = a.number_input("Depth (%)", 40.0, 80.0, 61.5, .1) table = a.number_input("Table (%)", 40.0, 100.0, 57.0, .1) x = b.number_input("Length x (mm)", 1.0, 15.0, 6.4, .1) y = b.number_input("Width y (mm)", 1.0, 15.0, 6.4, .1) z = b.number_input("Depth z (mm)", .5, 10.0, 4.0, .1) cut = c.selectbox("Cut", list(cut_map), index=4) color = c.selectbox("Color", list(color_map), index=3) clarity = c.selectbox("Clarity", list(clarity_map), index=3) if st.button("Estimate diamond price", type="primary"): values = {"carat": carat, "depth": depth, "table": table, "x": x, "y": y, "z": z, "volume": x*y*z, "color_ord": color_map[color], "clarity_ord": clarity_map[clarity], "cut_ord": cut_map[cut]} row = pd.DataFrame([values], columns=models["diamond"]["columns"]) price = max(0.0, float(models["diamond"]["model"].predict(row)[0])) st.metric("Estimated price", f"${price:,.0f}") st.caption("Educational estimate based on the training dataset; laboratory certification and market conditions also affect real prices.") with tip_tab: st.subheader("Estimate a restaurant tip") a, b = st.columns(2) bill = a.number_input("Total bill ($)", 1.0, 500.0, 35.0, 1.0) party = a.slider("Party size", 1, 10, 2) sex = a.selectbox("Customer sex (dataset field)", ["Female", "Male"]) smoker = b.selectbox("Smoking table", ["No", "Yes"]) day = b.selectbox("Day", ["Thursday", "Friday", "Saturday", "Sunday"]) meal = b.selectbox("Meal", ["Dinner", "Lunch"]) if st.button("Estimate tip", type="primary"): day_code = {"Friday": 0, "Saturday": 1, "Sunday": 2, "Thursday": 3}[day] weekend = int(day in ["Friday", "Saturday", "Sunday"]) smoker_code = int(smoker == "Yes") values = {"total_bill": bill, "sex": int(sex == "Male"), "smoker": smoker_code, "day": day_code, "time": int(meal == "Lunch"), "size": party, "is_weekend": weekend, "is_smoker": smoker_code, "is_dinner": int(meal == "Dinner"), "bill_x_size": bill*party, "smoker_weekend": smoker_code*weekend} row = pd.DataFrame([values], columns=models["tips"]["features"]) tip = max(0.0, float(models["tips"]["model"].predict(row)[0])) st.metric("Estimated tip", f"${tip:.2f}", f"{tip/bill:.1%} of bill") st.caption("Model validation MAE: approximately $0.75 on the small 244-row tips dataset.") st.divider() st.caption("Portfolio of Jale Summak ยท Educational machine-learning estimates")