Enter the Recency, Frequency, and Monetary data to find out which segment the customer belongs to.
The customer segment will appear here.
packages = [
"pandas",
"scikit-learn",
"numpy",
"joblib"
]
import pandas as pd
import joblib
from pyodide.http import pyfetch
from js import document, console
import io
# Global variables to store the scaler and model
scaler = None
model = None
async def load_model_and_scaler():
"""Asynchronously loads the scaler and .joblib model file."""
global scaler, model
if scaler is None or model is None:
console.log("Loading the scaler and model...")
try:
response = await pyfetch('./rfm_cluster_model.joblib')
if response.ok:
model_bytes = await response.bytes()
# joblib.load returns the tuple we saved: (scaler, kmeans_model)
scaler, model = joblib.load(io.BytesIO(model_bytes))
console.log("Scaler and model loaded successfully!")
else:
console.error(f"Error fetching the file: {response.status}")
except Exception as e:
console.error(f"An error occurred while loading the file: {e}")
async def segment_customer(*args, **kwargs):
"""Function called by the button to segment the customer (final corrected version)."""
await load_model_and_scaler()
output_div = document.getElementById('output-div')
if scaler is None or model is None:
output_div.innerText = "Error: Model could not be loaded."
return
try:
recency_val = document.getElementById('recency').value
frequency_val = document.getElementById('frequency').value
monetary_val = document.getElementById('monetary').value
if not recency_val or not frequency_val or not monetary_val:
raise ValueError("Fields cannot be empty.")
recency = int(recency_val)
frequency = int(frequency_val)
monetary = float(monetary_val)
# Creates the input DataFrame with the correct column names
input_df = pd.DataFrame([[recency, frequency, monetary]], columns=['Recency', 'Frequency', 'Monetary'])
# STEP 1: Apply scaling
scaled_input_array = scaler.transform(input_df) # This returns a NumPy Array
# --- CORRECTED/ADDED LINE ---
# Convert the array back to a DataFrame with column names
scaled_input_df = pd.DataFrame(scaled_input_array, columns=input_df.columns)
# STEP 2: Use the model to predict the cluster from the scaled DataFrame
# --- CHANGED LINE ---
cluster = model.predict(scaled_input_df)[0]
# Map the cluster number to a user-friendly description
cluster_map = {
0: "At-Risk Customers (Purchased a long time ago)",
1: "Best Customers (Champions)",
2: "Loyal Customers (Potential for growth)",
3: "New Customers (Low value, but recent)"
}
segment_name = cluster_map.get(cluster, "Unknown Segment")
# Display the result on the screen
output_div.innerText = f"Segment: {segment_name}"
except ValueError as e:
output_div.innerText = "Error: Please fill all fields with valid numbers."
except Exception as e:
console.error(f"An unexpected error occurred: {e}")
output_div.innerText = "An unexpected error occurred. Check the console (F12)."