DawnC commited on
Commit
2fcf095
1 Parent(s): 470297d

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +88 -63
scoring_calculation_system.py CHANGED
@@ -1317,82 +1317,107 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
1317
  }
1318
 
1319
  # 2. 優化權重配置 - 根據使用者情況動態調整權重
1320
- base_weights = {
1321
- 'space': 0.28,
1322
- 'exercise': 0.18,
1323
- 'grooming': 0.12,
1324
- 'experience': 0.22,
1325
- 'health': 0.12,
1326
- 'noise': 0.08
1327
- }
1328
-
1329
- # 根據特殊情況調整權重
1330
- weights = base_weights.copy()
1331
-
1332
- # 有孩童時的權重調整
1333
- if user_prefs.has_children:
1334
- if user_prefs.children_age == 'toddler':
1335
- weights['experience'] *= 1.4 # 幼童需要更有經驗的配對
1336
- weights['noise'] *= 1.3 # 噪音影響更重要
1337
- weights['health'] *= 1.2 # 健康因素更關鍵
1338
- elif user_prefs.children_age == 'school_age':
1339
- weights['experience'] *= 1.2
1340
- weights['noise'] *= 1.2
1341
 
1342
- # 居住環境的權重調整
1343
- if user_prefs.living_space == 'apartment':
1344
- weights['space'] *= 1.3 # 空間限制更重要
1345
- weights['noise'] *= 1.2 # 噪音影響更顯著
1346
-
1347
- # 重新正規化權重
1348
- total_weight = sum(weights.values())
1349
- weights = {k: v/total_weight for k, v in weights.items()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1350
 
1351
- # 3. 計算加權總分
1352
- weighted_score = sum(score * weights[category] for category, score in scores.items())
 
 
 
 
1353
 
1354
- # 4. 改進的分數放大函數
1355
- def amplify_score(score):
 
 
 
1356
  """
1357
- 改進的分數放大函數,提供更大的分數差異。
1358
-
1359
- 主要改進:
1360
- 1. 調整基礎計算參數以產生更明顯的差異
1361
- 2. 根據分數區間使用不同的放大策略
1362
- 3. 擴大最終分數範圍
1363
  """
1364
- # 基礎調整,擴大差異
1365
- adjusted = (score - 0.4) * 2.0 # 從0.35調整到0.4,倍數從1.8提高到2.0
1366
 
1367
- # 使用更陡峭的曲線,從3.2降到2.8使曲線不會過於極端
1368
- amplified = pow(adjusted, 2.8) / 4.5 + score
1369
 
1370
- # 分數區間處理
1371
- if score < 0.65: # 低分區間
1372
- amplified *= 0.85 # 進一步降低不適合的配對
1373
- elif score > 0.85: # 高分區間
1374
- amplified = 0.85 + (amplified - 0.85) * 0.4 # 高分區間的緩和壓縮
1375
 
1376
- # 擴大分數範圍到0.45-0.95,原本是0.55-0.95
1377
- final_score = max(0.45, min(0.95, amplified))
 
 
 
 
 
1378
 
1379
- # 四捨五入到小數點後第三位
1380
- return round(final_score, 3)
 
 
 
 
1381
 
1382
- # 5. 計算最終分數並應用關鍵條件檢查
1383
- final_score = amplify_score(weighted_score)
1384
 
1385
- # 針對特殊情況的最終調整
1386
- if user_prefs.has_children and scores['experience'] < 0.4:
1387
- final_score *= 0.8 # 有孩童但經驗分數過低時大幅降低
1388
- if user_prefs.living_space == 'apartment' and scores['noise'] < 0.3:
1389
- final_score *= 0.75 # 住公寓但噪音分數極低時顯著降低
 
 
 
 
 
 
 
 
 
1390
 
1391
- # 6. 準備返回結果
1392
- scores = {k: round(v, 4) for k, v in scores.items()}
1393
- scores['overall'] = round(final_score, 4)
1394
 
1395
- return scores
 
1396
 
1397
  except Exception as e:
1398
  print(f"Error details: {str(e)}")
 
1317
  }
1318
 
1319
  # 2. 優化權重配置 - 根據使用者情況動態調整權重
1320
+ def get_adjusted_weights(user_prefs, scores):
1321
+ """
1322
+ 根據使用者條件動態調整各項評分的權重。
1323
+ 確保權重調整合理,避免過度偏移。
1324
+ """
1325
+ weights = {
1326
+ 'space': 0.28,
1327
+ 'exercise': 0.18,
1328
+ 'grooming': 0.12,
1329
+ 'experience': 0.22,
1330
+ 'health': 0.12,
1331
+ 'noise': 0.08
1332
+ }
 
 
 
 
 
 
 
 
1333
 
1334
+ # 公寓住戶需要更注重空間和噪音
1335
+ if user_prefs.living_space == 'apartment':
1336
+ if scores['space'] < 0.6: # 空間評分不理想時更重視
1337
+ weights['space'] *= 1.25
1338
+ weights['noise'] *= 1.15
1339
+
1340
+ # 新手飼主需要更注重經驗要求
1341
+ if user_prefs.experience_level == 'beginner':
1342
+ if scores['experience'] < 0.5: # 經驗需求較高時更重視
1343
+ weights['experience'] *= 1.3
1344
+
1345
+ # 有孩童時的特殊考量
1346
+ if user_prefs.has_children:
1347
+ child_age_weights = {
1348
+ 'toddler': {'experience': 1.3, 'health': 1.2, 'noise': 1.2},
1349
+ 'school_age': {'experience': 1.2, 'health': 1.1, 'noise': 1.1},
1350
+ 'teenager': {'experience': 1.1, 'health': 1.05, 'noise': 1.05}
1351
+ }
1352
+
1353
+ age_adjustments = child_age_weights.get(user_prefs.children_age,
1354
+ child_age_weights['school_age'])
1355
+ for key, mult in age_adjustments.items():
1356
+ weights[key] *= mult
1357
 
1358
+ # 重新正規化權重總和為1
1359
+ total = sum(weights.values())
1360
+ return {k: v/total for k, v in weights.items()}
1361
+
1362
+ # 3. 套用調整後的權重
1363
+ weights = get_adjusted_weights(user_prefs, scores)
1364
 
1365
+ # 4. 計算初始加權分數
1366
+ weighted_score = sum(score * weights[category] for category, score in scores.items())
1367
+
1368
+ # 5. 改進的分數放大函數
1369
+ def amplify_score(raw_score, scores, user_prefs):
1370
  """
1371
+ 優化的分數放大函數,確保分數分布合理且有意義。
1372
+ 考慮原始分數的分布和關鍵條件的影響。
 
 
 
 
1373
  """
1374
+ # 基礎轉換:將分數範圍從[0.1-1.0]映射到[0-1]
1375
+ normalized = (raw_score - 0.1) / 0.9
1376
 
1377
+ # 使用S型曲線轉換,使中間範圍的差異更明顯
1378
+ transformed = 1 / (1 + math.exp(-6 * (normalized - 0.5)))
1379
 
1380
+ # 將分數映射回目標範圍[0.6-0.95]
1381
+ score = 0.6 + transformed * 0.35
 
 
 
1382
 
1383
+ # 關鍵條件檢查和調整
1384
+ critical_conditions = [
1385
+ (scores['experience'] < 0.4 and user_prefs.has_children, 0.85),
1386
+ (scores['noise'] < 0.3 and user_prefs.living_space == 'apartment', 0.85),
1387
+ (scores['health'] < 0.3, 0.9),
1388
+ (scores['space'] < 0.3 and user_prefs.living_space == 'apartment', 0.85)
1389
+ ]
1390
 
1391
+ # 應用關鍵條件調整
1392
+ for condition, factor in critical_conditions:
1393
+ if condition:
1394
+ score *= factor
1395
+
1396
+ return round(max(0.6, min(0.95, score)), 4)
1397
 
1398
+ # 6. 計算最終分數
1399
+ final_score = amplify_score(weighted_score, scores, user_prefs)
1400
 
1401
+ # 7. 確保分數差異性
1402
+ def adjust_final_scores(base_scores, final_score):
1403
+ """
1404
+ 確保最終分數能反映品種間的實際差異。
1405
+ """
1406
+ scores = base_scores.copy()
1407
+ scores['overall'] = final_score
1408
+
1409
+ # 檢查是否有極端低分項目
1410
+ min_score = min(v for k, v in base_scores.items())
1411
+ if min_score < 0.4: # 如果有特別低的分數
1412
+ scores['overall'] *= 0.92 # 適度降低整體評分
1413
+
1414
+ return scores
1415
 
1416
+ # 8. 準備最終結果
1417
+ final_scores = adjust_final_scores(scores, final_score)
 
1418
 
1419
+ # 四捨五入所有分數
1420
+ return {k: round(v, 4) for k, v in final_scores.items()}
1421
 
1422
  except Exception as e:
1423
  print(f"Error details: {str(e)}")