Skip to content

Instantly share code, notes, and snippets.

@qathom
Created November 10, 2021 20:02
Show Gist options
  • Save qathom/3e4f7a88805e299a0f538d44fbfbbe5e to your computer and use it in GitHub Desktop.
Save qathom/3e4f7a88805e299a0f538d44fbfbbe5e to your computer and use it in GitHub Desktop.
Interactive CRS (minimal approach)
from scipy import spatial
import math
# User preferences/interests
user_embedding = [0, 0, 0, 0]
# Item representation { PRODUCT TYPE (1=MOUSE), COLOR (1=BLACK), MULTI_DEVICE (1=YES), HIGH_DPI (1=YES) }
item_embeddings = [
[1, 0, 0, 0],
[1, 1, 0, 1],
[1, 0, 0, 1],
[1, 1, 1, 1],
[1, 0, 1, 0],
[0, 1, 1, 0],
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 0, 1, 0],
[1, 1, 1, 0],
]
# Session based
likes = []
forbidden = []
def build_item_score(item, P):
s = 0
for i, p in enumerate(P):
if item[i] == p:
s += 1
return s / len(P)
def build_sim_score(item, L):
best_cos = 0
for l in L:
liked_item = item_embeddings[l]
s = sim_cos_score(item, liked_item)
if s > best_cos:
best_cos = s
return best_cos
def get_available_items():
l = item_embeddings.copy()
for f in forbidden:
l.pop(f)
return l
def sim_cos_score(i1, i2):
return 1 - spatial.distance.cosine(i1, i2)
def sigmoid(x):
return 1 / (1 + math.exp(-x))
def build_scores():
candidates = get_available_items()
scores = []
for item in candidates:
# User - Item comparison
s1 = build_item_score(item, user_embedding)
# Item - Item comparison
s2 = build_sim_score(item, likes)
# Normalize score
sf = sigmoid(s1 + s2)
scores.append(sf)
return scores
current_turn = 0
max_turns = 5
# Conversation simulation based on defined questionnaire
# Basically, we start with an user_embedding of zero values only
# Turn 1: zero values
# Turn 2: user wants a MOUSE [1, 0, 0, 0]
# Turn 3: user wants a mouse which is BLACK [1, 1, 0, 0]
# Turn 4: user wants a mouse which is BLACK and is supporting multi-devices [1, 1, 1, 0]
# Best results have indexes 3 and 9 in item_embeddings = [1, 1, 1, 0]
# Turn 5: user likes index=1 of item_embeddings = [1, 1, 0, 1] which is not supporting multi device but high DPI becomes another priority (preference)
# Best recommendation is now index=3 = [1, 1, 1, 1]
while current_turn < max_turns:
if current_turn == 1:
user_embedding = [1, 0, 0]
if current_turn == 2:
user_embedding = [1, 1, 0]
if current_turn == 3:
user_embedding = [1, 1, 1]
if current_turn == 4:
likes = [2]
print('TURN', current_turn + 1, build_scores())
current_turn += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment