Spaces:
Runtime error
Runtime error
Download src/streamlit_app.py from nab3588/demandregression: direct link, hf CLI and curl.
- Browser
- Download file 7.36 kB
-
https://huggingface.co/spaces/nab3588/demandregression/resolve/main/src/streamlit_app.py
- Command line
-
hf download hf://spaces/nab3588/demandregression/src/streamlit_app.py
-
curl -L -o streamlit_app.py https://huggingface.co/spaces/nab3588/demandregression/resolve/main/src/streamlit_app.py
7.36 kB
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| from sklearn.linear_model import LinearRegression | |
| from sklearn.preprocessing import PolynomialFeatures | |
| import plotly.graph_objects as go | |
| import math | |
| import os | |
| os.environ["HF_HOME"] = "./hf_home" # optional, for other HF cache | |
| st.set_page_config(page_title="Prediksi Penjualan Warung", page_icon="π", layout="centered") | |
| st.markdown( | |
| """ | |
| <style> | |
| iframe[src*="fileUpload"] { | |
| pointer-events: auto !important; | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| st.title("Prediksi & Rekomendasi Penjualan - Profitly") | |
| st.markdown(""" | |
| Unggah file **CSV** dengan format dari unduhan Dashboard | |
| """) | |
| # FILE UPLOAD | |
| uploaded_file = st.file_uploader("π Unggah File CSV Penjualan", type=None) | |
| if uploaded_file is not None: | |
| try: | |
| df = pd.read_csv(uploaded_file) | |
| if "Hari" not in df.columns or "Jumlah Terjual" not in df.columns: | |
| st.error("β Format CSV tidak sesuai. Pastikan kolom 'Hari' dan 'Jumlah Terjual' ada.") | |
| else: | |
| # Convert "Day X" to number | |
| df["Hari_Num"] = df["Hari"].str.extract(r"(\d+)").astype(int) | |
| unique_days = df["Hari_Num"].nunique() | |
| if unique_days <= 2: | |
| st.warning("β οΈ Data harus memiliki lebih dari 2 hari agar prediksi bisa dilakukan.") | |
| else: | |
| # Regression type selection | |
| regression_type = "Linear" if unique_days <= 4 else "Polynomial" | |
| st.success(f"β Data berhasil dimuat! Menggunakan **{regression_type} Regression**.") | |
| st.subheader("π Data Penjualan") | |
| st.dataframe(df, use_container_width=True) | |
| st.markdown("---") | |
| st.header("π Prediksi Penjualan per Barang (2 Hari ke Depan)") | |
| predictions = [] | |
| fig = go.Figure() | |
| # Loop per item | |
| for item in df["Barang"].unique(): | |
| item_df = df[df["Barang"] == item] | |
| X = item_df[["Hari_Num"]] | |
| y = item_df["Jumlah Terjual"] | |
| # Choose regression model | |
| if regression_type == "Linear": | |
| # Linear | |
| model = LinearRegression() | |
| model.fit(X, y) | |
| predict_func = lambda x: model.predict(x) | |
| else: | |
| # Polynomial regression | |
| poly = PolynomialFeatures(degree=2) | |
| X_poly = poly.fit_transform(X) | |
| model = LinearRegression() | |
| model.fit(X_poly, y) | |
| predict_func = lambda x: model.predict(poly.transform(x)) | |
| # Generate predictions 2 days | |
| future_days = np.array([max(df["Hari_Num"]) + 1, max(df["Hari_Num"]) + 2]).reshape(-1, 1) | |
| predicted_sales = [max(0, math.floor(p)) for p in predict_func(future_days)] | |
| # Assign consistent color | |
| color = f"hsl({hash(item) % 360}, 70%, 50%)" | |
| # Save for summary | |
| for day, pred in zip(future_days.flatten(), predicted_sales): | |
| predictions.append({ | |
| "Barang": item, | |
| "Hari": f"Day {int(day)}", | |
| "Prediksi Terjual": round(pred, 2) | |
| }) | |
| # Plot actual line | |
| fig.add_trace(go.Scatter( | |
| x=item_df["Hari_Num"], | |
| y=item_df["Jumlah Terjual"], | |
| mode='lines+markers', | |
| name=f"{item} (Aktual)", | |
| line=dict(color=color, width=3) | |
| )) | |
| # Plot predicted line | |
| fig.add_trace(go.Scatter( | |
| x=future_days.flatten(), | |
| y=predicted_sales, | |
| mode='lines+markers', | |
| name=f"{item} (Prediksi)", | |
| line=dict(color=color, dash='dot', width=2) | |
| )) | |
| # Plot settings | |
| fig.update_layout( | |
| title=f"Prediksi Penjualan per Barang ({regression_type} Regression)", | |
| xaxis_title="Hari", | |
| yaxis_title="Jumlah Terjual", | |
| template="plotly_white", | |
| height=500 | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # TABEL PREDIKSI CUI | |
| pred_df = pd.DataFrame(predictions)[["Hari", "Barang", "Prediksi Terjual"]] | |
| day_plus1 = pred_df[pred_df["Hari"].str.contains(f"Day {max(df['Hari_Num']) + 1}")] | |
| day_plus2 = pred_df[pred_df["Hari"].str.contains(f"Day {max(df['Hari_Num']) + 2}")] | |
| st.subheader(f"π Prediksi Penjualan Hari Berikutnya (Day {max(df['Hari_Num']) + 1})") | |
| st.dataframe(day_plus1, use_container_width=True) | |
| st.subheader(f"π Prediksi Penjualan 2 Hari Lagi (Day {max(df['Hari_Num']) + 2})") | |
| st.dataframe(day_plus2, use_container_width=True) | |
| st.markdown("---") | |
| st.header("Analisis & Rekomendasi") | |
| # Find top and bottom performers | |
| avg_sales = df.groupby("Barang")["Jumlah Terjual"].mean().sort_values(ascending=False) | |
| top_items = avg_sales.head(2).index.tolist() | |
| low_items = avg_sales.tail(2).index.tolist() | |
| st.write("**2 Barang dengan Penjualan Tertinggi:**") | |
| st.success(", ".join(top_items)) | |
| st.write("**2 Barang dengan Penjualan Terendah:**") | |
| st.warning(", ".join(low_items)) | |
| # Smart discount recommendations | |
| st.subheader("Rekomendasi Diskon") | |
| st.markdown(""" | |
| Rekomendasi dibuat berdasarkan tren penjualan: | |
| - Barang dengan **penjualan tinggi** bisa diberi diskon kecil untuk menarik lebih banyak pelanggan. | |
| - Barang dengan **penjualan rendah** bisa diberi diskon lebih besar agar stok cepat berputar. | |
| """) | |
| discount_suggestions = [] | |
| for item in top_items: | |
| discount_suggestions.append({ | |
| "Barang": item, | |
| "Tipe Rekomendasi": "Penjualan Tinggi", | |
| "Saran Diskon": "Diskon ringan (5-10%) untuk menarik loyalitas pelanggan." | |
| }) | |
| for item in low_items: | |
| discount_suggestions.append({ | |
| "Barang": item, | |
| "Tipe Rekomendasi": "Penjualan Rendah", | |
| "Saran Diskon": "Diskon besar (15-25%) agar penjualan meningkat." | |
| }) | |
| st.dataframe(pd.DataFrame(discount_suggestions), use_container_width=True) | |
| st.markdown("β¨ _Gunakan prediksi dan rekomendasi ini untuk menyesuaikan strategi penjualan Anda agar semakin menguntungkan!_") | |
| except Exception as e: | |
| st.error(f"Terjadi kesalahan saat memproses file: {e}") | |
| else: | |
| st.info("Silakan unggah file CSV untuk memulai analisis.") | |