Update app.py
Browse files
app.py
CHANGED
|
@@ -7,7 +7,7 @@ from fastapi import FastAPI, HTTPException
|
|
| 7 |
from pydantic import BaseModel
|
| 8 |
from sentence_transformers import SentenceTransformer
|
| 9 |
import os
|
| 10 |
-
from typing import Optional, List
|
| 11 |
|
| 12 |
|
| 13 |
#####################################
|
|
@@ -1026,71 +1026,65 @@ def cosine_similarity(vec1, vec2):
|
|
| 1026 |
return 0.0
|
| 1027 |
return float(np.dot(vec1, vec2) / (norm1 * norm2))
|
| 1028 |
|
| 1029 |
-
def recommend_content_based(user_profile, top_n=5):
|
| 1030 |
user_emb = get_user_embedding(user_profile)
|
| 1031 |
scored = []
|
|
|
|
| 1032 |
|
| 1033 |
-
# ๐ข ๋ค์ค
|
| 1034 |
user_hobbies = user_profile.get("hobby", []) or []
|
| 1035 |
user_details = user_profile.get("detail_hobby", []) or []
|
| 1036 |
-
|
| 1037 |
user_extroversion = user_profile.get("extroversion", "")
|
| 1038 |
user_feeling_thinking = user_profile.get("feeling_thinking", "")
|
| 1039 |
|
| 1040 |
-
hobby_count = {hobby: 0 for hobby in user_hobbies} # ์ทจ๋ฏธ๋ณ ์ถ์ฒ ๊ฐ์ ์ ํ
|
| 1041 |
-
|
| 1042 |
for item in items:
|
| 1043 |
item_id = item["item_id"]
|
|
|
|
|
|
|
|
|
|
| 1044 |
item_emb = item_embedding_dict[item_id]
|
| 1045 |
sim = cosine_similarity(user_emb, item_emb)
|
| 1046 |
|
| 1047 |
# ๊ธฐ๋ณธ ๊ฐ์ค์น
|
| 1048 |
weight = 1.0
|
| 1049 |
|
| 1050 |
-
# (1) ์ทจ๋ฏธ ๊ฐ์ค์น
|
| 1051 |
desc_hobby = extract_hobby(item["desc"]) # ์: "(์ด๋, ํฌ์ค)"
|
| 1052 |
-
|
| 1053 |
for h in user_hobbies:
|
| 1054 |
if h in desc_hobby:
|
| 1055 |
-
weight *= 1.
|
| 1056 |
-
hobby_count[h] += 1
|
| 1057 |
|
|
|
|
| 1058 |
for dh in user_details:
|
| 1059 |
if dh in desc_hobby:
|
| 1060 |
-
weight *= 1.3
|
| 1061 |
|
| 1062 |
-
# (
|
| 1063 |
personality_match_count = sum(
|
| 1064 |
trait in item["personality"]
|
| 1065 |
for trait in [user_extroversion, user_feeling_thinking]
|
| 1066 |
)
|
| 1067 |
if personality_match_count == 1:
|
| 1068 |
-
weight *= 1.
|
| 1069 |
elif personality_match_count == 2:
|
| 1070 |
-
weight *= 1.
|
| 1071 |
|
| 1072 |
final_score = sim * weight
|
| 1073 |
scored.append((item, final_score))
|
| 1074 |
|
| 1075 |
-
# ์ ์๊ฐ ๋์ ์์ผ๋ก ์ ๋ ฌ
|
| 1076 |
scored.sort(key=lambda x: x[1], reverse=True)
|
| 1077 |
|
| 1078 |
-
# ๐ข
|
| 1079 |
-
|
| 1080 |
-
|
| 1081 |
-
|
| 1082 |
-
for item, score in scored:
|
| 1083 |
-
item_hobby = extract_hobby(item["desc"]) # "(๋
์, ์์ค)" โ "๋
์, ์์ค"
|
| 1084 |
-
item_main_hobby = item_hobby.split(", ")[0] if item_hobby else None
|
| 1085 |
-
|
| 1086 |
-
# ํน์ ์ทจ๋ฏธ๊ฐ ์ด๋ฏธ ๋๋ฌด ๋ง๋ค๋ฉด ์คํต
|
| 1087 |
-
if item_main_hobby and hobby_limits.get(item_main_hobby, 0) > 0:
|
| 1088 |
-
balanced_recommendations.append((item, score))
|
| 1089 |
-
hobby_limits[item_main_hobby] -= 1
|
| 1090 |
-
|
| 1091 |
-
# ์ถ์ฒ ๊ฐ์๊ฐ ์ถฉ๋ถํ ์ฑ์์ง ๋๊น์ง ๊ณ์ ์ถ์ฒ
|
| 1092 |
-
if len(balanced_recommendations) >= top_n:
|
| 1093 |
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1094 |
|
| 1095 |
# ์ถ์ฒ ๊ฐ์๊ฐ ๋ถ์กฑํ๋ค๋ฉด, ๋๋จธ์ง ์ถ์ฒ์ ์ถ๊ฐ
|
| 1096 |
if len(balanced_recommendations) < top_n:
|
|
|
|
| 7 |
from pydantic import BaseModel
|
| 8 |
from sentence_transformers import SentenceTransformer
|
| 9 |
import os
|
| 10 |
+
from typing import Optional, List,Dict
|
| 11 |
|
| 12 |
|
| 13 |
#####################################
|
|
|
|
| 1026 |
return 0.0
|
| 1027 |
return float(np.dot(vec1, vec2) / (norm1 * norm2))
|
| 1028 |
|
| 1029 |
+
def recommend_content_based(user_profile: dict, top_n=5):
|
| 1030 |
user_emb = get_user_embedding(user_profile)
|
| 1031 |
scored = []
|
| 1032 |
+
seen_items = set() # ์ค๋ณต ๋ฐฉ์ง๋ฅผ ์ํ ์งํฉ
|
| 1033 |
|
| 1034 |
+
# ๐ข ๋ค์ค ์ทจ๋ฏธ/์ธ๋ถ์ทจ๋ฏธ ์ง์
|
| 1035 |
user_hobbies = user_profile.get("hobby", []) or []
|
| 1036 |
user_details = user_profile.get("detail_hobby", []) or []
|
|
|
|
| 1037 |
user_extroversion = user_profile.get("extroversion", "")
|
| 1038 |
user_feeling_thinking = user_profile.get("feeling_thinking", "")
|
| 1039 |
|
|
|
|
|
|
|
| 1040 |
for item in items:
|
| 1041 |
item_id = item["item_id"]
|
| 1042 |
+
if item_id in seen_items: # ์ค๋ณต ๋ฐฉ์ง
|
| 1043 |
+
continue
|
| 1044 |
+
|
| 1045 |
item_emb = item_embedding_dict[item_id]
|
| 1046 |
sim = cosine_similarity(user_emb, item_emb)
|
| 1047 |
|
| 1048 |
# ๊ธฐ๋ณธ ๊ฐ์ค์น
|
| 1049 |
weight = 1.0
|
| 1050 |
|
| 1051 |
+
# (1) ์ทจ๋ฏธ ๊ฐ์ค์น
|
| 1052 |
desc_hobby = extract_hobby(item["desc"]) # ์: "(์ด๋, ํฌ์ค)"
|
|
|
|
| 1053 |
for h in user_hobbies:
|
| 1054 |
if h in desc_hobby:
|
| 1055 |
+
weight *= 1.15
|
|
|
|
| 1056 |
|
| 1057 |
+
# (2) ์ธ๋ถ ์ทจ๋ฏธ ๊ฐ์ค์น
|
| 1058 |
for dh in user_details:
|
| 1059 |
if dh in desc_hobby:
|
| 1060 |
+
weight *= 1.3
|
| 1061 |
|
| 1062 |
+
# (3) ์ฑํฅ ๊ฐ์ค์น (์ธํฅํ/๋ดํฅํ, ๊ฐ์ ํ/์ด์ฑํ)
|
| 1063 |
personality_match_count = sum(
|
| 1064 |
trait in item["personality"]
|
| 1065 |
for trait in [user_extroversion, user_feeling_thinking]
|
| 1066 |
)
|
| 1067 |
if personality_match_count == 1:
|
| 1068 |
+
weight *= 1.2
|
| 1069 |
elif personality_match_count == 2:
|
| 1070 |
+
weight *= 1.3
|
| 1071 |
|
| 1072 |
final_score = sim * weight
|
| 1073 |
scored.append((item, final_score))
|
| 1074 |
|
| 1075 |
+
# ๐ข ์ ์๊ฐ ๋์ ์์ผ๋ก ์ ๋ ฌ
|
| 1076 |
scored.sort(key=lambda x: x[1], reverse=True)
|
| 1077 |
|
| 1078 |
+
# ๐ข ์์ 5๊ฐ๋ฅผ ํ๋ณด (์ค๋ณต ์์ด)
|
| 1079 |
+
selected_items = []
|
| 1080 |
+
for (item, score) in scored:
|
| 1081 |
+
if len(selected_items) >= top_n:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1082 |
break
|
| 1083 |
+
if item["item_id"] not in seen_items:
|
| 1084 |
+
seen_items.add(item["item_id"])
|
| 1085 |
+
selected_items.append((item, score))
|
| 1086 |
+
|
| 1087 |
+
return selected_items
|
| 1088 |
|
| 1089 |
# ์ถ์ฒ ๊ฐ์๊ฐ ๋ถ์กฑํ๋ค๋ฉด, ๋๋จธ์ง ์ถ์ฒ์ ์ถ๊ฐ
|
| 1090 |
if len(balanced_recommendations) < top_n:
|