Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
import random
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
from sklearn.preprocessing import MinMaxScaler
|
7 |
+
from backend.src.dqn_agent import AdvancedDQNAgent
|
8 |
+
|
9 |
+
st.set_page_config(page_title="Next (AI): Customer", layout="wide")
|
10 |
+
st.title("Next AI: Product Recommendation Agent")
|
11 |
+
st.markdown("Chat with nExT(AI) to get real-time customer targeting recommendations. Type a query (e.g., 'Show me discount recommendations') and nExT(AI) will reply with the corresponding customer table.")
|
12 |
+
|
13 |
+
# Initialize session state for chat history
|
14 |
+
if "chat_history" not in st.session_state:
|
15 |
+
st.session_state.chat_history = []
|
16 |
+
|
17 |
+
# Helper function to load and preprocess data
|
18 |
+
@st.cache_data(show_spinner=False)
|
19 |
+
def load_data():
|
20 |
+
df = pd.read_csv("data\\customers.csv")
|
21 |
+
return df
|
22 |
+
|
23 |
+
def preprocess_data(df):
|
24 |
+
churn_mapping = {"Low": 0, "Medium": 1, "High": 2}
|
25 |
+
df['ChurnRiskEncoded'] = df['ChurnRisk'].map(churn_mapping)
|
26 |
+
features = df[['Age', 'Income', 'PurchaseFrequency', 'AvgSpend', 'ChurnRiskEncoded']].values
|
27 |
+
scaler = MinMaxScaler()
|
28 |
+
features = scaler.fit_transform(features)
|
29 |
+
return features
|
30 |
+
|
31 |
+
# Load and preprocess data
|
32 |
+
df = load_data()
|
33 |
+
states = preprocess_data(df)
|
34 |
+
|
35 |
+
# Setup RL agent (state vector of 5 features; actions: 0: Discount, 1: Recommend Product, 2: No Action)
|
36 |
+
state_size = states.shape[1]
|
37 |
+
action_size = 3
|
38 |
+
agent = AdvancedDQNAgent(state_size, action_size)
|
39 |
+
|
40 |
+
# For demonstration, run the agent on all customers to compute recommendations.
|
41 |
+
recommendations = [agent.act(state) for state in states]
|
42 |
+
df['Recommendation'] = recommendations
|
43 |
+
|
44 |
+
# Group recommendations
|
45 |
+
discount_df = df[df['Recommendation'] == 0]
|
46 |
+
product_df = df[df['Recommendation'] == 1]
|
47 |
+
no_action_df = df[df['Recommendation'] == 2]
|
48 |
+
|
49 |
+
# Define a simple function to process user queries
|
50 |
+
def process_query(query):
|
51 |
+
query_lower = query.lower()
|
52 |
+
if "discount" in query_lower:
|
53 |
+
response = "Here are the customers recommended for a discount (Action 0):"
|
54 |
+
table = discount_df[['CustomerID', 'Age', 'Income', 'PurchaseFrequency', 'AvgSpend', 'ChurnRisk']]
|
55 |
+
elif "product" in query_lower:
|
56 |
+
response = "Here are the customers recommended for a product suggestion (Action 1):"
|
57 |
+
table = product_df[['CustomerID', 'Age', 'Income', 'PurchaseFrequency', 'AvgSpend', 'ChurnRisk']]
|
58 |
+
elif "no action" in query_lower:
|
59 |
+
response = "Here are the customers for whom no specific action is recommended (Action 2):"
|
60 |
+
table = no_action_df[['CustomerID', 'Age', 'Income', 'PurchaseFrequency', 'AvgSpend', 'ChurnRisk']]
|
61 |
+
elif "all" in query_lower or "recommendation" in query_lower:
|
62 |
+
response = "Here are all customer recommendations:"
|
63 |
+
table = df[['CustomerID', 'Age', 'Income', 'PurchaseFrequency', 'AvgSpend', 'ChurnRisk', 'Recommendation']]
|
64 |
+
else:
|
65 |
+
response = "I'm sorry, I didn't understand that. Please ask for discount, product, or no action recommendations."
|
66 |
+
table = None
|
67 |
+
return response, table
|
68 |
+
|
69 |
+
# Display chat history
|
70 |
+
for chat in st.session_state.chat_history:
|
71 |
+
if chat["role"] == "user":
|
72 |
+
st.markdown(f"**User:** {chat['message']}")
|
73 |
+
else:
|
74 |
+
st.markdown(f"**nExT(AI):** {chat['message']}")
|
75 |
+
if chat.get("table") is not None:
|
76 |
+
st.table(chat["table"])
|
77 |
+
|
78 |
+
# Input for new message
|
79 |
+
user_input = st.text_input("Type your message here and press Enter:")
|
80 |
+
|
81 |
+
if user_input:
|
82 |
+
# Append user's message to chat history
|
83 |
+
st.session_state.chat_history.append({"role": "user", "message": user_input})
|
84 |
+
# Process the query and get reply
|
85 |
+
reply_text, reply_table = process_query(user_input)
|
86 |
+
st.session_state.chat_history.append({"role": "agent", "message": reply_text, "table": reply_table})
|
87 |
+
# Clear input by simply relying on Streamlit's reactivity (the text input resets on script re-run)
|
88 |
+
# Note: Without experiment
|