Download ml/models/segmentation/segmentation_model.py from Vishu2006/customer360AI: direct link, hf CLI and curl.
- Browser
- Download file 3.34 kB
-
https://huggingface.co/Vishu2006/customer360AI/resolve/main/ml/models/segmentation/segmentation_model.py
- Command line
-
hf download hf://Vishu2006/customer360AI/ml/models/segmentation/segmentation_model.py
-
curl -L -o segmentation_model.py https://huggingface.co/Vishu2006/customer360AI/resolve/main/ml/models/segmentation/segmentation_model.py
3.34 kB
| import numpy as np | |
| import pandas as pd | |
| from sklearn.cluster import KMeans | |
| from sklearn.preprocessing import StandardScaler | |
| BUSINESS_SEGMENTS = [ | |
| "High Value Loyal", | |
| "High Value At Risk", | |
| "High Intent", | |
| "Low Value Active", | |
| "Dormant" | |
| ] | |
| class CustomerSegmentationModel: | |
| def __init__(self, n_clusters=5, random_state=42): | |
| self.n_clusters = n_clusters | |
| self.random_state = random_state | |
| self.scaler = StandardScaler() | |
| self.kmeans = KMeans(n_clusters=n_clusters, random_state=random_state, n_init=10) | |
| self.cluster_to_segment_map = {} | |
| def fit(self, X: pd.DataFrame, df_raw: pd.DataFrame = None): | |
| X_scaled = self.scaler.fit_transform(X) | |
| cluster_labels = self.kmeans.fit_predict(X_scaled) | |
| # Map clusters to meaningful business names using domain rules on cluster centers | |
| if df_raw is not None: | |
| df_temp = df_raw.copy() | |
| df_temp['cluster'] = cluster_labels | |
| cluster_stats = df_temp.groupby('cluster').agg({ | |
| 'monetary_total_spend': 'mean', | |
| 'recency_days': 'mean', | |
| 'product_views_30d': 'mean', | |
| 'frequency_purchases': 'mean' | |
| }) | |
| # Sort clusters by spend & recency | |
| assigned = {} | |
| unassigned_segments = list(BUSINESS_SEGMENTS) | |
| # High Value Loyal: highest spend + low recency | |
| loyal_idx = cluster_stats.sort_values(by=['monetary_total_spend', 'recency_days'], ascending=[False, True]).index[0] | |
| assigned[loyal_idx] = "High Value Loyal" | |
| # High Value At Risk: high spend + high recency | |
| at_risk_candidates = cluster_stats.drop(index=[loyal_idx]) | |
| at_risk_idx = at_risk_candidates.sort_values(by=['recency_days', 'monetary_total_spend'], ascending=[False, False]).index[0] | |
| assigned[at_risk_idx] = "High Value At Risk" | |
| # High Intent: remaining with highest product_views_30d | |
| intent_candidates = cluster_stats.drop(index=list(assigned.keys())) | |
| intent_idx = intent_candidates.sort_values(by='product_views_30d', ascending=False).index[0] | |
| assigned[intent_idx] = "High Intent" | |
| # Dormant: remaining with highest recency & lowest spend | |
| dormant_candidates = cluster_stats.drop(index=list(assigned.keys())) | |
| dormant_idx = dormant_candidates.sort_values(by=['recency_days', 'monetary_total_spend'], ascending=[True, True]).index[0] | |
| assigned[dormant_idx] = "Dormant" | |
| # Remaining cluster -> Low Value Active | |
| remaining = [c for c in range(self.n_clusters) if c not in assigned] | |
| if remaining: | |
| assigned[remaining[0]] = "Low Value Active" | |
| self.cluster_to_segment_map = assigned | |
| else: | |
| self.cluster_to_segment_map = {i: BUSINESS_SEGMENTS[i % len(BUSINESS_SEGMENTS)] for i in range(self.n_clusters)} | |
| return self | |
| def predict(self, X: pd.DataFrame) -> list[str]: | |
| X_scaled = self.scaler.transform(X) | |
| clusters = self.kmeans.predict(X_scaled) | |
| return [self.cluster_to_segment_map.get(c, "Low Value Active") for c in clusters] | |