Spaces:
Sleeping
Sleeping
Complete step 6
Browse files- npc_social_network/npc/emotion_config.py +79 -70
- npc_social_network/npc/npc_base.py +7 -5
- npc_social_network/npc/npc_emotion.py +34 -12
- test.ipynb +15 -4
npc_social_network/npc/emotion_config.py
CHANGED
@@ -3,79 +3,88 @@
|
|
3 |
|
4 |
# κ³ μ°¨μ κ°μ μν μ μ (GoEmotions κΈ°λ°, 보μ¬μ£ΌκΈ°μ©)
|
5 |
EMOTION_STATE_TEMPLATE = {
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
|
46 |
# κ°μ λ³ ν볡 μλ (ms λ¨μκ° μλ λ¨μλΉ κ°μ μλ)
|
47 |
EMOTION_DECAY_RATE = {
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
# κ³ μ°¨μ κ°μ μν μ μ (GoEmotions κΈ°λ°, 보μ¬μ£ΌκΈ°μ©)
|
5 |
EMOTION_STATE_TEMPLATE = {
|
6 |
+
# κΈ°λ³Έ μ μ (κΈμ )
|
7 |
+
"core_positive":{
|
8 |
+
"joy": 0, # κΈ°μ¨
|
9 |
+
"satisfaction": 0, # λ§μ‘±
|
10 |
+
"gratitude": 0, # κ°μ¬
|
11 |
+
"calm": 0, # νμ¨
|
12 |
+
"anticipation": 0, # κΈ°λ
|
13 |
+
"pride": 0, # μλΆμ¬
|
14 |
+
"connectedness": 0 # μ λκ°
|
15 |
+
},
|
16 |
+
# κΈ°λ³Έ μ μ (λΆμ )
|
17 |
+
"core_negative": {
|
18 |
+
"sadness": 0, # μ¬ν
|
19 |
+
"anger": 0, # λΆλ
Έ
|
20 |
+
"anxiety": 0, # λΆμ
|
21 |
+
"disgust": 0, # νμ€
|
22 |
+
"fear": 0, # 곡ν¬
|
23 |
+
"regret": 0, # νν
|
24 |
+
"frustration": 0 # μ’μ
|
25 |
+
},
|
26 |
+
# μ¬νμ κ°μ
|
27 |
+
"social_emotion": {
|
28 |
+
"jealousy": 0, # μ§ν¬
|
29 |
+
"shame": 0, # μμΉμ¬
|
30 |
+
"guilt": 0, # μ£μ±
κ°
|
31 |
+
"compassion": 0, # λμ μ¬
|
32 |
+
"awe": 0, # κ²½μΈμ¬
|
33 |
+
"empathy": 0 # 곡κ°
|
34 |
+
},
|
35 |
+
# μΈμ§μ μν
|
36 |
+
"cognitive_state": {
|
37 |
+
"confusion": 0, # νΌλ
|
38 |
+
"nervousness": 0, # κΈ΄μ₯
|
39 |
+
"apathy": 0, # 무κ΄μ¬
|
40 |
+
"excitement": 0, # ν₯λΆ
|
41 |
+
"immersion": 0, # λͺ°μ
|
42 |
+
"skepticism": 0 # νμ
|
43 |
+
}
|
44 |
+
}
|
45 |
|
46 |
# κ°μ λ³ ν볡 μλ (ms λ¨μκ° μλ λ¨μλΉ κ°μ μλ)
|
47 |
EMOTION_DECAY_RATE = {
|
48 |
+
# κΈ°λ³Έ μ μ (κΈμ )
|
49 |
+
"joy": 1, # κΈ°μ¨
|
50 |
+
"satisfaction": 1, # λ§μ‘±
|
51 |
+
"gratitude": 1, # κ°μ¬
|
52 |
+
"calm": 1, # νμ¨
|
53 |
+
"anticipation": 1, # κΈ°λ
|
54 |
+
"pride": 1, # μλΆμ¬
|
55 |
+
"connectedness": 1, # μ λκ°
|
56 |
|
57 |
+
# κΈ°λ³Έ μ μ (λΆμ ) - λλ¦Ό
|
58 |
+
"sadness": 0.2, # μ¬ν
|
59 |
+
"anger": 0.5, # λΆλ
Έ
|
60 |
+
"anxiety": 0.4, # λΆμ
|
61 |
+
"disgust": 0.8, # νμ€
|
62 |
+
"fear": 0.6, # 곡ν¬
|
63 |
+
"regret": 0.3, # νν
|
64 |
+
"frustration": 0.5, # μ’μ
|
65 |
|
66 |
+
# μ¬νμ κ°μ
|
67 |
+
"jealousy": 0.4, # μ§ν¬
|
68 |
+
"shame": 0.4, # μμΉμ¬
|
69 |
+
"guilt": 0.4, # μ£μ±
κ°
|
70 |
+
"compassion": 1, # λμ μ¬
|
71 |
+
"awe": 1, # κ²½μΈμ¬
|
72 |
+
"empathy": 1, # 곡κ°
|
73 |
|
74 |
+
# μΈμ§μ μν
|
75 |
+
"confusion": 0.8, # νΌλ
|
76 |
+
"nervousness": 0.7, # κΈ΄μ₯
|
77 |
+
"apathy": 0.4, # 무κ΄μ¬
|
78 |
+
"excitement": 1.2, # ν₯λΆ
|
79 |
+
"immersion": 1.0, # λͺ°μ
|
80 |
+
"skepticism": 0.5, # νμ
|
81 |
+
}
|
82 |
+
|
83 |
+
# κ°μ± ν
νλ¦Ώ(0~1 λ²μ)
|
84 |
+
PERSONALITY_TEMPLATE = {
|
85 |
+
"sensitive" : 0.8, # κ°μ λ°μ κ°λ μ¦κ°
|
86 |
+
"stoic": 0.2, # κ°μ λ°μ λν
|
87 |
+
"positive_bias": 0.6, # κΈμ κ°μ μ λ―Όκ°
|
88 |
+
"negative_bias": 0.4, # λΆμ κ°μ μ λ―Όκ°
|
89 |
+
"sociality" : 0.5, # μ¬νμ κ°μ λ―Όκ°
|
90 |
+
}
|
npc_social_network/npc/npc_base.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
from .npc_memory import Memory, MemoryStore
|
3 |
from .npc_emotion import EmotionManager
|
4 |
from .npc_behavior import BehaviorManager
|
5 |
-
from .emotion_config import EMOTION_STATE_TEMPLATE, EMOTION_DECAY_RATE
|
6 |
|
7 |
# NPC ν΄λμ€ μ μ
|
8 |
class NPC:
|
@@ -10,23 +10,25 @@ class NPC:
|
|
10 |
NPC ν΄λμ€
|
11 |
NPCμ λν κΈ°λ³Έ μ 보λ₯Ό κ°μ²΄ν
|
12 |
"""
|
13 |
-
def __init__(self, name, job, path, image):
|
14 |
self.name = name
|
15 |
self.job = job
|
16 |
self.path = path
|
17 |
self.image = image
|
18 |
self.current_index = 0
|
|
|
19 |
|
20 |
# npc κΈ°μ΅
|
21 |
self.memory_store = MemoryStore()
|
22 |
-
# κ°μ μν
|
23 |
self.emotion_state = EMOTION_STATE_TEMPLATE
|
24 |
self.emotion_decay_rate = EMOTION_DECAY_RATE
|
25 |
-
self.
|
|
|
|
|
26 |
|
27 |
# νλ κ΄λ¦¬μ
|
28 |
self.behavior = BehaviorManager()
|
29 |
-
|
30 |
# λ΄λΆ: float κ°μ μμΉ κ΄λ¦¬μ© λ²νΌ
|
31 |
self._emotion_buffer = self.emotion.get_buffer()
|
32 |
|
|
|
2 |
from .npc_memory import Memory, MemoryStore
|
3 |
from .npc_emotion import EmotionManager
|
4 |
from .npc_behavior import BehaviorManager
|
5 |
+
from .emotion_config import EMOTION_STATE_TEMPLATE, EMOTION_DECAY_RATE, PERSONALITY_TEMPLATE
|
6 |
|
7 |
# NPC ν΄λμ€ μ μ
|
8 |
class NPC:
|
|
|
10 |
NPC ν΄λμ€
|
11 |
NPCμ λν κΈ°λ³Έ μ 보λ₯Ό κ°μ²΄ν
|
12 |
"""
|
13 |
+
def __init__(self, name, job, path, image, personality=None):
|
14 |
self.name = name
|
15 |
self.job = job
|
16 |
self.path = path
|
17 |
self.image = image
|
18 |
self.current_index = 0
|
19 |
+
self.personality = personality or {}
|
20 |
|
21 |
# npc κΈ°μ΅
|
22 |
self.memory_store = MemoryStore()
|
23 |
+
# κ°μ μν λ± κ°μ κ΄λ¦¬μ μ΄κΈ°ν
|
24 |
self.emotion_state = EMOTION_STATE_TEMPLATE
|
25 |
self.emotion_decay_rate = EMOTION_DECAY_RATE
|
26 |
+
self.personality = personality or PERSONALITY_TEMPLATE
|
27 |
+
|
28 |
+
self.emotion = EmotionManager(self.emotion_state, self.emotion_decay_rate, self.personality)
|
29 |
|
30 |
# νλ κ΄λ¦¬μ
|
31 |
self.behavior = BehaviorManager()
|
|
|
32 |
# λ΄λΆ: float κ°μ μμΉ κ΄λ¦¬μ© λ²νΌ
|
33 |
self._emotion_buffer = self.emotion.get_buffer()
|
34 |
|
npc_social_network/npc/npc_emotion.py
CHANGED
@@ -1,29 +1,49 @@
|
|
1 |
# κ°μ μν, κ°μ μ
λ°μ΄νΈ, decay μ²λ¦¬
|
2 |
# portfolio/npc_social_network/npc/npc_emotion.py
|
|
|
3 |
|
4 |
class EmotionManager:
|
5 |
-
def __init__(self, emotion_state, decay_rate):
|
6 |
# κ³ μ°¨μ κ°μ μν (GoEmotions κΈ°λ°)
|
7 |
self.emotion_state = emotion_state
|
8 |
# κ°μ λ³ ν볡 μλ (ms λ¨μκ° μλ λ¨μλΉ κ°μ μλ)
|
9 |
self.decay_rate = decay_rate
|
10 |
# λ΄λΆ: float κ°μ μμΉ κ΄λ¦¬μ© λ²νΌ
|
11 |
-
self._emotion_buffer = {emo: 0.0 for cat in emotion_state for emo in
|
12 |
-
|
13 |
-
for emo in emotion_state[cat]:
|
14 |
-
self._emotion_buffer[emo] = float(emotion_state[cat][emo])
|
15 |
|
16 |
# νΉμ κ°μ μ κ°μ μνμ λ°μ (μΉ΄ν
κ³ λ¦¬ κΈ°λ°)
|
17 |
def update_emotion(self, emotion: str, strength: float = 1.0):
|
18 |
-
if emotion in self._emotion_buffer:
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
# μκ°μ΄ μ§λ¨μ λ°λΌ λͺ¨λ κ°μ μ΄ μμν κ°μ
|
23 |
def decay_emotion(self):
|
24 |
-
for
|
25 |
-
rate = self.decay_rate.get(
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
# μ μ κΈ°λ° μΆλ ₯μ© κ°μ μν λ°ν
|
29 |
def get_state(self):
|
@@ -31,7 +51,9 @@ class EmotionManager:
|
|
31 |
|
32 |
# νμ¬ κ°μ₯ κ°ν κ°μ λ°ν (μ 체 κ°μ μ€ μ΅λκ° 1κ°)
|
33 |
def get_dominant_emotion(self):
|
34 |
-
|
|
|
|
|
35 |
|
36 |
def get_buffer(self):
|
37 |
return self._emotion_buffer.copy()
|
|
|
1 |
# κ°μ μν, κ°μ μ
λ°μ΄νΈ, decay μ²λ¦¬
|
2 |
# portfolio/npc_social_network/npc/npc_emotion.py
|
3 |
+
from .emotion_config import EMOTION_DECAY_RATE
|
4 |
|
5 |
class EmotionManager:
|
6 |
+
def __init__(self, emotion_state, decay_rate, personality = None):
|
7 |
# κ³ μ°¨μ κ°μ μν (GoEmotions κΈ°λ°)
|
8 |
self.emotion_state = emotion_state
|
9 |
# κ°μ λ³ ν볡 μλ (ms λ¨μκ° μλ λ¨μλΉ κ°μ μλ)
|
10 |
self.decay_rate = decay_rate
|
11 |
# λ΄λΆ: float κ°μ μμΉ κ΄λ¦¬μ© λ²νΌ
|
12 |
+
self._emotion_buffer = {emo: 0.0 for cat in emotion_state.values() for emo in cat}
|
13 |
+
self.personality = personality or {}
|
|
|
|
|
14 |
|
15 |
# νΉμ κ°μ μ κ°μ μνμ λ°μ (μΉ΄ν
κ³ λ¦¬ κΈ°λ°)
|
16 |
def update_emotion(self, emotion: str, strength: float = 1.0):
|
17 |
+
if emotion not in self._emotion_buffer:
|
18 |
+
print(f"[κ²½κ³ ] '{emotion}'μ(λ) μ μλ κ°μ μ΄ μλλλ€.")
|
19 |
+
return
|
20 |
+
|
21 |
+
# κ°μ± κ³μ λ°μ
|
22 |
+
multiplier = 1.0
|
23 |
+
if emotion in ["joy", "gratitude", "pride"]:
|
24 |
+
multiplier *= self.personality.get("positive_bias", 1)
|
25 |
+
elif emotion in ["anger", "fear", "regret"]:
|
26 |
+
multiplier *= self.personality.get("negative_bias", 1)
|
27 |
+
|
28 |
+
multiplier *= self.personality.get("sensitive", 1)
|
29 |
+
|
30 |
+
self._emotion_buffer[emotion] += strength * multiplier
|
31 |
+
for category in self.emotion_state:
|
32 |
+
if emotion in self.emotion_state[category]:
|
33 |
+
self.emotion_state[category][emotion] = int(self._emotion_buffer[emotion])
|
34 |
+
break
|
35 |
+
|
36 |
|
37 |
# μκ°μ΄ μ§λ¨μ λ°λΌ λͺ¨λ κ°μ μ΄ μμν κ°μ
|
38 |
def decay_emotion(self):
|
39 |
+
for emotion, value in self._emotion_buffer.items():
|
40 |
+
rate = self.decay_rate.get(emotion, 0.5)
|
41 |
+
modifier = 1.0 - self.personality.get("stoic", 0)
|
42 |
+
self._emotion_buffer[emotion] = max(0.0, value - rate * modifier)
|
43 |
+
|
44 |
+
for category in self.emotion_state:
|
45 |
+
for emotion in self.emotion_state[category]:
|
46 |
+
self.emotion_state[category][emotion] = int(self._emotion_buffer[emotion])
|
47 |
|
48 |
# μ μ κΈ°λ° μΆλ ₯μ© κ°μ μν λ°ν
|
49 |
def get_state(self):
|
|
|
51 |
|
52 |
# νμ¬ κ°μ₯ κ°ν κ°μ λ°ν (μ 체 κ°μ μ€ μ΅λκ° 1κ°)
|
53 |
def get_dominant_emotion(self):
|
54 |
+
if not self._emotion_buffer:
|
55 |
+
return "neutral"
|
56 |
+
return max(self._emotion_buffer.items(), key=lambda x: x[1])[0]
|
57 |
|
58 |
def get_buffer(self):
|
59 |
return self._emotion_buffer.copy()
|
test.ipynb
CHANGED
@@ -2822,7 +2822,7 @@
|
|
2822 |
},
|
2823 |
{
|
2824 |
"cell_type": "code",
|
2825 |
-
"execution_count":
|
2826 |
"id": "cc6f2948",
|
2827 |
"metadata": {},
|
2828 |
"outputs": [
|
@@ -2830,13 +2830,24 @@
|
|
2830 |
"name": "stdout",
|
2831 |
"output_type": "stream",
|
2832 |
"text": [
|
2833 |
-
"
|
2834 |
]
|
2835 |
}
|
2836 |
],
|
2837 |
"source": [
|
2838 |
-
"
|
2839 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2840 |
]
|
2841 |
}
|
2842 |
],
|
|
|
2822 |
},
|
2823 |
{
|
2824 |
"cell_type": "code",
|
2825 |
+
"execution_count": 1,
|
2826 |
"id": "cc6f2948",
|
2827 |
"metadata": {},
|
2828 |
"outputs": [
|
|
|
2830 |
"name": "stdout",
|
2831 |
"output_type": "stream",
|
2832 |
"text": [
|
2833 |
+
"κ°μ νκ· κ°λ: 0.96 / λν κ°μ : fear(0.96)\n"
|
2834 |
]
|
2835 |
}
|
2836 |
],
|
2837 |
"source": [
|
2838 |
+
"from npc_social_network.npc.npc_base import NPC\n",
|
2839 |
+
"\n",
|
2840 |
+
"# λ―Όκ°νκ³ λΆμ μ μ·¨μ½ν μΊλ¦ν°\n",
|
2841 |
+
"custom_personality = {\n",
|
2842 |
+
" \"sensitive\": 1.0,\n",
|
2843 |
+
" \"negative_bias\": 1.5,\n",
|
2844 |
+
" \"stoic\": 0.1\n",
|
2845 |
+
"}\n",
|
2846 |
+
"\n",
|
2847 |
+
"npc = NPC(\"μλ¦°\", \"farmer\", [(0, 0)], None, personality=custom_personality)\n",
|
2848 |
+
"npc.remember(\"무μμ΄ μ리λ₯Ό λ€μ\", emotion=\"fear\", importance=5)\n",
|
2849 |
+
"npc.decay_emotion()\n",
|
2850 |
+
"print(npc.summarize_emotional_state())"
|
2851 |
]
|
2852 |
}
|
2853 |
],
|