AdvancedTopics: recommend_for_client.py

File recommend_for_client.py, 2.9 KB (added by 231040, 2 weeks ago)
Line 
1from sentence_transformers import SentenceTransformer
2import psycopg2
3import numpy as np
4
5model = SentenceTransformer('all-MiniLM-L6-v2')
6
7conn = psycopg2.connect(
8 host="localhost",
9 port="5432",
10 database="your_db_name",
11 user="your_db_user",
12 password="your_password"
13)
14
15cur = conn.cursor()
16
17client_id = input("Enter client_id: ")
18
19# =========================
20# 1. GET CLIENT HISTORY
21# =========================
22cur.execute("""
23 SELECT s.embedding
24 FROM appointment a
25 JOIN appointment_service aps
26 ON a.appointment_id = aps.appointment_id
27 JOIN service s
28 ON aps.service_id = s.service_id
29 WHERE a.client_id = %s
30""", (client_id,))
31
32history = cur.fetchall()
33
34if not history:
35 print("No history found for this client. Using cold-start mode.")
36
37 # fallback: generic query vector
38 user_query = input("What are you looking for? ")
39 client_vector = model.encode(user_query)
40
41else:
42 # =========================
43 # 2. BUILD USER PROFILE VECTOR
44 # =========================
45 embeddings = [np.array(row[0]) for row in history]
46 client_vector = np.mean(embeddings, axis=0)
47
48# =========================
49# 3. FETCH ALL SERVICES
50# =========================
51cur.execute("""
52 SELECT
53 s.service_id,
54 s.service_name,
55 sc.category_name,
56 s.price,
57 s.embedding,
58 s.avg_rating,
59 s.popularity
60 FROM service s
61 JOIN service_category sc
62 ON s.service_category_id = sc.service_category_id
63 WHERE s.embedding IS NOT NULL
64""")
65
66rows = cur.fetchall()
67
68service_embeddings = np.array([r[4] for r in rows])
69
70# =========================
71# 4. VECTORIZED SIMILARITY
72# =========================
73norms = np.linalg.norm(service_embeddings, axis=1) * np.linalg.norm(client_vector)
74
75similarities = (service_embeddings @ client_vector) / norms
76
77# =========================
78# 5. SCORING
79# =========================
80results = []
81
82for i, row in enumerate(rows):
83
84 service_id, name, category, price, _, rating, popularity = row
85
86 rating_score = rating / 5
87 popularity_score = min(popularity / 50, 1)
88
89 final_score = (
90 similarities[i] * 0.75 +
91 rating_score * 0.15 +
92 popularity_score * 0.10
93 )
94
95 results.append({
96 "service": name,
97 "category": category,
98 "price": price,
99 "score": final_score
100 })
101
102# =========================
103# 6. SORT + FILTER
104# =========================
105results.sort(key=lambda x: x["score"], reverse=True)
106
107seen = set()
108
109print("\nPersonalized recommendations:\n")
110
111count = 0
112
113for r in results:
114
115 if r["service"] in seen:
116 continue
117
118 seen.add(r["service"])
119
120 print(
121 f"{r['service']} | {r['category']} | {r['price']} | Score: {r['score']:.3f}"
122 )
123
124 count += 1
125 if count == 5:
126 break
127
128cur.close()
129conn.close()