# app.py import streamlit as st import pickle import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # Load dataset df = pd.read_csv("/app/src/dataset_Facebook.csv", sep=";") # Load trained regression model (pipeline) with open("/app/src/regression_model.pkl", "rb") as f: model = pickle.load(f) st.set_page_config(page_title="Facebook Post Reach Prediction", layout="wide") # Sidebar navigation st.sidebar.title("Navigation") menu = [ "Introduction", "Problem Statement", "Data Collection", "EDA", "Feature Engineering", "Model Building", "Deployment" ] choice = st.sidebar.radio("Go to", menu) # Page 1: Introduction if choice == "Introduction": st.title("Facebook Post Reach Prediction using Regression") st.write(""" This project predicts the **Lifetime Post Total Reach** of Facebook posts using machine learning regression. By analyzing engagement metrics (likes, shares, comments, impressions, etc.), as well as temporal and categorical features, we can estimate how many people a post is likely to reach. Navigate through the sections to explore the dataset, insights, model building process, and live predictions. """) # Page 2: Problem Statement elif choice == "Problem Statement": st.title("Problem Statement") st.write(""" Social media managers often struggle to estimate how far a post will reach before it is published. **Goal:** Build a regression model that predicts the **Lifetime Post Total Reach** of a Facebook post using historical data. **Why it matters:** - Optimize posting time and strategy - Anticipate engagement levels - Improve ad budget allocation """) # Page 3: Data Collection elif choice == "Data Collection": st.title("Data Collection") st.write("Here’s a preview of the dataset used:") st.dataframe(df.head()) st.markdown(""" **Key Features:** - `page_total_likes` — Page followers at posting time - `type` — Post type (Photo, Status, Link, Video) - `category` — Category of the post - `post_month`, `post_weekday`, `post_hour` — Temporal features - `paid` — Boosted (1) or Organic (0) - `total_post_impressions`, `lifetime_engaged_users`, `lifetime_post_consumers`, `lifetime_post_consumptions`, `impressions_from_likers`, `reach_from_likers`, `likers_engaged_with_post` - Engagement metrics: `comments`, `likes`, `shares`, `total_interactions` - **Target variable:** `Lifetime Post Total Reach` """) # Page 4: EDA elif choice == "EDA": st.title("Exploratory Data Analysis (EDA)") # Distribution of target fig1, ax = plt.subplots(figsize=(6, 4)) sns.histplot(df["Lifetime Post Total Reach"], bins=30, kde=True, ax=ax) ax.set_title("Distribution of Post Reach") st.pyplot(fig1) plt.close(fig1) # Correlation heatmap fig2, ax = plt.subplots(figsize=(10, 6)) corr = df.corr(numeric_only=True) sns.heatmap(corr, cmap="coolwarm", annot=False, ax=ax) ax.set_title("Correlation Heatmap") st.pyplot(fig2) plt.close(fig2) st.markdown(""" **Insights:** - Higher likes, shares, and comments correlate strongly with reach. - Paid posts generally achieve higher reach. - Some temporal patterns are visible (e.g., posting time/weekday). """) # Page 5: Feature Engineering elif choice == "Feature Engineering": st.title("Feature Engineering") st.markdown(""" - Missing values handled in categorical and numerical features - `type` encoded using OneHotEncoder - Numeric features scaled using StandardScaler - Combined into a **ColumnTransformer** pipeline - Train-test split performed for unbiased evaluation """) # Page 6: Model Building elif choice == "Model Building": st.title("Model Building") st.markdown(""" - Algorithm: **KNeighborsRegressor** - Preprocessing included OneHotEncoding + Scaling - Model trained on full feature set of Facebook post data - Evaluation metrics: - **R² Score** - **Mean Squared Error (MSE)** Final model saved as `regression_model.pkl` and used for predictions in this app. """) # Page 7: Deployment elif choice == "Deployment": st.title("Deployment") st.write("Fill in the details below to predict **Lifetime Post Reach**:") # Inputs for all required features page_total_likes = st.number_input("Page Total Likes", min_value=0, step=100) post_type = st.selectbox("Post Type", ["Photo", "Status", "Link", "Video"]) category = st.selectbox("Category", [1, 2, 3]) post_month = st.selectbox("Post Month", list(range(1, 13))) post_weekday = st.selectbox("Post Weekday (1=Sun ... 7=Sat)", list(range(1, 8))) post_hour = st.slider("Post Hour", 0, 23, 12) paid = st.selectbox("Paid Promotion", [0, 1]) total_post_impressions = st.number_input("Total Post Impressions", min_value=0, step=100) lifetime_engaged_users = st.number_input("Lifetime Engaged Users", min_value=0, step=10) lifetime_post_consumers = st.number_input("Lifetime Post Consumers", min_value=0, step=10) lifetime_post_consumptions = st.number_input("Lifetime Post Consumptions", min_value=0, step=10) impressions_from_likers = st.number_input("Impressions from Likers", min_value=0, step=10) reach_from_likers = st.number_input("Reach from Likers", min_value=0, step=10) likers_engaged_with_post = st.number_input("Likers Engaged with Post", min_value=0, step=1) comments = st.number_input("Comments", min_value=0, step=1) likes = st.number_input("Likes", min_value=0, step=1) shares = st.number_input("Shares", min_value=0, step=1) total_interactions = st.number_input("Total Interactions", min_value=0, step=1) if st.button("Predict Reach"): input_df = pd.DataFrame([[ page_total_likes, post_type, category, post_month, post_weekday, post_hour, paid, total_post_impressions, lifetime_engaged_users, lifetime_post_consumers, lifetime_post_consumptions, impressions_from_likers, reach_from_likers, likers_engaged_with_post, comments, likes, shares, total_interactions ]], columns=[ 'page_total_likes', 'type', 'category', 'post_month', 'post_weekday', 'post_hour', 'paid', 'total_post_impressions', 'lifetime_engaged_users', 'lifetime_post_consumers', 'lifetime_post_consumptions', 'impressions_from_likers', 'reach_from_likers', 'likers_engaged_with_post', 'comments', 'likes', 'shares', 'total_interactions' ]) prediction = model.predict(input_df)[0] st.success(f"Estimated Post Reach: {prediction:.0f} users")