Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- Dockerfile +15 -12
- app.py +82 -0
- requirements.txt +8 -3
Dockerfile
CHANGED
|
@@ -1,20 +1,23 @@
|
|
| 1 |
-
|
|
|
|
| 2 |
|
|
|
|
| 3 |
WORKDIR /app
|
| 4 |
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
curl \
|
| 8 |
-
git \
|
| 9 |
-
&& rm -rf /var/lib/apt/lists/*
|
| 10 |
-
|
| 11 |
-
COPY requirements.txt ./
|
| 12 |
-
COPY src/ ./src/
|
| 13 |
|
|
|
|
| 14 |
RUN pip3 install -r requirements.txt
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
-
|
| 19 |
|
| 20 |
-
|
|
|
|
|
|
| 1 |
+
# Use a minimal base image with Python 3.9 installed
|
| 2 |
+
FROM python:3.9
|
| 3 |
|
| 4 |
+
# Set the working directory inside the container to /app
|
| 5 |
WORKDIR /app
|
| 6 |
|
| 7 |
+
# Copy all files from the current directory on the host to the container's /app directory
|
| 8 |
+
COPY . .
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
# Install Python dependencies listed in requirements.txt
|
| 11 |
RUN pip3 install -r requirements.txt
|
| 12 |
|
| 13 |
+
RUN useradd -m -u 1000 user
|
| 14 |
+
USER user
|
| 15 |
+
ENV HOME=/home/user \
|
| 16 |
+
PATH=/home/user/.local/bin:$PATH
|
| 17 |
+
|
| 18 |
+
WORKDIR $HOME/app
|
| 19 |
|
| 20 |
+
COPY --chown=user . $HOME/app
|
| 21 |
|
| 22 |
+
# Define the command to run the Streamlit app on port "8501" and make it accessible externally
|
| 23 |
+
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0", "--server.enableXsrfProtection=false"]
|
app.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import huggingface_hub
|
| 4 |
+
from huggingface_hub import HfApi,hf_hub_download
|
| 5 |
+
import joblib
|
| 6 |
+
import os
|
| 7 |
+
|
| 8 |
+
# Connect to HuggingFace Space using token from git secret
|
| 9 |
+
print("Connecting to Huggingface...")
|
| 10 |
+
try:
|
| 11 |
+
api = HfApi(token=os.getenv("HF_TOKEN"))
|
| 12 |
+
print("Connected..")
|
| 13 |
+
except Exception as e:
|
| 14 |
+
print(f"Error connecting to HuggingFace Space:{e}")
|
| 15 |
+
|
| 16 |
+
# Download the model from the Model Hub
|
| 17 |
+
model_path = hf_hub_download(repo_id="supravab/Tourism_Package_Prediction", filename="tourism_package_prediction_modelv1.joblib")
|
| 18 |
+
|
| 19 |
+
# Load the trained model
|
| 20 |
+
print("Loading tourism_package_prediction model from Huggingface...")
|
| 21 |
+
try:
|
| 22 |
+
model = joblib.load(model_path)
|
| 23 |
+
print("Model loaded successfully.")
|
| 24 |
+
except FileNotFoundError:
|
| 25 |
+
print("Error: 'tourism_package_prediction_modelv1.joblib' not found. Please train and save the model first.")
|
| 26 |
+
model = None
|
| 27 |
+
|
| 28 |
+
# Streamlit UI for Tourism Package Prediction
|
| 29 |
+
print("Preparing Streamlit UI App for Tourism Package Prediction..")
|
| 30 |
+
st.title("Tourism Package Prediction App")
|
| 31 |
+
st.write("The Tourism Package Prediction App is an internal tool for the company, that predicts whether a customer purchase a tourist package.")
|
| 32 |
+
st.write("Kindly enter the customer details to check whether they are likely to purchase.")
|
| 33 |
+
|
| 34 |
+
# Collect user input
|
| 35 |
+
Age = st.number_input("Age (Age of the customer)", min_value=15, max_value=100, value=30)
|
| 36 |
+
Gender = st.selectbox("Gender (Gender of customer)", ["Male", "Female"])
|
| 37 |
+
MaritalStatus = st.selectbox("MaritalStatus (Marital Status of customer)", ["Married", "Unmarried", "Divorced"])
|
| 38 |
+
Occupation = st.selectbox("Occupation (Occupation of customer)", ["Salaried", "Small Business", "Large Business", "Free Lancer"])
|
| 39 |
+
Designation = st.selectbox("Designation (Designation of customer)", ["Executive", "Manager", "Senior Manager", "AVP", "VP"])
|
| 40 |
+
CityTier = st.selectbox("CityTier (city category based on living)", ["1", "2","3"])
|
| 41 |
+
MonthlyIncome = st.number_input("MonthlyIncome (customer’s monthly income)", min_value=0.0, value=50000.0)
|
| 42 |
+
Passport = st.selectbox("Has Passport?", ["Yes", "No"])
|
| 43 |
+
OwnCar = st.selectbox("Has Own Car?", ["Yes", "No"])
|
| 44 |
+
|
| 45 |
+
NumberOfPersonVisiting = st.number_input("NumberOfPersonVisiting (No of people accompanying the customer)", min_value=1, max_value=10, value=5)
|
| 46 |
+
NumberOfChildrenVisiting = st.number_input("NumberOfChildrenVisiting (No of children accompanying the customer)", min_value=0, max_value=5, value=2)
|
| 47 |
+
NumberOfTrips = st.number_input("NumberOfTrips (No of trips per year)", min_value=0, max_value=10, value=3)
|
| 48 |
+
|
| 49 |
+
TypeofContact = st.selectbox("TypeofContact (Method by which customer was contacted)", ["Self Enquiry", "Company Invited"])
|
| 50 |
+
ProductPitched = st.selectbox("ProductPitched (Type of product pitched)", ["Basic", "Standard", "Deluxe", "Super Deluxe", "King"])
|
| 51 |
+
DurationOfPitch = st.number_input("DurationOfPitch (Duration of the sales pitch)", min_value=0, max_value=100, value=20)
|
| 52 |
+
NumberOfFollowups = st.number_input("NumberOfFollowups (Number of follow-ups by the salesperson)", min_value=0, max_value=10, value=2)
|
| 53 |
+
PitchSatisfactionScore = st.number_input("PitchSatisfactionScore (Pitch satisfaction score given by customer)", min_value=0, max_value=10, value=5)
|
| 54 |
+
PreferredPropertyStar = st.number_input("PreferredPropertyStar (Preferred rating given by customer)", min_value=1, max_value=5, value=2)
|
| 55 |
+
|
| 56 |
+
# Assemble input into DataFrame
|
| 57 |
+
input_data = pd.DataFrame([{
|
| 58 |
+
'Age': Age,
|
| 59 |
+
'Gender': Gender,
|
| 60 |
+
'MaritalStatus': MaritalStatus,
|
| 61 |
+
'Occupation': Occupation,
|
| 62 |
+
'Designation': Designation,
|
| 63 |
+
'CityTier': CityTier,
|
| 64 |
+
'MonthlyIncome': MonthlyIncome,
|
| 65 |
+
'Passport': 1 if Passport == "Yes" else 0,
|
| 66 |
+
'OwnCar': 1 if OwnCar == "Yes" else 0,
|
| 67 |
+
'NumberOfPersonVisiting': NumberOfPersonVisiting,
|
| 68 |
+
'NumberOfChildrenVisiting': NumberOfChildrenVisiting,
|
| 69 |
+
'NumberOfTrips': NumberOfTrips,
|
| 70 |
+
'TypeofContact': TypeofContact,
|
| 71 |
+
'ProductPitched': ProductPitched,
|
| 72 |
+
'DurationOfPitch': DurationOfPitch,
|
| 73 |
+
'NumberOfFollowups': NumberOfFollowups,
|
| 74 |
+
'PitchSatisfactionScore': PitchSatisfactionScore,
|
| 75 |
+
'PreferredPropertyStar': PreferredPropertyStar
|
| 76 |
+
}])
|
| 77 |
+
|
| 78 |
+
if st.button("Predict Purchase"):
|
| 79 |
+
prediction = model.predict(input_data)[0]
|
| 80 |
+
result = "Purchase Yes" if prediction == 1 else "Purchase No"
|
| 81 |
+
st.subheader("Prediction Result:")
|
| 82 |
+
st.success(f"The model predicts: **{result}**")
|
requirements.txt
CHANGED
|
@@ -1,3 +1,8 @@
|
|
| 1 |
-
|
| 2 |
-
pandas
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
numpy==2.0.2
|
| 2 |
+
pandas==2.2.2
|
| 3 |
+
scikit-learn==1.6.1
|
| 4 |
+
xgboost==3.1.2
|
| 5 |
+
mlflow==3.0.1
|
| 6 |
+
joblib==1.5.1
|
| 7 |
+
huggingface_hub==0.32.6
|
| 8 |
+
streamlit==1.43.2
|