DawnC commited on
Commit
0d70940
1 Parent(s): 16aab35

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +215 -360
scoring_calculation_system.py CHANGED
@@ -409,7 +409,7 @@ def calculate_additional_factors(breed_info: dict, user_prefs: 'UserPreferences'
409
 
410
 
411
  def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences) -> dict:
412
- """計算品種與使用者條件的相容性分數的優化版本"""
413
  try:
414
  print(f"Processing breed: {breed_info.get('Breed', 'Unknown')}")
415
  print(f"Breed info keys: {breed_info.keys()}")
@@ -417,192 +417,10 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
417
  if 'Size' not in breed_info:
418
  print("Missing Size information")
419
  raise KeyError("Size information missing")
420
-
421
-
422
- # def calculate_space_score(size: str, living_space: str, has_yard: bool, exercise_needs: str) -> float:
423
- # """
424
- # 主要改進:
425
- # 1. 更均衡的基礎分數分配
426
- # 2. 更細緻的空間需求評估
427
- # 3. 強化運動需求與空間的關聯性
428
- # """
429
- # # 重新設計基礎分數矩陣,降低普遍分數以增加區別度
430
- # base_scores = {
431
- # "Small": {
432
- # "apartment": 0.90, # 降低滿分機會
433
- # "house_small": 0.85, # 小型犬不應在大空間得到太高分數
434
- # "house_large": 0.80 # 避免小型犬總是得到最高分
435
- # },
436
- # "Medium": {
437
- # "apartment": 0.40, # 維持對公寓環境的限制
438
- # "house_small": 0.80, # 適中的分數
439
- # "house_large": 0.90 # 給予合理的獎勵
440
- # },
441
- # "Large": {
442
- # "apartment": 0.10, # 加重對大型犬在公寓的限制
443
- # "house_small": 0.60, # 中等適合度
444
- # "house_large": 0.95 # 最適合的環境
445
- # },
446
- # "Giant": {
447
- # "apartment": 0.10, # 更嚴格的限制
448
- # "house_small": 0.45, # 顯著的空間限制
449
- # "house_large": 0.95 # 最理想的配對
450
- # }
451
- # }
452
-
453
- # # 取得基礎分數
454
- # base_score = base_scores.get(size, base_scores["Medium"])[living_space]
455
-
456
- # # 運動需求相關的調整更加動態
457
- # exercise_adjustments = {
458
- # "Very High": {
459
- # "apartment": -0.25, # 加重在受限空間的懲罰
460
- # "house_small": -0.15,
461
- # "house_large": -0.05
462
- # },
463
- # "High": {
464
- # "apartment": -0.20,
465
- # "house_small": -0.10,
466
- # "house_large": 0
467
- # },
468
- # "Moderate": {
469
- # "apartment": -0.10,
470
- # "house_small": -0.05,
471
- # "house_large": 0
472
- # },
473
- # "Low": {
474
- # "apartment": 0.05, # 低運動需求在小空間反而有優勢
475
- # "house_small": 0,
476
- # "house_large": -0.05 # 輕微降低評分,因為空間可能過大
477
- # }
478
- # }
479
-
480
- # # 根據空間類型獲取運動需求調整
481
- # adjustment = exercise_adjustments.get(exercise_needs,
482
- # exercise_adjustments["Moderate"])[living_space]
483
-
484
- # # 院子效益根據品種大小和運動需求動態調整
485
- # if has_yard:
486
- # yard_bonus = {
487
- # "Giant": 0.20,
488
- # "Large": 0.15,
489
- # "Medium": 0.10,
490
- # "Small": 0.05
491
- # }.get(size, 0.10)
492
-
493
- # # 運動需求會影響院子的重要性
494
- # if exercise_needs in ["Very High", "High"]:
495
- # yard_bonus *= 1.2
496
- # elif exercise_needs == "Low":
497
- # yard_bonus *= 0.8
498
-
499
- # current_score = base_score + adjustment + yard_bonus
500
- # else:
501
- # current_score = base_score + adjustment
502
-
503
- # # 確保分數在合理範圍內,但避免極端值
504
- # return min(0.95, max(0.15, current_score))
505
-
506
-
507
- # def calculate_exercise_score(breed_needs: str, exercise_time: int, exercise_type: str) -> float:
508
- # """
509
- # 精確評估品種運動需求與使用者運動條件的匹配度
510
-
511
- # Parameters:
512
- # breed_needs: 品種的運動需求等級
513
- # exercise_time: 使用者能提供的運動時間(分鐘)
514
- # exercise_type: 使用者偏好的運動類型
515
-
516
- # Returns:
517
- # float: -0.2 到 0.2 之間的��配分數
518
- # """
519
- # # 定義更細緻的運動需求等級
520
- # exercise_levels = {
521
- # 'VERY HIGH': {
522
- # 'min': 120,
523
- # 'ideal': 150,
524
- # 'max': 180,
525
- # 'intensity': 'high',
526
- # 'sessions': 'multiple',
527
- # 'preferred_types': ['active_training', 'intensive_exercise']
528
- # },
529
- # 'HIGH': {
530
- # 'min': 90,
531
- # 'ideal': 120,
532
- # 'max': 150,
533
- # 'intensity': 'moderate_high',
534
- # 'sessions': 'multiple',
535
- # 'preferred_types': ['active_training', 'moderate_activity']
536
- # },
537
- # 'MODERATE HIGH': {
538
- # 'min': 70,
539
- # 'ideal': 90,
540
- # 'max': 120,
541
- # 'intensity': 'moderate',
542
- # 'sessions': 'flexible',
543
- # 'preferred_types': ['moderate_activity', 'active_training']
544
- # },
545
- # 'MODERATE': {
546
- # 'min': 45,
547
- # 'ideal': 60,
548
- # 'max': 90,
549
- # 'intensity': 'moderate',
550
- # 'sessions': 'flexible',
551
- # 'preferred_types': ['moderate_activity', 'light_walks']
552
- # },
553
- # 'MODERATE LOW': {
554
- # 'min': 30,
555
- # 'ideal': 45,
556
- # 'max': 70,
557
- # 'intensity': 'light_moderate',
558
- # 'sessions': 'flexible',
559
- # 'preferred_types': ['light_walks', 'moderate_activity']
560
- # },
561
- # 'LOW': {
562
- # 'min': 15,
563
- # 'ideal': 30,
564
- # 'max': 45,
565
- # 'intensity': 'light',
566
- # 'sessions': 'single',
567
- # 'preferred_types': ['light_walks']
568
- # }
569
- # }
570
-
571
- # # 獲取品種的運動需求配置
572
- # breed_level = exercise_levels.get(breed_needs.upper(), exercise_levels['MODERATE'])
573
-
574
- # # 計算時間匹配度(使用更平滑的評分曲線)
575
- # if exercise_time >= breed_level['ideal']:
576
- # if exercise_time > breed_level['max']:
577
- # # 運動時間過長,適度降分
578
- # time_score = 0.15 - (0.08 * (exercise_time - breed_level['max']) / 30)
579
- # else:
580
- # time_score = 0.15
581
- # elif exercise_time >= breed_level['min']:
582
- # # 在最小需求和理想需求之間,線性計算分數
583
- # time_ratio = (exercise_time - breed_level['min']) / (breed_level['ideal'] - breed_level['min'])
584
- # time_score = 0.05 + (time_ratio * 0.10)
585
- # else:
586
- # # 運動時間不足,根據差距程度扣分
587
- # time_ratio = max(0, exercise_time / breed_level['min'])
588
- # time_score = -0.20 * (1 - time_ratio)
589
-
590
- # # 運動類型匹配度評估
591
- # type_score = 0.0
592
- # if exercise_type in breed_level['preferred_types']:
593
- # type_score = 0.05
594
- # if exercise_type == breed_level['preferred_types'][0]:
595
- # type_score = 0.08 # 最佳匹配類型給予更高分數
596
-
597
- # return max(-0.2, min(0.2, time_score + type_score))
598
-
599
 
600
  def calculate_space_score(size: str, living_space: str, has_yard: bool, exercise_needs: str) -> float:
601
  """
602
- 改進的空間評分系統,提供更細緻的居住環境評估
603
-
604
- 改進重點:
605
- 1. 更動態的基礎分數矩陣
606
  2. 強化空間品質評估
607
  3. 增加極端情況處理
608
  4. 考慮不同空間組合的協同效應
@@ -1479,210 +1297,212 @@ def calculate_environmental_fit(breed_info: dict, user_prefs: UserPreferences) -
1479
 
1480
  # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1481
  # """
1482
- # 改進的品種相容性評分系統,提供更動態和精確的評分
1483
-
1484
- # 主要改進:
1485
- # 1. 更動態的權重系統
1486
- # 2. 更強的極端情況處理
1487
- # 3. 更精確的品種特性評估
1488
  # """
1489
- # def evaluate_condition_extremity():
1490
- # """評估使用者條件的極端程度"""
1491
- # extremity_count = 0
 
 
 
 
 
1492
 
1493
- # # 空間條件極端性
1494
- # if user_prefs.living_space == 'apartment' and breed_info['Size'] in ['Large', 'Giant']:
1495
- # extremity_count += 2
1496
- # elif user_prefs.living_space == 'house_large' and breed_info['Size'] == 'Small':
1497
- # extremity_count += 1
1498
 
1499
- # # 運動需求極端性
1500
  # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1501
- # if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time < 60:
1502
- # extremity_count += 2
1503
- # elif exercise_needs == 'LOW' and user_prefs.exercise_time > 150:
1504
- # extremity_count += 1
 
 
1505
 
1506
- # # 經驗等級極端性
1507
  # care_level = breed_info.get('Care Level', 'MODERATE')
1508
- # if care_level == 'High' and user_prefs.experience_level == 'beginner':
1509
- # extremity_count += 2
 
 
 
 
 
 
 
 
1510
 
1511
- # return extremity_count
1512
 
1513
- # def calculate_dynamic_weights():
1514
  # """計算動態權重"""
1515
- # # 基礎權重
1516
- # weights = {
1517
  # 'space': 0.20,
1518
  # 'exercise': 0.20,
1519
- # 'experience': 0.15,
1520
  # 'grooming': 0.15,
1521
  # 'health': 0.15,
1522
- # 'noise': 0.15
1523
  # }
1524
 
1525
- # # 根據生活環境調整權重
1526
- # if user_prefs.living_space == 'apartment':
1527
- # weights['space'] *= 2.0
1528
- # weights['noise'] *= 1.8
1529
-
1530
- # # 根據家庭情況調整
1531
- # if user_prefs.has_children:
1532
- # if user_prefs.children_age == 'toddler':
1533
- # weights['noise'] *= 2.0
1534
- # weights['experience'] *= 1.8
1535
- # weights['health'] *= 1.5
1536
- # elif user_prefs.children_age == 'school_age':
1537
- # weights['noise'] *= 1.5
1538
- # weights['experience'] *= 1.3
1539
 
1540
- # # 根據運動時間調整
1541
- # if user_prefs.exercise_time < 30:
1542
- # weights['exercise'] *= 2.5
1543
- # elif user_prefs.exercise_time > 150:
1544
- # weights['exercise'] *= 2.0
 
 
 
 
 
 
 
 
 
 
 
1545
 
1546
- # # 根據健康敏感度調整
1547
- # if user_prefs.health_sensitivity == 'high':
1548
- # weights['health'] *= 1.8
1549
 
1550
- # return weights
1551
 
1552
- # # 計算條件極端程度
1553
- # extremity_level = evaluate_condition_extremity()
1554
 
1555
  # # 計算動態權重
1556
- # weights = calculate_dynamic_weights()
1557
 
1558
  # # 正規化權重
1559
  # total_weight = sum(weights.values())
1560
  # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1561
 
1562
- # # 計算加權分數
1563
- # weighted_scores = {
1564
- # k: scores[k] * normalized_weights[k] for k in scores.keys()
1565
- # }
1566
-
1567
- # # 基礎分數
1568
- # base_score = sum(weighted_scores.values())
1569
 
 
 
 
 
 
 
 
 
 
 
 
1570
  # # 品種特性加成
1571
- # breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
1572
-
1573
- # # 根據極端程度調整最終分數
1574
- # if extremity_level >= 3:
1575
- # base_score *= 0.6 # 多個極端條件的嚴重懲罰
1576
- # elif extremity_level >= 2:
1577
- # base_score *= 0.8 # 較少極端條件的適度懲罰
1578
 
1579
- # # 完美匹配加成
1580
- # if all(score >= 0.8 for score in scores.values()):
1581
- # base_score *= 1.3
1582
 
1583
- # # 品種特性影響力隨匹配度增加
1584
- # bonus_weight = min(0.35, max(0.15, breed_bonus))
1585
-
1586
- # # 最終分數計算
1587
- # final_score = (base_score * (1.0 - bonus_weight)) + (breed_bonus * bonus_weight)
1588
-
1589
- # return min(1.0, max(0.0, final_score))
1590
-
1591
-
1592
- # def amplify_score_extreme(score: float) -> float:
1593
- # """
1594
- # 改進的分數轉換函數,提供更合理的分數分布
1595
-
1596
- # 特點:
1597
- # 1. 更大的分數範圍
1598
- # 2. 更平滑的轉換曲線
1599
- # 3. 更準確的極端情況處理
1600
- # """
1601
- # def sigmoid_transform(x: float, steepness: float = 10) -> float:
1602
- # """使用 sigmoid 函數實現更平滑的轉換"""
1603
- # import math
1604
- # return 1 / (1 + math.exp(-steepness * (x - 0.5)))
1605
-
1606
- # if score < 0.2:
1607
- # # 極差匹配:使用更低的起始分數
1608
- # base = 0.40
1609
- # range_score = 0.15
1610
- # position = score / 0.2
1611
- # return base + (sigmoid_transform(position) * range_score)
1612
-
1613
- # elif score < 0.4:
1614
- # # 較差匹配:緩慢增長
1615
- # base = 0.55
1616
- # range_score = 0.15
1617
- # position = (score - 0.2) / 0.2
1618
- # return base + (sigmoid_transform(position) * range_score)
1619
-
1620
- # elif score < 0.6:
1621
- # # 中等匹配:較大增長
1622
- # base = 0.70
1623
- # range_score = 0.15
1624
- # position = (score - 0.4) / 0.2
1625
- # return base + (sigmoid_transform(position) * range_score)
1626
-
1627
- # elif score < 0.8:
1628
- # # 良好匹配:快速增長
1629
- # base = 0.85
1630
- # range_score = 0.10
1631
- # position = (score - 0.6) / 0.2
1632
- # return base + (sigmoid_transform(position) * range_score)
1633
-
1634
- # elif score < 0.9:
1635
- # # 優秀匹配:接近最高分
1636
- # base = 0.95
1637
- # range_score = 0.03
1638
- # position = (score - 0.8) / 0.1
1639
- # return base + (sigmoid_transform(position) * range_score)
1640
-
1641
- # else:
1642
- # # 完美匹配:可能達到最高分
1643
- # base = 0.98
1644
- # range_score = 0.02
1645
- # position = (score - 0.9) / 0.1
1646
- # return base + (sigmoid_transform(position) * range_score)
1647
-
1648
 
1649
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1650
  """
1651
  重構的品種相容性評分系統
1652
- 目標:實現更大的分數差異和更高的頂部分數
1653
  """
1654
  def evaluate_perfect_conditions():
1655
- """評估完美條件匹配度"""
1656
  perfect_matches = {
1657
- 'size_match': False,
1658
- 'exercise_match': False,
1659
- 'experience_match': False,
1660
  'general_match': False
1661
  }
1662
 
1663
- # 體型與空間匹配
1664
  if user_prefs.living_space == 'apartment':
1665
- perfect_matches['size_match'] = breed_info['Size'] == 'Small'
 
 
 
 
 
 
 
 
 
 
 
 
1666
  elif user_prefs.living_space == 'house_large':
1667
- perfect_matches['size_match'] = breed_info['Size'] in ['Medium', 'Large']
 
 
 
 
 
1668
 
1669
- # 運動需求匹配
1670
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1671
- if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time >= 150:
1672
- perfect_matches['exercise_match'] = True
1673
- elif exercise_needs == 'LOW' and 30 <= user_prefs.exercise_time <= 90:
1674
- perfect_matches['exercise_match'] = True
1675
- elif 60 <= user_prefs.exercise_time <= 120:
1676
- perfect_matches['exercise_match'] = True
1677
-
1678
- # 經驗匹配
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1679
  care_level = breed_info.get('Care Level', 'MODERATE')
1680
- if care_level == 'High' and user_prefs.experience_level == 'advanced':
1681
- perfect_matches['experience_match'] = True
1682
- elif care_level == 'Low' and user_prefs.experience_level == 'beginner':
1683
- perfect_matches['experience_match'] = True
1684
- elif user_prefs.experience_level == 'intermediate':
1685
- perfect_matches['experience_match'] = True
 
 
 
 
 
 
 
 
 
 
 
 
 
1686
 
1687
  # 一般條件匹配
1688
  if all(score >= 0.85 for score in scores.values()):
@@ -1691,11 +1511,11 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
1691
  return perfect_matches
1692
 
1693
  def calculate_weights():
1694
- """計算動態權重"""
1695
  base_weights = {
1696
  'space': 0.20,
1697
  'exercise': 0.20,
1698
- 'experience': 0.20,
1699
  'grooming': 0.15,
1700
  'health': 0.15,
1701
  'noise': 0.10
@@ -1704,15 +1524,25 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
1704
  # 極端條件權重調整
1705
  multipliers = {}
1706
 
1707
- # 經驗權重調整
1708
  if user_prefs.experience_level == 'beginner':
1709
- multipliers['experience'] = 3.0 # 新手經驗極其重要
 
 
 
1710
  elif user_prefs.experience_level == 'advanced':
1711
- multipliers['experience'] = 2.5 # 專家經驗很重要
1712
-
1713
- # 運動需求權重調整
1714
- if user_prefs.exercise_time > 150:
1715
- multipliers['exercise'] = 3.0
 
 
 
 
 
 
 
1716
  elif user_prefs.exercise_time < 30:
1717
  multipliers['exercise'] = 3.5
1718
 
@@ -1721,12 +1551,37 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
1721
  multipliers['space'] = 2.5
1722
  multipliers['noise'] = 2.0
1723
 
 
 
 
 
1724
  # 應用乘數
1725
  for key, multiplier in multipliers.items():
1726
  base_weights[key] *= multiplier
1727
 
1728
  return base_weights
1729
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1730
  # 評估完美匹配條件
1731
  perfect_conditions = evaluate_perfect_conditions()
1732
 
@@ -1740,23 +1595,23 @@ def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreference
1740
  # 計算基礎分數
1741
  base_score = sum(scores[k] * normalized_weights[k] for k in scores.keys())
1742
 
1743
- # 完美匹配獎勵
1744
  perfect_bonus = 1.0
1745
- if perfect_conditions['size_match']:
1746
- perfect_bonus += 0.2
1747
- if perfect_conditions['exercise_match']:
1748
- perfect_bonus += 0.2
1749
- if perfect_conditions['experience_match']:
1750
- perfect_bonus += 0.2
1751
  if perfect_conditions['general_match']:
1752
  perfect_bonus += 0.2
1753
 
1754
  # 品種特性加成
1755
- breed_bonus = calculate_breed_bonus(breed_info, user_prefs) * 1.5 # 增加品種特性影響
1756
 
1757
  # 計算最終分數
1758
  final_score = (base_score * 0.7 + breed_bonus * 0.3) * perfect_bonus
1759
 
 
 
 
1760
  return min(1.0, final_score)
1761
 
1762
 
 
409
 
410
 
411
  def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences) -> dict:
412
+ """計算品種與使用者條件的相容性分數"""
413
  try:
414
  print(f"Processing breed: {breed_info.get('Breed', 'Unknown')}")
415
  print(f"Breed info keys: {breed_info.keys()}")
 
417
  if 'Size' not in breed_info:
418
  print("Missing Size information")
419
  raise KeyError("Size information missing")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
 
421
  def calculate_space_score(size: str, living_space: str, has_yard: bool, exercise_needs: str) -> float:
422
  """
423
+ 1. 動態的基礎分數矩陣
 
 
 
424
  2. 強化空間品質評估
425
  3. 增加極端情況處理
426
  4. 考慮不同空間組合的協同效應
 
1297
 
1298
  # def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1299
  # """
1300
+ # 重構的品種相容性評分系統
1301
+ # 目標:實現更大的分數差異和更高的頂部分數
 
 
 
 
1302
  # """
1303
+ # def evaluate_perfect_conditions():
1304
+ # """評估完美條件匹配度"""
1305
+ # perfect_matches = {
1306
+ # 'size_match': False,
1307
+ # 'exercise_match': False,
1308
+ # 'experience_match': False,
1309
+ # 'general_match': False
1310
+ # }
1311
 
1312
+ # # 體型與空間匹配
1313
+ # if user_prefs.living_space == 'apartment':
1314
+ # perfect_matches['size_match'] = breed_info['Size'] == 'Small'
1315
+ # elif user_prefs.living_space == 'house_large':
1316
+ # perfect_matches['size_match'] = breed_info['Size'] in ['Medium', 'Large']
1317
 
1318
+ # # 運動需求匹配
1319
  # exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1320
+ # if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time >= 150:
1321
+ # perfect_matches['exercise_match'] = True
1322
+ # elif exercise_needs == 'LOW' and 30 <= user_prefs.exercise_time <= 90:
1323
+ # perfect_matches['exercise_match'] = True
1324
+ # elif 60 <= user_prefs.exercise_time <= 120:
1325
+ # perfect_matches['exercise_match'] = True
1326
 
1327
+ # # 經驗匹配
1328
  # care_level = breed_info.get('Care Level', 'MODERATE')
1329
+ # if care_level == 'High' and user_prefs.experience_level == 'advanced':
1330
+ # perfect_matches['experience_match'] = True
1331
+ # elif care_level == 'Low' and user_prefs.experience_level == 'beginner':
1332
+ # perfect_matches['experience_match'] = True
1333
+ # elif user_prefs.experience_level == 'intermediate':
1334
+ # perfect_matches['experience_match'] = True
1335
+
1336
+ # # 一般條件匹配
1337
+ # if all(score >= 0.85 for score in scores.values()):
1338
+ # perfect_matches['general_match'] = True
1339
 
1340
+ # return perfect_matches
1341
 
1342
+ # def calculate_weights():
1343
  # """計算動態權重"""
1344
+ # base_weights = {
 
1345
  # 'space': 0.20,
1346
  # 'exercise': 0.20,
1347
+ # 'experience': 0.20,
1348
  # 'grooming': 0.15,
1349
  # 'health': 0.15,
1350
+ # 'noise': 0.10
1351
  # }
1352
 
1353
+ # # 極端條件權重調整
1354
+ # multipliers = {}
 
 
 
 
 
 
 
 
 
 
 
 
1355
 
1356
+ # # 經驗權重調整
1357
+ # if user_prefs.experience_level == 'beginner':
1358
+ # multipliers['experience'] = 3.0 # 新手經驗極其重要
1359
+ # elif user_prefs.experience_level == 'advanced':
1360
+ # multipliers['experience'] = 2.5 # 專家經驗很重要
1361
+
1362
+ # # 運動需求權重調整
1363
+ # if user_prefs.exercise_time > 150:
1364
+ # multipliers['exercise'] = 3.0
1365
+ # elif user_prefs.exercise_time < 30:
1366
+ # multipliers['exercise'] = 3.5
1367
+
1368
+ # # 空間限制權重調整
1369
+ # if user_prefs.living_space == 'apartment':
1370
+ # multipliers['space'] = 2.5
1371
+ # multipliers['noise'] = 2.0
1372
 
1373
+ # # 應用乘數
1374
+ # for key, multiplier in multipliers.items():
1375
+ # base_weights[key] *= multiplier
1376
 
1377
+ # return base_weights
1378
 
1379
+ # # 評估完美匹配條件
1380
+ # perfect_conditions = evaluate_perfect_conditions()
1381
 
1382
  # # 計算動態權重
1383
+ # weights = calculate_weights()
1384
 
1385
  # # 正規化權重
1386
  # total_weight = sum(weights.values())
1387
  # normalized_weights = {k: v/total_weight for k, v in weights.items()}
1388
 
1389
+ # # 計算基礎分數
1390
+ # base_score = sum(scores[k] * normalized_weights[k] for k in scores.keys())
 
 
 
 
 
1391
 
1392
+ # # 完美匹配獎勵
1393
+ # perfect_bonus = 1.0
1394
+ # if perfect_conditions['size_match']:
1395
+ # perfect_bonus += 0.2
1396
+ # if perfect_conditions['exercise_match']:
1397
+ # perfect_bonus += 0.2
1398
+ # if perfect_conditions['experience_match']:
1399
+ # perfect_bonus += 0.2
1400
+ # if perfect_conditions['general_match']:
1401
+ # perfect_bonus += 0.2
1402
+
1403
  # # 品種特性加成
1404
+ # breed_bonus = calculate_breed_bonus(breed_info, user_prefs) * 1.5 # 增加品種特性影響
 
 
 
 
 
 
1405
 
1406
+ # # 計算最終分數
1407
+ # final_score = (base_score * 0.7 + breed_bonus * 0.3) * perfect_bonus
 
1408
 
1409
+ # return min(1.0, final_score)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1410
 
1411
  def calculate_breed_compatibility_score(scores: dict, user_prefs: UserPreferences, breed_info: dict) -> float:
1412
  """
1413
  重構的品種相容性評分系統
1414
+ 目標:實現更大的分數差異和更高的頂部分數,更精確的條件匹配
1415
  """
1416
  def evaluate_perfect_conditions():
1417
+ """評估完美條件匹配度,允許部分匹配"""
1418
  perfect_matches = {
1419
+ 'size_match': 0,
1420
+ 'exercise_match': 0,
1421
+ 'experience_match': 0,
1422
  'general_match': False
1423
  }
1424
 
1425
+ # 體型與空間匹配更細緻化
1426
  if user_prefs.living_space == 'apartment':
1427
+ if breed_info['Size'] == 'Small':
1428
+ perfect_matches['size_match'] = 1.0
1429
+ elif breed_info['Size'] == 'Medium':
1430
+ perfect_matches['size_match'] = 0.5
1431
+ else:
1432
+ perfect_matches['size_match'] = 0
1433
+ elif user_prefs.living_space == 'house_small':
1434
+ if breed_info['Size'] in ['Small', 'Medium']:
1435
+ perfect_matches['size_match'] = 1.0
1436
+ elif breed_info['Size'] == 'Large':
1437
+ perfect_matches['size_match'] = 0.6
1438
+ else:
1439
+ perfect_matches['size_match'] = 0.3
1440
  elif user_prefs.living_space == 'house_large':
1441
+ if breed_info['Size'] in ['Medium', 'Large']:
1442
+ perfect_matches['size_match'] = 1.0
1443
+ elif breed_info['Size'] == 'Small':
1444
+ perfect_matches['size_match'] = 0.7
1445
+ else:
1446
+ perfect_matches['size_match'] = 0.8
1447
 
1448
+ # 運動需求匹配更精確
1449
  exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1450
+ exercise_time = user_prefs.exercise_time
1451
+
1452
+ if exercise_needs == 'VERY HIGH':
1453
+ if exercise_time >= 150:
1454
+ perfect_matches['exercise_match'] = 1.0
1455
+ elif exercise_time >= 120:
1456
+ perfect_matches['exercise_match'] = 0.7
1457
+ elif exercise_time >= 90:
1458
+ perfect_matches['exercise_match'] = 0.4
1459
+ else:
1460
+ perfect_matches['exercise_match'] = 0
1461
+ elif exercise_needs == 'HIGH':
1462
+ if 120 <= exercise_time <= 150:
1463
+ perfect_matches['exercise_match'] = 1.0
1464
+ elif exercise_time >= 90:
1465
+ perfect_matches['exercise_match'] = 0.8
1466
+ elif exercise_time >= 60:
1467
+ perfect_matches['exercise_match'] = 0.5
1468
+ else:
1469
+ perfect_matches['exercise_match'] = 0.2
1470
+ elif exercise_needs == 'MODERATE':
1471
+ if 60 <= exercise_time <= 120:
1472
+ perfect_matches['exercise_match'] = 1.0
1473
+ elif exercise_time > 120:
1474
+ perfect_matches['exercise_match'] = 0.8
1475
+ else:
1476
+ perfect_matches['exercise_match'] = 0.6
1477
+ elif exercise_needs == 'LOW':
1478
+ if 30 <= exercise_time <= 90:
1479
+ perfect_matches['exercise_match'] = 1.0
1480
+ elif exercise_time > 90:
1481
+ perfect_matches['exercise_match'] = 0.7
1482
+ else:
1483
+ perfect_matches['exercise_match'] = 0.5
1484
+
1485
+ # 經驗匹配更細緻
1486
  care_level = breed_info.get('Care Level', 'MODERATE')
1487
+ if care_level == 'High':
1488
+ if user_prefs.experience_level == 'advanced':
1489
+ perfect_matches['experience_match'] = 1.0
1490
+ elif user_prefs.experience_level == 'intermediate':
1491
+ perfect_matches['experience_match'] = 0.6
1492
+ else:
1493
+ perfect_matches['experience_match'] = 0.2
1494
+ elif care_level == 'Moderate':
1495
+ if user_prefs.experience_level == 'advanced':
1496
+ perfect_matches['experience_match'] = 0.9
1497
+ elif user_prefs.experience_level == 'intermediate':
1498
+ perfect_matches['experience_match'] = 1.0
1499
+ else:
1500
+ perfect_matches['experience_match'] = 0.7
1501
+ elif care_level == 'Low':
1502
+ if user_prefs.experience_level == 'beginner':
1503
+ perfect_matches['experience_match'] = 1.0
1504
+ else:
1505
+ perfect_matches['experience_match'] = 0.9
1506
 
1507
  # 一般條件匹配
1508
  if all(score >= 0.85 for score in scores.values()):
 
1511
  return perfect_matches
1512
 
1513
  def calculate_weights():
1514
+ """計算更動態的權重"""
1515
  base_weights = {
1516
  'space': 0.20,
1517
  'exercise': 0.20,
1518
+ 'experience': 0.20,
1519
  'grooming': 0.15,
1520
  'health': 0.15,
1521
  'noise': 0.10
 
1524
  # 極端條件權重調整
1525
  multipliers = {}
1526
 
1527
+ # 經驗權重更細緻的調整
1528
  if user_prefs.experience_level == 'beginner':
1529
+ if breed_info.get('Care Level') == 'High':
1530
+ multipliers['experience'] = 3.5
1531
+ else:
1532
+ multipliers['experience'] = 3.0
1533
  elif user_prefs.experience_level == 'advanced':
1534
+ if breed_info.get('Care Level') == 'High':
1535
+ multipliers['experience'] = 2.8
1536
+ else:
1537
+ multipliers['experience'] = 2.5
1538
+
1539
+ # 運動需求更細緻的調整
1540
+ exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1541
+ if exercise_needs == 'VERY HIGH':
1542
+ if user_prefs.exercise_time < 90:
1543
+ multipliers['exercise'] = 4.0
1544
+ elif user_prefs.exercise_time > 150:
1545
+ multipliers['exercise'] = 3.0
1546
  elif user_prefs.exercise_time < 30:
1547
  multipliers['exercise'] = 3.5
1548
 
 
1551
  multipliers['space'] = 2.5
1552
  multipliers['noise'] = 2.0
1553
 
1554
+ # 噪音敏感度調整
1555
+ if user_prefs.noise_tolerance == 'low':
1556
+ multipliers['noise'] = multipliers.get('noise', 1.0) * 2.5
1557
+
1558
  # 應用乘數
1559
  for key, multiplier in multipliers.items():
1560
  base_weights[key] *= multiplier
1561
 
1562
  return base_weights
1563
 
1564
+ def apply_special_case_adjustments(score):
1565
+ """處理特殊情況"""
1566
+ # 新手不適合的特殊情況
1567
+ if user_prefs.experience_level == 'beginner':
1568
+ if (breed_info.get('Care Level') == 'High' and
1569
+ breed_info.get('Exercise Needs') == 'VERY HIGH'):
1570
+ score *= 0.7
1571
+
1572
+ # 運動時間極端不匹配的情況
1573
+ exercise_needs = breed_info.get('Exercise Needs', 'MODERATE').upper()
1574
+ if exercise_needs == 'VERY HIGH' and user_prefs.exercise_time < 60:
1575
+ score *= 0.6
1576
+
1577
+ # 噪音敏感度極端情況
1578
+ if (user_prefs.noise_tolerance == 'low' and
1579
+ breed_info.get('Breed') in breed_noise_info and
1580
+ breed_noise_info[breed_info['Breed']]['noise_level'].lower() == 'high'):
1581
+ score *= 0.7
1582
+
1583
+ return score
1584
+
1585
  # 評估完美匹配條件
1586
  perfect_conditions = evaluate_perfect_conditions()
1587
 
 
1595
  # 計算基礎分數
1596
  base_score = sum(scores[k] * normalized_weights[k] for k in scores.keys())
1597
 
1598
+ # 完美匹配獎勵更動態
1599
  perfect_bonus = 1.0
1600
+ perfect_bonus += 0.2 * perfect_conditions['size_match']
1601
+ perfect_bonus += 0.2 * perfect_conditions['exercise_match']
1602
+ perfect_bonus += 0.2 * perfect_conditions['experience_match']
 
 
 
1603
  if perfect_conditions['general_match']:
1604
  perfect_bonus += 0.2
1605
 
1606
  # 品種特性加成
1607
+ breed_bonus = calculate_breed_bonus(breed_info, user_prefs) * 1.5
1608
 
1609
  # 計算最終分數
1610
  final_score = (base_score * 0.7 + breed_bonus * 0.3) * perfect_bonus
1611
 
1612
+ # 應用特殊情況調整
1613
+ final_score = apply_special_case_adjustments(final_score)
1614
+
1615
  return min(1.0, final_score)
1616
 
1617