deacher commited on
Commit
25147f0
·
verified ·
1 Parent(s): e6f1da3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -21
app.py CHANGED
@@ -187,9 +187,10 @@ def get_unified_recommendations_api(
187
 
188
 
189
  # JALUR 2 & 3: Pengguna Baru (dengan atau tanpa probe)
190
- elif preferred_categories and probe_user_raw_ids:
191
- # Ini adalah jalur yang benar untuk probing (Logika dari model asli)
192
- print(f"Membuat rekomendasi untuk pengguna baru dengan preferensi: {preferred_categories} (NCF probe)")
 
193
 
194
  # 1. Validasi Kategori
195
  valid_categories = [cat for cat in preferred_categories if cat in df_wisata.columns and cat in list_kategori_wisata_valid_passed]
@@ -210,17 +211,32 @@ def get_unified_recommendations_api(
210
  else:
211
  candidate_wisata_df['google_rating_norm'] = 0.0
212
 
213
- # 4. Validasi Probe User IDs
 
 
 
 
 
 
 
 
 
 
 
 
214
  valid_probe_user_ids_int = []
 
215
  for raw_id in probe_user_raw_ids:
216
  try:
217
  valid_probe_user_ids_int.append(user_encoder_passed.transform([raw_id])[0])
218
  except ValueError:
219
- print(f"Warning: Probe user ID '{raw_id}' tidak dikenal.")
220
-
221
- # 5. Hitung Skor NCF untuk setiap kandidat wisata
 
 
222
  if not valid_probe_user_ids_int:
223
- print("Warning: Tidak ada probe user ID yang valid. NCF appeal score akan 0.")
224
  candidate_wisata_df['avg_ncf_appeal_score'] = 0.0
225
  else:
226
  avg_ncf_appeal_scores = []
@@ -251,26 +267,25 @@ def get_unified_recommendations_api(
251
 
252
  candidate_wisata_df['avg_ncf_appeal_score'] = avg_ncf_appeal_scores
253
 
254
- # 6. Hitung Skor Akhir dan Lakukan Ranking
255
  candidate_wisata_df['final_score %'] = (
256
  (weight_google_rating_new * candidate_wisata_df['google_rating_norm'].fillna(0) +
257
  weight_ncf_appeal_new * candidate_wisata_df['avg_ncf_appeal_score']) * 100
258
  )
259
  ranked_wisata = candidate_wisata_df.sort_values(by='final_score %', ascending=False).head(n)
260
 
261
- # 7. Kembalikan hasil dalam format yang diinginkan
262
  display_cols = ['ID Tempat', 'Nama Wisata', 'final_score %']
263
- return ranked_wisata[display_cols].to_dict(orient='records')
264
-
265
  else:
266
- # Jika tidak ada input yang valid
267
- return []
268
 
269
  # --- 5. Definisikan Request Body dengan Pydantic ---
270
  class RecommendationRequest(BaseModel):
271
- user_id: Optional[str] = Field(None, description="ID unik pengguna yang sudah ada di sistem.")
272
- preferred_categories: Optional[List[str]] = Field(None, description="List kategori yang disukai pengguna baru, cth: ['budaya', 'seni'].")
273
- probe_user_ids: Optional[List[str]] = Field(None, description="(Opsional) Daftar ID pengguna 'probe' untuk NCF hybrid.")
274
  n: int = Field(10, gt=0, le=50, description="Jumlah rekomendasi yang diinginkan.")
275
 
276
  class Config:
@@ -314,10 +329,6 @@ async def get_recommendations(request: RecommendationRequest):
314
  recommendations = get_unified_recommendations_api(
315
  raw_user_id=request.user_id,
316
  preferred_categories=request.preferred_categories,
317
-
318
- # Teruskan probe_user_ids ke fungsi utama
319
- probe_user_raw_ids=request.probe_user_ids,
320
-
321
  n=request.n
322
  )
323
 
 
187
 
188
 
189
  # JALUR 2 & 3: Pengguna Baru (dengan atau tanpa probe)
190
+ elif preferred_categories:
191
+ # Ini adalah jalur untuk pengguna baru dengan metode hybrid NCF probing.
192
+ # Probe users akan dipilih secara otomatis dan acak di server.
193
+ print(f"Membuat rekomendasi untuk pengguna baru dengan preferensi: {preferred_categories} (NCF probe otomatis)")
194
 
195
  # 1. Validasi Kategori
196
  valid_categories = [cat for cat in preferred_categories if cat in df_wisata.columns and cat in list_kategori_wisata_valid_passed]
 
211
  else:
212
  candidate_wisata_df['google_rating_norm'] = 0.0
213
 
214
+ # 4. Pilih Probe Users Secara Acak di Server (LOGIKA BARU)
215
+ all_known_users = list(user_encoder_passed.classes_)
216
+ if not all_known_users:
217
+ print("Warning: Tidak ada data pengguna di dalam sistem untuk melakukan probing. Rekomendasi tidak dapat dibuat.")
218
+ # Opsi: Jatuh ke metode fallback yang lebih sederhana (non-NCF) atau kembalikan kosong.
219
+ # Mengembalikan kosong lebih aman jika NCF adalah inti dari logika ini.
220
+ return []
221
+
222
+ num_to_sample = min(NUM_SAMPLES_FOR_PROBE, len(all_known_users))
223
+ probe_user_raw_ids = random.sample(all_known_users, num_to_sample)
224
+ print(f"Server memilih {len(probe_user_raw_ids)} probe users secara acak.")
225
+
226
+ # 5. Ubah Probe User IDs ke Format Integer (yang sebelumnya adalah Validasi)
227
  valid_probe_user_ids_int = []
228
+ # Loop ini tetap diperlukan untuk mengubah ID string acak menjadi integer untuk model
229
  for raw_id in probe_user_raw_ids:
230
  try:
231
  valid_probe_user_ids_int.append(user_encoder_passed.transform([raw_id])[0])
232
  except ValueError:
233
+ # Secara teori ini jarang terjadi jika `all_known_users` berasal dari sumber yang sama,
234
+ # tapi ini adalah pengaman yang baik.
235
+ print(f"Warning: Probe user ID '{raw_id}' yang dipilih secara acak tidak dikenal encoder.")
236
+
237
+ # 6. Hitung Skor NCF untuk Setiap Kandidat Wisata
238
  if not valid_probe_user_ids_int:
239
+ print("Warning: Tidak ada probe user ID yang valid setelah proses encoding. NCF appeal score akan 0.")
240
  candidate_wisata_df['avg_ncf_appeal_score'] = 0.0
241
  else:
242
  avg_ncf_appeal_scores = []
 
267
 
268
  candidate_wisata_df['avg_ncf_appeal_score'] = avg_ncf_appeal_scores
269
 
270
+ # 7. Hitung Skor Akhir dan Lakukan Ranking
271
  candidate_wisata_df['final_score %'] = (
272
  (weight_google_rating_new * candidate_wisata_df['google_rating_norm'].fillna(0) +
273
  weight_ncf_appeal_new * candidate_wisata_df['avg_ncf_appeal_score']) * 100
274
  )
275
  ranked_wisata = candidate_wisata_df.sort_values(by='final_score %', ascending=False).head(n)
276
 
277
+ # 8. Kembalikan Hasil dalam Format yang Diinginkan
278
  display_cols = ['ID Tempat', 'Nama Wisata', 'final_score %']
279
+ return ranked_wisata[[col for col in display_cols if col in ranked_wisata.columns]].to_dict(orient='records')
280
+
281
  else:
282
+ # Jika tidak ada input yang valid
283
+ return []
284
 
285
  # --- 5. Definisikan Request Body dengan Pydantic ---
286
  class RecommendationRequest(BaseModel):
287
+ user_id: Optional[str] = Field(None, description="ID unik pengguna yang sudah terdaftar.")
288
+ preferred_categories: Optional[List[str]] = Field(None, description="Daftar kategori yang disukai pengguna baru.")
 
289
  n: int = Field(10, gt=0, le=50, description="Jumlah rekomendasi yang diinginkan.")
290
 
291
  class Config:
 
329
  recommendations = get_unified_recommendations_api(
330
  raw_user_id=request.user_id,
331
  preferred_categories=request.preferred_categories,
 
 
 
 
332
  n=request.n
333
  )
334