File size: 9,659 Bytes
a832dee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
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
47
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
"""Fix the 17 new NER fixture samples added in Wave 3:
- Add proper Vietnamese diacritics to time_preference samples
- Fix gold annotations to be consistent with model keyword dictionaries
- Replace Bali Mount Batur with simpler text (avoid 'batu' FP)
- Fix 'Family of 4' sample to not conflict with travel_style suppression logic
"""
import json
import os

DATA_PATH = os.path.join(os.path.dirname(__file__), '..', 'app', 'data', 'datasets', 'ner_eval.json')

CORRECTED = [
    # --- time_preference samples (12) with proper diacritics ---
    # NOTE: each destination city annotated as BOTH 'location' AND 'destination'
    # (matching convention in original 85 samples; model returns both)
    {
        'text': 'Muốn đi tham quan Hạ Long buổi sáng sớm trước khi tàu đông khách',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'ha-long'},
            {'type': 'destination', 'value': 'ha-long'},
            {'type': 'time_preference', 'value': 'early_morning'},
        ]
    },
    {
        'text': 'Hội An 3 ngày, đi phố cổ buổi chiều và xem đèn lồng buổi tối',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'hoi-an'},
            {'type': 'destination', 'value': 'hoi-an'},
            {'type': 'duration', 'value': {'days': 3, 'nights': 2}},
            {'type': 'time_preference', 'value': 'afternoon'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        'text': 'Chụp ảnh hoàng hôn ở Mũi Né, thích đi vào buổi chiều',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'mui-ne'},
            {'type': 'destination', 'value': 'mui-ne'},
            {'type': 'activity_preference', 'value': 'photography'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        'text': 'Sapa trekking buổi sáng, nghỉ trưa rồi tiếp tục leo núi',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'sapa'},
            {'type': 'destination', 'value': 'sapa'},
            {'type': 'activity_preference', 'value': 'trekking'},
            {'type': 'time_preference', 'value': 'morning'},
            {'type': 'time_preference', 'value': 'noon'},
        ]
    },
    {
        'text': 'Hà Nội 2 ngày 1 đêm, tham quan buổi sáng, mua sắm buổi chiều',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'hanoi'},
            {'type': 'destination', 'value': 'hanoi'},
            {'type': 'duration', 'value': {'days': 2, 'nights': 1}},
            {'type': 'activity_preference', 'value': 'sightseeing'},
            {'type': 'activity_preference', 'value': 'shopping'},
            {'type': 'time_preference', 'value': 'morning'},
            {'type': 'time_preference', 'value': 'afternoon'},
        ]
    },
    {
        'text': 'Nha Trang 4 ngày, lặn biển buổi sáng sớm và đi chợ đêm buổi tối',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'nha-trang'},
            {'type': 'destination', 'value': 'nha-trang'},
            {'type': 'duration', 'value': {'days': 4, 'nights': 3}},
            {'type': 'activity_preference', 'value': 'diving'},
            {'type': 'time_preference', 'value': 'early_morning'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        'text': 'Đi Phú Quốc ăn hải sản buổi trưa, ngắm hoàng hôn buổi chiều',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'phu-quoc'},
            {'type': 'destination', 'value': 'phu-quoc'},
            {'type': 'cuisine', 'value': 'seafood'},
            {'type': 'time_preference', 'value': 'noon'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        # Bangkok: 'night markets in the evening' -> evening only (night compound suppressed)
        'text': 'I want to explore Bangkok temples in the morning and night markets in the evening',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'bangkok'},
            {'type': 'destination', 'value': 'bangkok'},
            {'type': 'activity_preference', 'value': 'sightseeing'},
            {'type': 'time_preference', 'value': 'morning'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        'text': 'Kyoto 5 days, visit shrines early morning before crowds arrive',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'kyoto'},
            {'type': 'destination', 'value': 'kyoto'},
            {'type': 'duration', 'value': {'days': 5, 'nights': 4}},
            {'type': 'activity_preference', 'value': 'sightseeing'},
            {'type': 'time_preference', 'value': 'early_morning'},
        ]
    },
    {
        'text': 'Singapore 3 nights, food tour at noon and rooftop bar in the evening',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'singapore'},
            {'type': 'destination', 'value': 'singapore'},
            {'type': 'duration', 'value': {'days': 3, 'nights': 3}},
            {'type': 'cuisine', 'value': 'local_specialty'},
            {'type': 'time_preference', 'value': 'noon'},
            {'type': 'time_preference', 'value': 'evening'},
        ]
    },
    {
        # Removed 'Mount Batur' to avoid 'batu' location FP; simplified to Bali morning hike
        'text': 'Bali morning hike, afternoon spa and massage session',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'bali'},
            {'type': 'destination', 'value': 'bali'},
            {'type': 'activity_preference', 'value': 'trekking'},
            {'type': 'activity_preference', 'value': 'spa'},
            {'type': 'time_preference', 'value': 'morning'},
            {'type': 'time_preference', 'value': 'afternoon'},
        ]
    },
    {
        'text': 'Paris night tour: Eiffel Tower at night, brunch in the morning',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'paris'},
            {'type': 'destination', 'value': 'paris'},
            {'type': 'activity_preference', 'value': 'sightseeing'},
            {'type': 'time_preference', 'value': 'night'},
            {'type': 'time_preference', 'value': 'morning'},
        ]
    },
    # --- people edge cases (5 samples) ---
    {
        # 'Solo backpacker 7 days' - explicit '7 days' duration
        # gold: backpacker+adventure (both fired by model keywords)
        'text': 'Solo backpacker trip to Sapa 7 days, hiking and photography',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'sapa'},
            {'type': 'destination', 'value': 'sapa'},
            {'type': 'duration', 'value': {'days': 7, 'nights': 6}},
            {'type': 'people', 'value': {'adults': 1, 'children': 0, 'infants': 0}},
            {'type': 'travel_style', 'value': 'backpacker'},
            {'type': 'travel_style', 'value': 'adventure'},
            {'type': 'activity_preference', 'value': 'trekking'},
            {'type': 'activity_preference', 'value': 'photography'},
        ]
    },
    {
        'text': 'Couple trip to Bali 7 days, honeymoon package',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'bali'},
            {'type': 'destination', 'value': 'bali'},
            {'type': 'duration', 'value': {'days': 7, 'nights': 6}},
            {'type': 'people', 'value': {'adults': 2, 'children': 0, 'infants': 0}},
            {'type': 'travel_style', 'value': 'honeymoon'},
        ]
    },
    {
        'text': 'Group of 8 friends to Da Nang beach, budget hostel',
        'language': 'en',
        'entities': [
            {'type': 'location', 'value': 'da-nang'},
            {'type': 'destination', 'value': 'da-nang'},
            {'type': 'people', 'value': {'adults': 8, 'children': 0, 'infants': 0}},
            {'type': 'hotel_type', 'value': 'hostel'},
        ]
    },
    {
        'text': 'Đi Phú Quốc 2 vợ chồng 5 ngày nghỉ dưỡng',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'phu-quoc'},
            {'type': 'destination', 'value': 'phu-quoc'},
            {'type': 'duration', 'value': {'days': 5, 'nights': 4}},
            {'type': 'people', 'value': {'adults': 2, 'children': 0, 'infants': 0}},
            {'type': 'travel_style', 'value': 'relaxation'},
        ]
    },
    {
        'text': 'Gia đình 5 người đi Đà Lạt 4 ngày, có 2 trẻ em',
        'language': 'vi',
        'entities': [
            {'type': 'location', 'value': 'da-lat'},
            {'type': 'destination', 'value': 'da-lat'},
            {'type': 'duration', 'value': {'days': 4, 'nights': 3}},
            {'type': 'people', 'value': {'adults': 3, 'children': 2, 'infants': 0}},
            {'type': 'travel_style', 'value': 'family'},
        ]
    },
]

assert len(CORRECTED) == 17, f'Expected 17, got {len(CORRECTED)}'

data = json.load(open(DATA_PATH, encoding='utf-8'))
print(f'Before: {len(data)} samples')
data[85:] = CORRECTED
print(f'After: {len(data)} samples')

tp = sum(1 for s in data if any(e['type'] == 'time_preference' for e in s.get('entities', [])))
print(f'time_preference samples: {tp}')

json.dump(data, open(DATA_PATH, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)
print('Saved.')