Spaces:
Sleeping
Sleeping
Update scoring_calculation_system.py
Browse files- 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 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
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 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1350 |
|
1351 |
-
|
1352 |
-
|
|
|
|
|
|
|
|
|
1353 |
|
1354 |
-
# 4.
|
1355 |
-
|
|
|
|
|
|
|
1356 |
"""
|
1357 |
-
|
1358 |
-
|
1359 |
-
主要改進:
|
1360 |
-
1. 調整基礎計算參數以產生更明顯的差異
|
1361 |
-
2. 根據分數區間使用不同的放大策略
|
1362 |
-
3. 擴大最終分數範圍
|
1363 |
"""
|
1364 |
-
#
|
1365 |
-
|
1366 |
|
1367 |
-
#
|
1368 |
-
|
1369 |
|
1370 |
-
#
|
1371 |
-
|
1372 |
-
amplified *= 0.85 # 進一步降低不適合的配對
|
1373 |
-
elif score > 0.85: # 高分區間
|
1374 |
-
amplified = 0.85 + (amplified - 0.85) * 0.4 # 高分區間的緩和壓縮
|
1375 |
|
1376 |
-
#
|
1377 |
-
|
|
|
|
|
|
|
|
|
|
|
1378 |
|
1379 |
-
#
|
1380 |
-
|
|
|
|
|
|
|
|
|
1381 |
|
1382 |
-
#
|
1383 |
-
final_score = amplify_score(weighted_score)
|
1384 |
|
1385 |
-
#
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1390 |
|
1391 |
-
#
|
1392 |
-
|
1393 |
-
scores['overall'] = round(final_score, 4)
|
1394 |
|
1395 |
-
|
|
|
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)}")
|