Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| from sklearn.manifold import TSNE | |
| from sklearn.preprocessing import MinMaxScaler | |
| import os | |
| INPUT_FILE = "wallet_dataset_labeled.csv" | |
| OUTPUT_DIR = "docs" | |
| RADAR_CHART_FILE = os.path.join(OUTPUT_DIR, "persona_radar_chart.png") | |
| TSNE_PLOT_FILE = os.path.join(OUTPUT_DIR, "clusters_tsne.png") | |
| os.makedirs(OUTPUT_DIR, exist_ok=True) | |
| def load_data(): | |
| if not os.path.exists(INPUT_FILE): | |
| print(f"Error: {INPUT_FILE} not found.") | |
| return None | |
| return pd.read_csv(INPUT_FILE) | |
| def plot_radar_chart(df): | |
| print("Generating Radar Chart") | |
| features = [ | |
| 'tx_count', 'active_days', 'total_gas_spent', | |
| 'total_nft_volume_usd', 'dex_trades', 'total_traded_usd' | |
| ] | |
| scaler = MinMaxScaler() | |
| df_scaled = df.copy() | |
| df_scaled[features] = scaler.fit_transform(df[features]) | |
| persona_means = df_scaled.groupby('Persona')[features].mean() | |
| labels=np.array(features) | |
| num_vars = len(labels) | |
| angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist() | |
| angles += angles[:1] | |
| fig, ax = plt.subplots(figsize=(10, 10), subplot_kw=dict(polar=True)) | |
| colors = sns.color_palette("husl", len(persona_means)) | |
| for idx, (persona, row) in enumerate(persona_means.iterrows()): | |
| values = row.tolist() | |
| values += values[:1] | |
| ax.plot(angles, values, color=colors[idx], linewidth=2, label=persona) | |
| ax.fill(angles, values, color=colors[idx], alpha=0.1) | |
| ax.set_theta_offset(np.pi / 2) | |
| ax.set_theta_direction(-1) | |
| ax.set_xticks(angles[:-1]) | |
| ax.set_xticklabels(labels) | |
| plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1)) | |
| plt.title("Persona Behavioral Fingerprints (Normalized)", y=1.08) | |
| plt.savefig(RADAR_CHART_FILE, bbox_inches='tight', dpi=300) | |
| print(f"Saved radar chart to {RADAR_CHART_FILE}") | |
| plt.close() | |
| def plot_tsne(df): | |
| print("Generating t-SNE Plot (this may take a moment)...") | |
| feature_cols = [ | |
| 'tx_count', 'active_days', 'avg_tx_per_day', 'total_gas_spent', | |
| 'total_nft_buys', 'total_nft_sells', 'total_nft_volume_usd', | |
| 'unique_nfts_owned', 'dex_trades', 'avg_trade_size_usd', | |
| 'total_traded_usd', 'erc20_receive_usd', 'erc20_send_usd', | |
| 'native_balance_delta' | |
| ] | |
| X = df[feature_cols].fillna(0) | |
| tsne = TSNE(n_components=2, random_state=42, init='random', learning_rate='auto') | |
| X_embedded = tsne.fit_transform(X) | |
| plt.figure(figsize=(12, 8)) | |
| sns.scatterplot( | |
| x=X_embedded[:, 0], | |
| y=X_embedded[:, 1], | |
| hue=df['Persona'], | |
| palette='husl', | |
| alpha=0.7 | |
| ) | |
| plt.title("t-SNE Projection of Wallet Clusters") | |
| plt.xlabel("Dimension 1") | |
| plt.ylabel("Dimension 2") | |
| plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') | |
| plt.tight_layout() | |
| plt.savefig(TSNE_PLOT_FILE, dpi=300) | |
| print(f"Saved t-SNE plot to {TSNE_PLOT_FILE}") | |
| plt.close() | |
| if __name__ == "__main__": | |
| df = load_data() | |
| if df is not None: | |
| plot_radar_chart(df) | |
| plot_tsne(df) | |
| print("Visualization complete.") | |