# Donnees OOS : grille 8x8 seed 42 (bruit gaussien 0.3, valeurs a 1 decimale) -- identique au jumeau Infer.NET
oos_n_users = 8
oos_n_items = 8
oos_rank = 1 # structure aime/non-aime = bloc 2x2 -> rang latent 1 suffit
oos_grid = np.array([
[ 5.0, 3.7, 4.2, 4.3, 1.4, 1.0, 2.0, 1.0],
[ 4.0, 3.7, 4.3, 5.0, 1.0, 2.3, 1.1, 1.7],
[ 4.1, 3.7, 5.0, 4.0, 1.9, 1.0, 2.4, 1.0],
[ 3.9, 4.9, 4.2, 4.1, 1.1, 2.1, 1.6, 1.9],
[ 1.8, 1.0, 2.2, 1.3, 5.0, 3.7, 3.8, 4.2],
[ 1.2, 2.2, 1.0, 2.1, 4.0, 4.1, 4.3, 5.0],
[ 2.2, 1.0, 2.1, 1.2, 3.6, 3.9, 4.9, 3.8],
[ 1.0, 2.4, 1.0, 2.3, 3.5, 4.9, 4.0, 4.2],
])
# Entrainement : 4 notes par utilisateur (3 aimees + 1 non-aimee) = 32 observations
oos_user_obs = np.array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7])
oos_item_obs = np.array([1, 2, 3, 4, 0, 2, 3, 5, 0, 1, 3, 6, 0, 1, 2, 7, 5, 6, 7, 0, 4, 6, 7, 1, 4, 5, 7, 2, 4, 5, 6, 3])
oos_rating_obs = np.array([3.7, 4.2, 4.3, 1.4, 4.0, 4.3, 5.0, 2.3, 4.1, 3.7, 4.0, 2.4, 3.9, 4.9, 4.2, 1.9, 3.7, 3.8, 4.2, 1.8, 4.0, 4.3, 5.0, 2.2, 3.6, 3.9, 3.8, 2.1, 3.5, 4.9, 4.0, 2.3])
# Test (masque) : 2 notes par utilisateur (1 aimee + 1 non-aimee) = 16 observations invisibles
oos_test_user = np.array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7])
oos_test_item = np.array([0, 5, 1, 6, 2, 7, 3, 4, 4, 1, 5, 2, 6, 3, 7, 0])
oos_test_rating = np.array([5.0, 1.0, 3.7, 1.1, 5.0, 1.0, 4.1, 1.1, 5.0, 1.0, 4.1, 1.0, 4.9, 1.2, 4.2, 1.0])
# 16 autres paires restent inobservees (masque) : bras cold-start / extension, non utilisees par l'inference
n_oos_train = len(oos_rating_obs)
n_oos_test = len(oos_test_rating)
print(f"OOS : {n_oos_train} notes train (+{n_oos_test} masquees), grille {oos_n_users}x{oos_n_items} (seed 42)")
# Chaque item doit rester represente en entrainement (sinon la tache devient du cold-start)
for k in range(oos_n_items):
c = int((oos_item_obs == k).sum())
if c == 0:
print(f" WARN : item {k} absent du train")
print("Representativite : chaque item present en train (0 WARN attendu).")