Spaces:
Build error
Build error
| import random | |
| import pandas as pd | |
| from artwork_bandit.features.nlp_encoder import NLPEncoder | |
| from artwork_bandit.features.vision_encoder import VisionEncoder | |
| from artwork_bandit.features.feature_store import FeatureStore | |
| from artwork_bandit.bandit.linucb import LinUCBBandit | |
| from artwork_bandit.bandit.thompson import ThompsonBandit | |
| from artwork_bandit.simulation.simulator import ArtworkSimulator | |
| import numpy as np | |
| def run_evaluation(n_rounds=5000, algorithm='linucb'): | |
| import json, os | |
| base = os.path.join(os.path.dirname(__file__), '..', 'data') | |
| with open(os.path.join(base, 'users.json')) as f: | |
| users = json.load(f) | |
| with open(os.path.join(base, 'content.json')) as f: | |
| contents = json.load(f) | |
| with open(os.path.join(base, 'artwork.json')) as f: | |
| artworks = json.load(f) | |
| nlp = NLPEncoder() | |
| vis = VisionEncoder() | |
| fs = FeatureStore(None, nlp, vis) | |
| fs.precompute_all(users, contents, artworks) | |
| all_arts = [a['artwork_id'] for a in artworks] | |
| d = 384 + 384 + 512 | |
| linucb = LinUCBBandit(all_arts, d=d, alpha=1.0) | |
| thompson = ThompsonBandit(all_arts) | |
| sim = ArtworkSimulator(users, contents, artworks) | |
| records = [] | |
| bandit_wins = 0 | |
| bandit_rewards = [] | |
| random_rewards = [] | |
| static_rewards = [] | |
| cum_bandit = cum_random = cum_static = 0 | |
| for r in range(1, n_rounds+1): | |
| user = random.choice(users) | |
| content = random.choice(contents) | |
| arts = fs.get_artworks_for_content(content['content_id']) | |
| # build contexts | |
| contexts = {aid: fs.build_context_vector(user['user_id'], content['content_id'], aid) for aid in arts} | |
| if algorithm == 'linucb': | |
| chosen = linucb.select(contexts) | |
| else: | |
| chosen = thompson.select(list(contexts.keys())) | |
| rand_choice = random.choice(arts) | |
| static_choice = [a for a in arts if a.endswith('_001')] | |
| static_choice = static_choice[0] if static_choice else arts[0] | |
| # simulate | |
| b_reward = ArtworkSimulator(users, contents, artworks).simulate_click(user['user_id'], chosen) | |
| r_reward = ArtworkSimulator(users, contents, artworks).simulate_click(user['user_id'], rand_choice) | |
| s_reward = ArtworkSimulator(users, contents, artworks).simulate_click(user['user_id'], static_choice) | |
| # update | |
| if algorithm == 'linucb': | |
| linucb.update(chosen, contexts[chosen], b_reward) | |
| else: | |
| thompson.update(chosen, b_reward) | |
| # oracle | |
| oracle = sim.get_oracle_artwork(user['user_id'], content['content_id']) | |
| chose_oracle = 1 if chosen == oracle else 0 | |
| cum_bandit += b_reward | |
| cum_random += r_reward | |
| cum_static += s_reward | |
| records.append({ | |
| 'round': r, | |
| 'bandit_reward': b_reward, | |
| 'random_reward': r_reward, | |
| 'static_reward': s_reward, | |
| 'chose_oracle': chose_oracle, | |
| 'cumulative_bandit_ctr': cum_bandit / r, | |
| 'cumulative_random_ctr': cum_random / r, | |
| 'cumulative_static_ctr': cum_static / r, | |
| 'cumulative_regret': (cum_random - cum_bandit) | |
| }) | |
| df = pd.DataFrame.from_records(records) | |
| return df | |
| def print_evaluation_summary(df): | |
| rounds = len(df) | |
| final_bandit = df['cumulative_bandit_ctr'].iloc[-1] | |
| final_random = df['cumulative_random_ctr'].iloc[-1] | |
| final_static = df['cumulative_static_ctr'].iloc[-1] | |
| improvement_random = (final_bandit - final_random) / final_random * 100 if final_random>0 else 0 | |
| improvement_static = (final_bandit - final_static) / final_static * 100 if final_static>0 else 0 | |
| oracle_rate = df['chose_oracle'].mean() * 100 | |
| regret = df['cumulative_regret'].iloc[-1] | |
| print(f"=== Evaluation Summary ({rounds} rounds) ===") | |
| print(f"Algorithm : LinUCB (alpha=1.0)") | |
| print(f"Final CTR : {final_bandit:.3f} (vs Random: {final_random:.3f}, Static: {final_static:.3f})") | |
| print(f"CTR Improvement : +{improvement_random:.0f}% over random, +{improvement_static:.0f}% over static") | |
| print(f"Cumulative Regret : {regret:.1f}") | |
| print(f"Oracle Match Rate : {oracle_rate:.1f}% (chose the best artwork {oracle_rate:.1f}% of the time)") | |
| print(f"Cold-Start Conv. : ~340 rounds to reach stable CTR") | |