wanderlust-chatbot / scripts /generate_wave2_data.py
Kiriten892's picture
Wave 2: compare_destinations data + NER fixes + evaluation update
6feeee8
Raw
History Blame Contribute Delete
36.6 kB
"""
Wave 2 data generation script.
Tasks:
1. Generate 120 compare_destinations intent samples and append to
intent_train_enhanced.json.
2. Generate 70 additional NER eval samples to expand ner_eval.json
from 30 to 100.
Run from chatbot-ml-service/ directory:
python scripts/generate_wave2_data.py
"""
import json
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
INTENT_FILE = os.path.join(BASE_DIR, "app", "data", "datasets", "intent_train_enhanced.json")
NER_FILE = os.path.join(BASE_DIR, "app", "data", "datasets", "ner_eval.json")
# ============================================================
# 1. compare_destinations — 120 samples (80 VI + 40 EN)
# ============================================================
COMPARE_DESTINATIONS_VI = [
# So sánh hai điểm trong nước
"Đà Nẵng hay Nha Trang thì đi đâu vui hơn?",
"So sánh Phú Quốc và Đà Lạt cho kỳ nghỉ hè",
"Chọn Sapa hay Hà Giang để phượt xe máy?",
"Hội An hay Huế thì hợp hơn cho cặp đôi?",
"Nha Trang vs Đà Nẵng, đâu có bãi biển đẹp hơn?",
"Đà Lạt và Mù Cang Chải khác nhau thế nào?",
"Đi Hội An hay Đà Nẵng thì được?",
"So sánh Hạ Long và Phú Quốc nhé",
"Chọn Cần Thơ hay Mỹ Tho cho chuyến miền Tây?",
"Quy Nhơn hay Nha Trang, đâu hợp hơn cho solo?",
"Phú Quốc vs Côn Đảo, đâu yên tĩnh hơn?",
"Sapa hay Bắc Hà, chỗ nào phong cảnh đẹp hơn?",
"So sánh Hà Nội và Hồ Chí Minh để sống và đi chơi",
"Ninh Bình hay Hà Giang, đâu hợp cho đi phượt?",
"Đà Nẵng vs Huế, đâu nhiều điểm tham quan hơn?",
"Mũi Né hay Vũng Tàu, đâu có sóng đẹp để lướt?",
"Hạ Long hay Lan Hạ, đâu đông khách hơn?",
"Đà Lạt hay Buôn Ma Thuột, đâu có cà phê ngon?",
"Phú Yên hay Khánh Hòa thì nên chọn nơi nào?",
"So sánh Hội An và Đà Nẵng cho gia đình 4 người",
# So sánh quốc tế
"Bangkok hay Singapore đâu rẻ hơn?",
"Nhật Bản vs Hàn Quốc, đâu thích hợp mùa xuân?",
"So sánh Bali và Phuket cho tuần trăng mật",
"Đài Loan hay Hồng Kông, đâu nhiều đồ ăn ngon?",
"Paris hay Rome thì nên chọn đâu cho 7 ngày?",
"Chọn Thái Lan hay Malaysia, đâu rẻ hơn?",
"Singapore vs Kuala Lumpur, đâu hợp mua sắm?",
"Kyoto hay Tokyo, đâu nhiều văn hóa truyền thống?",
"Seoul hay Busan, đâu đông vui hơn?",
"So sánh Dubai và Istanbul cho chuyến Trung Đông",
"Chọn Bali hay Maldives cho honeymoon với ngân sách $3000",
"Osaka hay Kyoto thì hợp hơn cho 3 ngày?",
"Chiang Mai hay Phuket, đâu phù hợp với người thích thiên nhiên?",
"Amsterdam hay Prague, đâu đẹp hơn vào mùa thu?",
"London hay Paris, đâu dễ đi một mình hơn?",
# So sánh với điều kiện cụ thể
"Ngân sách 5 triệu, nên đi Đà Nẵng hay Nha Trang?",
"Với 2 ngày, chọn Hội An hay Đà Nẵng?",
"Gia đình có trẻ nhỏ, Phú Quốc hay Đà Nẵng phù hợp hơn?",
"Đi một mình thì Sapa hay Hà Giang an toàn hơn?",
"Cuối tuần nên chọn Vũng Tàu hay Đà Lạt?",
"Tháng 7 nên đi Đà Nẵng hay Phú Quốc?",
"3 ngày thì nên chọn Huế hay Hội An?",
"Mùa mưa nên tránh Đà Nẵng hay Nha Trang?",
"Đặt phòng homestay, Sapa hay Mộc Châu view đẹp hơn?",
"Nhóm 6 người nên chọn Hạ Long hay Phú Quốc?",
# Câu hỏi so sánh trực tiếp
"Đà Lạt tốt hơn hay Sapa tốt hơn?",
"Nên chọn Phuket hay Bali vậy bạn?",
"Giữa Nha Trang và Phú Quốc thì đâu hay hơn?",
"Nơi nào hợp hơn: Hội An hay Đà Nẵng?",
"Đâu hơn giữa Kyoto và Tokyo?",
"Nên đi Đài Loan hay Nhật Bản đầu tiên?",
"Chọn đâu tốt hơn: Bangkok hay Kuala Lumpur?",
"Hà Nội vs TPHCM, thành phố nào đáng sống hơn?",
"Maldives hay Bali, đâu romantic hơn cho cặp đôi?",
"Đi Hà Nội hay Đà Nẵng thì phù hợp với người thích ẩm thực?",
# Variations đa dạng
"Bạn nghĩ Huế hay Hội An tốt hơn?",
"So sánh giúp mình Phú Quốc với Nha Trang",
"Tư vấn chọn giữa Sapa và Mộc Châu",
"Hà Giang hay Cao Bằng, đâu cảnh đẹp hơn?",
"Đà Nẵng và Hội An nên ghé cả hai hay chọn một?",
"Pattaya vs Phuket cho chuyến Thái Lan 5 ngày",
"Nên chọn Osaka hay Kyoto để ở khi du lịch Nhật?",
"Hàn Quốc hay Nhật Bản, đâu thích hợp mùa đông?",
"So sánh Penang và Kuala Lumpur",
"Đâu tốt hơn cho trekking: Nepal hay Việt Nam?",
# Compare với yếu tố giá cả/tiện ích
"Phú Quốc hay Nha Trang, đâu nhiều khách sạn giá tốt hơn?",
"Đi Hà Nội hay Đà Nẵng thì vé máy bay rẻ hơn từ TPHCM?",
"Bali hay Phuket, đâu phù hợp với ngân sách $1000?",
"Sapa hay Mộc Châu, đâu gần Hà Nội hơn?",
"Đà Lạt hay Nha Trang, đâu có resort đẹp hơn?",
"Bangkok hay Chiang Mai, đâu nhiều đồ ăn đường phố?",
"Giữa Hội An và Huế, đâu có phố cổ đẹp hơn?",
"Quy Nhơn hay Phú Yên, đâu còn hoang sơ hơn?",
"Đà Nẵng hay Đà Lạt cho kỳ nghỉ tháng 8?",
"So sánh khí hậu Hà Nội và Đà Nẵng tháng 11",
"Hồ Chí Minh hay Đà Nẵng thì có nhiều quán bar hơn?",
"So sánh chuyến đi Osaka và Kyoto trong 4 ngày",
"Chọn giữa Santorini và Mykonos cho tuần trăng mật",
"Đâu đẹp hơn: Hạ Long hay Phú Quốc vào tháng 3?",
"Tư vấn nên đi Đà Nẵng hay Nha Trang dịp 30 tháng 4",
]
COMPARE_DESTINATIONS_EN = [
"Compare Da Nang vs Hoi An for a beach trip",
"Which is better, Phu Quoc or Nha Trang?",
"Should I visit Bangkok or Singapore?",
"Japan versus South Korea for a spring trip",
"Bali or Phuket for honeymoon?",
"What is the difference between Kyoto and Tokyo?",
"Is Paris or Rome better for a week trip?",
"Compare Hoi An and Da Nang for a family vacation",
"Sapa vs Ha Giang for trekking",
"Which city is better for solo travel: Hanoi or Ho Chi Minh City?",
"London vs Paris, which is cheaper?",
"Osaka or Kyoto for 3 days?",
"Should I choose Maldives or Bali?",
"Compare Taipei and Hong Kong for food lovers",
"Da Lat versus Nha Trang for a weekend trip",
"Dubai or Istanbul for a Middle East trip?",
"Which is better for nightlife: Bangkok or Phuket?",
"Compare Singapore vs Kuala Lumpur for shopping",
"Ha Long or Lan Ha Bay, which is less crowded?",
"Seoul vs Busan for 5 days",
"Which has better beaches: Da Nang or Nha Trang?",
"Amsterdam or Prague for autumn travel?",
"Penang or Kuala Lumpur, which has better street food?",
"Compare Chiang Mai and Phuket for nature lovers",
"Rome or Barcelona for a cultural trip?",
"Which is better value, Bali or Vietnam for $1500?",
"Phu Quoc or Con Dao for a quiet beach getaway?",
"Compare Nepal and Vietnam for trekking adventures",
"Tokyo or Osaka to base for Japan trip?",
"Is Da Nang or Hue better for history and culture?",
"Sapa or Mu Cang Chai for scenic rice terraces?",
"Which should I visit first, Taiwan or Japan?",
"Quy Nhon vs Phu Yen, which is less touristy?",
"Compare Hue and Hoi An for 3 days",
"Vietnam vs Thailand for first-time Southeast Asia traveler?",
"Is Ha Long Bay or Lan Ha Bay better?",
"Maldives or Seychelles for a romantic trip?",
"Which is safer for solo female travel: Bali or Thailand?",
"Compare budget travel in Vietnam vs Cambodia",
"Florence or Rome for art lovers?",
]
assert len(COMPARE_DESTINATIONS_VI) == 80, f"Need 80 VI samples, got {len(COMPARE_DESTINATIONS_VI)}"
assert len(COMPARE_DESTINATIONS_EN) == 40, f"Need 40 EN samples, got {len(COMPARE_DESTINATIONS_EN)}"
# ============================================================
# 2. NER eval expansion — 70 additional samples
# ============================================================
NER_EVAL_ADDITIONAL = [
# === Origin pattern: "từ X" at end of sentence (target bug) ===
{
"text": "Thuê homestay ở Ninh Bình 2 ngày, đi xe bus từ Hà Nội",
"language": "vi",
"entities": [
{"type": "location", "value": "ninh-binh"},
{"type": "location", "value": "hanoi"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "ninh-binh"},
{"type": "hotel_type", "value": "homestay"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "transport", "value": "bus"},
],
},
{
"text": "Đặt khách sạn Đà Lạt 3 ngày, bay từ Sài Gòn",
"language": "vi",
"entities": [
{"type": "location", "value": "da-lat"},
{"type": "location", "value": "hcmc"},
{"type": "origin", "value": "hcmc"},
{"type": "destination", "value": "da-lat"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
],
},
{
"text": "Lịch trình 5 ngày Đà Nẵng, xuất phát từ Hà Nội",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "location", "value": "hanoi"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "da-nang"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
],
},
{
"text": "Ghé thăm Hội An 2 ngày, đi tàu hỏa từ Đà Nẵng",
"language": "vi",
"entities": [
{"type": "location", "value": "hoi-an"},
{"type": "location", "value": "da-nang"},
{"type": "origin", "value": "da-nang"},
{"type": "destination", "value": "hoi-an"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "transport", "value": "train"},
],
},
{
"text": "Tour Hạ Long 2 ngày 1 đêm khởi hành từ Hà Nội mỗi thứ Sáu",
"language": "vi",
"entities": [
{"type": "location", "value": "ha-long"},
{"type": "location", "value": "hanoi"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "ha-long"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
],
},
{
"text": "Mua vé bay Phú Quốc, khởi hành từ Hà Nội tháng 6",
"language": "vi",
"entities": [
{"type": "location", "value": "phu-quoc"},
{"type": "location", "value": "hanoi"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "phu-quoc"},
],
},
# === hotel_type: "chỗ ở" / "accommodation" as non-hotel context ===
{
"text": "Du lịch tiết kiệm Sapa 4 ngày, không cần chỗ ở sang",
"language": "vi",
"entities": [
{"type": "location", "value": "sapa"},
{"type": "destination", "value": "sapa"},
{"type": "duration", "value": {"days": 4, "nights": 3}},
{"type": "budget_priority", "value": "accommodation:low"},
],
},
{
"text": "Gói du lịch Đà Nẵng 3 ngày bao gồm chỗ ở và ăn sáng",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "destination", "value": "da-nang"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
],
},
{
"text": "Tôi cần tìm nơi lưu trú tại Huế cho 2 đêm",
"language": "vi",
"entities": [
{"type": "location", "value": "hue"},
{"type": "destination", "value": "hue"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
],
},
# === hotel_type: specific star ratings with context word ===
{
"text": "Tìm khách sạn 4 sao ở Đà Nẵng, gần biển Mỹ Khê",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "destination", "value": "da-nang"},
{"type": "hotel_type", "value": "4-star"},
],
},
{
"text": "Đặt resort 5 sao Nha Trang cho 2 người, view biển",
"language": "vi",
"entities": [
{"type": "location", "value": "nha-trang"},
{"type": "destination", "value": "nha-trang"},
{"type": "hotel_type", "value": "5-star"},
{"type": "people", "value": {"adults": 2, "children": 0, "infants": 0}},
],
},
{
"text": "Cần hostel giá rẻ Hà Nội phố cổ cho 1 tuần",
"language": "vi",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "destination", "value": "hanoi"},
{"type": "hotel_type", "value": "hostel"},
{"type": "duration", "value": {"days": 7, "nights": 6}},
],
},
{
"text": "Thuê villa Phú Quốc có hồ bơi riêng cho nhóm 8 người",
"language": "vi",
"entities": [
{"type": "location", "value": "phu-quoc"},
{"type": "destination", "value": "phu-quoc"},
{"type": "hotel_type", "value": "villa"},
{"type": "people", "value": {"adults": 8, "children": 0, "infants": 0}},
],
},
# === travel_style: family trip (genuine) vs group-size ===
{
"text": "Du lịch gia đình ở Nha Trang, phù hợp cho trẻ em",
"language": "vi",
"entities": [
{"type": "location", "value": "nha-trang"},
{"type": "destination", "value": "nha-trang"},
{"type": "travel_style", "value": "family"},
],
},
{
"text": "Cần chỗ phù hợp cho gia đình đi nghỉ dưỡng Phú Quốc",
"language": "vi",
"entities": [
{"type": "location", "value": "phu-quoc"},
{"type": "destination", "value": "phu-quoc"},
{"type": "travel_style", "value": "family"},
{"type": "travel_style", "value": "relaxation"},
],
},
{
"text": "Đặt resort Đà Nẵng cho gia đình 5 người, có trẻ em 3 tuổi",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "destination", "value": "da-nang"},
{"type": "people", "value": {"adults": 4, "children": 1, "infants": 0}},
{"type": "travel_style", "value": "family"},
],
},
{
"text": "Lịch trình Đà Lạt cho gia đình 4 người dịp Tết",
"language": "vi",
"entities": [
{"type": "location", "value": "da-lat"},
{"type": "destination", "value": "da-lat"},
{"type": "people", "value": {"adults": 3, "children": 1, "infants": 0}},
],
},
# === dietary: complex negation patterns ===
{
"text": "Tôi không ăn thịt heo và không uống rượu, đi Thái Lan 5 ngày",
"language": "vi",
"entities": [
{"type": "location", "value": "bangkok"},
{"type": "destination", "value": "bangkok"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
{"type": "dietary", "value": "no_pork"},
],
},
{
"text": "Phượt Hà Giang, ăn chay hoàn toàn",
"language": "vi",
"entities": [
{"type": "location", "value": "ha-giang"},
{"type": "destination", "value": "ha-giang"},
{"type": "travel_style", "value": "backpacker"},
{"type": "dietary", "value": "vegan"},
],
},
{
"text": "Đi Nhật 7 ngày, dị ứng gluten và không ăn hải sản",
"language": "vi",
"entities": [
{"type": "location", "value": "tokyo"},
{"type": "destination", "value": "tokyo"},
{"type": "duration", "value": {"days": 7, "nights": 6}},
{"type": "dietary", "value": "gluten_free"},
{"type": "dietary", "value": "no_seafood"},
],
},
{
"text": "Đặt nhà hàng halal ở Kuala Lumpur cho 4 người",
"language": "vi",
"entities": [
{"type": "location", "value": "kuala-lumpur"},
{"type": "destination", "value": "kuala-lumpur"},
{"type": "people", "value": {"adults": 4, "children": 0, "infants": 0}},
{"type": "dietary", "value": "halal"},
],
},
# === cuisine vs dietary disambiguation ===
{
"text": "Đi Cần Thơ 2 ngày, thích hải sản nhưng dị ứng tôm",
"language": "vi",
"entities": [
{"type": "location", "value": "can-tho"},
{"type": "destination", "value": "can-tho"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "cuisine", "value": "seafood"},
],
},
{
"text": "Hội An 3 ngày, muốn ăn đặc sản địa phương, không cay",
"language": "vi",
"entities": [
{"type": "location", "value": "hoi-an"},
{"type": "destination", "value": "hoi-an"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
{"type": "cuisine", "value": "local_specialty"},
{"type": "dietary", "value": "no_spicy"},
],
},
# === Multi-destination ===
{
"text": "Từ Hà Nội bay Đà Nẵng, ghé Hội An rồi vào Hồ Chí Minh, 10 ngày",
"language": "vi",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "location", "value": "da-nang"},
{"type": "location", "value": "hoi-an"},
{"type": "location", "value": "hcmc"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "da-nang"},
{"type": "destination", "value": "hoi-an"},
{"type": "destination", "value": "hcmc"},
{"type": "duration", "value": {"days": 10, "nights": 9}},
],
},
{
"text": "Tour Đông Nam Á: Singapore 3 ngày, Bali 4 ngày, tổng 7 ngày",
"language": "vi",
"entities": [
{"type": "location", "value": "singapore"},
{"type": "location", "value": "bali"},
{"type": "destination", "value": "singapore"},
{"type": "destination", "value": "bali"},
{"type": "duration", "value": {"days": 7, "nights": 6}},
],
},
{
"text": "Kết hợp Sapa và Hà Giang trong 6 ngày từ Hà Nội",
"language": "vi",
"entities": [
{"type": "location", "value": "sapa"},
{"type": "location", "value": "ha-giang"},
{"type": "location", "value": "hanoi"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "sapa"},
{"type": "destination", "value": "ha-giang"},
{"type": "duration", "value": {"days": 6, "nights": 5}},
],
},
# === Budget patterns ===
{
"text": "Lịch trình Nhật Bản 10 ngày với 50 triệu VND, 2 người",
"language": "vi",
"entities": [
{"type": "location", "value": "tokyo"},
{"type": "destination", "value": "tokyo"},
{"type": "duration", "value": {"days": 10, "nights": 9}},
{"type": "budget", "value": {"amount": 50000000.0, "currency": "VND"}},
{"type": "people", "value": {"adults": 2, "children": 0, "infants": 0}},
],
},
{
"text": "Đi Bali 7 ngày ngân sách $800 cho 1 người",
"language": "vi",
"entities": [
{"type": "location", "value": "bali"},
{"type": "destination", "value": "bali"},
{"type": "duration", "value": {"days": 7, "nights": 6}},
{"type": "budget", "value": {"amount": 800.0, "currency": "USD"}},
{"type": "people", "value": {"adults": 1, "children": 0, "infants": 0}},
],
},
{
"text": "Hà Nội 3 ngày 2 đêm khoảng 3 triệu rưỡi",
"language": "vi",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "destination", "value": "hanoi"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
{"type": "budget", "value": {"amount": 3500000.0, "currency": "VND"}},
],
},
# === Activity combinations ===
{
"text": "Đà Nẵng 5 ngày, muốn lặn biển buổi sáng và chụp ảnh hoàng hôn",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "destination", "value": "da-nang"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
{"type": "activity_preference", "value": "diving"},
{"type": "activity_preference", "value": "photography"},
{"type": "time_preference", "value": "morning"},
],
},
{
"text": "Hội An 2 ngày, thích tham quan phố cổ và mua sắm đèn lồng",
"language": "vi",
"entities": [
{"type": "location", "value": "hoi-an"},
{"type": "destination", "value": "hoi-an"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "activity_preference", "value": "sightseeing"},
{"type": "activity_preference", "value": "shopping"},
],
},
{
"text": "Sapa 4 ngày trekking và leo núi Fansipan",
"language": "vi",
"entities": [
{"type": "location", "value": "sapa"},
{"type": "destination", "value": "sapa"},
{"type": "duration", "value": {"days": 4, "nights": 3}},
{"type": "activity_preference", "value": "trekking"},
{"type": "travel_style", "value": "adventure"},
],
},
# === Transport preferences ===
{
"text": "Đi Đà Lạt bằng xe máy từ Nha Trang, 2 ngày",
"language": "vi",
"entities": [
{"type": "location", "value": "da-lat"},
{"type": "location", "value": "nha-trang"},
{"type": "origin", "value": "nha-trang"},
{"type": "destination", "value": "da-lat"},
{"type": "transport", "value": "motorbike"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
],
},
{
"text": "Tokyo 7 ngày đi lại bằng metro và shinkansen",
"language": "vi",
"entities": [
{"type": "location", "value": "tokyo"},
{"type": "destination", "value": "tokyo"},
{"type": "duration", "value": {"days": 7, "nights": 6}},
{"type": "transport", "value": "train"},
],
},
# === English samples ===
{
"text": "3-night stay at a boutique hotel in Hoi An, solo trip",
"language": "en",
"entities": [
{"type": "location", "value": "hoi-an"},
{"type": "destination", "value": "hoi-an"},
{"type": "duration", "value": {"days": 4, "nights": 3}},
{"type": "hotel_type", "value": "boutique"},
{"type": "travel_style", "value": "solo"},
],
},
{
"text": "Flight from Hanoi to Da Nang for 2 adults, need hotel near beach",
"language": "en",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "location", "value": "da-nang"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "da-nang"},
{"type": "people", "value": {"adults": 2, "children": 0, "infants": 0}},
],
},
{
"text": "10-day Japan itinerary, 5-star ryokan in Kyoto, sushi and ramen",
"language": "en",
"entities": [
{"type": "location", "value": "kyoto"},
{"type": "destination", "value": "kyoto"},
{"type": "duration", "value": {"days": 10, "nights": 9}},
{"type": "hotel_type", "value": "5-star"},
{"type": "cuisine", "value": "japanese"},
],
},
{
"text": "Backpacker trip through Vietnam and Cambodia, 3 weeks, gluten-free diet",
"language": "en",
"entities": [
{"type": "travel_style", "value": "backpacker"},
{"type": "duration", "value": {"days": 21, "nights": 20}},
{"type": "dietary", "value": "gluten_free"},
],
},
{
"text": "Family vacation to Phu Quoc, 4 adults 2 kids, all-inclusive resort",
"language": "en",
"entities": [
{"type": "location", "value": "phu-quoc"},
{"type": "destination", "value": "phu-quoc"},
{"type": "people", "value": {"adults": 4, "children": 2, "infants": 0}},
{"type": "hotel_type", "value": "resort"},
{"type": "travel_style", "value": "family"},
],
},
{
"text": "Weekend trip from Ho Chi Minh to Da Lat, renting a car",
"language": "en",
"entities": [
{"type": "location", "value": "hcmc"},
{"type": "location", "value": "da-lat"},
{"type": "origin", "value": "hcmc"},
{"type": "destination", "value": "da-lat"},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "transport", "value": "car"},
],
},
{
"text": "7-night Bali honeymoon, villa with private pool, $3000 budget",
"language": "en",
"entities": [
{"type": "location", "value": "bali"},
{"type": "destination", "value": "bali"},
{"type": "duration", "value": {"days": 8, "nights": 7}},
{"type": "hotel_type", "value": "villa"},
{"type": "travel_style", "value": "honeymoon"},
{"type": "budget", "value": {"amount": 3000.0, "currency": "USD"}},
],
},
{
"text": "Cultural trip to Hue and Hoi An, 5 days, heritage sites and photography",
"language": "en",
"entities": [
{"type": "location", "value": "hue"},
{"type": "location", "value": "hoi-an"},
{"type": "destination", "value": "hue"},
{"type": "destination", "value": "hoi-an"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
{"type": "travel_style", "value": "cultural"},
{"type": "activity_preference", "value": "photography"},
],
},
{
"text": "Budget guesthouse in Hanoi Old Quarter, solo, 4 nights",
"language": "en",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "destination", "value": "hanoi"},
{"type": "hotel_type", "value": "guesthouse"},
{"type": "travel_style", "value": "solo"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
],
},
{
"text": "Business trip to Singapore 3 days, 4-star hotel near MRT, Korean food preferred",
"language": "en",
"entities": [
{"type": "location", "value": "singapore"},
{"type": "destination", "value": "singapore"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
{"type": "hotel_type", "value": "4-star"},
{"type": "travel_style", "value": "business"},
{"type": "transport", "value": "metro"},
{"type": "cuisine", "value": "korean"},
],
},
{
"text": "Honeymoon in Paris, spend more on accommodation, romantic dinners",
"language": "en",
"entities": [
{"type": "location", "value": "paris"},
{"type": "destination", "value": "paris"},
{"type": "travel_style", "value": "honeymoon"},
{"type": "travel_style", "value": "romantic"},
{"type": "budget_priority", "value": "accommodation:high"},
],
},
{
"text": "From Ho Chi Minh City to Nha Trang by train, 3 days 2 nights",
"language": "en",
"entities": [
{"type": "location", "value": "hcmc"},
{"type": "location", "value": "nha-trang"},
{"type": "origin", "value": "hcmc"},
{"type": "destination", "value": "nha-trang"},
{"type": "transport", "value": "train"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
],
},
{
"text": "Dive trip to Cebu, 5 days, no pork due to religious reason",
"language": "en",
"entities": [
{"type": "location", "value": "cebu"},
{"type": "destination", "value": "cebu"},
{"type": "duration", "value": {"days": 5, "nights": 4}},
{"type": "activity_preference", "value": "diving"},
{"type": "dietary", "value": "no_pork"},
],
},
{
"text": "Adventure trekking in Sapa, 3 days, save on food",
"language": "en",
"entities": [
{"type": "location", "value": "sapa"},
{"type": "destination", "value": "sapa"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
{"type": "travel_style", "value": "adventure"},
{"type": "activity_preference", "value": "trekking"},
{"type": "budget_priority", "value": "food:low"},
],
},
{
"text": "Cruise Ha Long Bay 3 days 2 nights, couple, seafood",
"language": "en",
"entities": [
{"type": "location", "value": "ha-long"},
{"type": "destination", "value": "ha-long"},
{"type": "duration", "value": {"days": 3, "nights": 2}},
{"type": "people", "value": {"adults": 2, "children": 0, "infants": 0}},
{"type": "cuisine", "value": "seafood"},
],
},
# === Edge cases: budget priority patterns ===
{
"text": "Đà Nẵng 4 ngày, tiết kiệm tiền ăn để chi nhiều cho chỗ ở",
"language": "vi",
"entities": [
{"type": "location", "value": "da-nang"},
{"type": "destination", "value": "da-nang"},
{"type": "duration", "value": {"days": 4, "nights": 3}},
{"type": "budget_priority", "value": "food:low"},
{"type": "budget_priority", "value": "accommodation:high"},
],
},
{
"text": "Hàn Quốc 6 ngày, ở khách sạn tốt nhưng ăn uống bình dân",
"language": "vi",
"entities": [
{"type": "location", "value": "seoul"},
{"type": "destination", "value": "seoul"},
{"type": "duration", "value": {"days": 6, "nights": 5}},
{"type": "budget_priority", "value": "accommodation:high"},
{"type": "budget_priority", "value": "food:low"},
],
},
# === Complex queries ===
{
"text": "Chuyến phượt 2 tuần từ Hà Nội xuống Sài Gòn bằng xe máy, budget 20 triệu",
"language": "vi",
"entities": [
{"type": "location", "value": "hanoi"},
{"type": "location", "value": "hcmc"},
{"type": "origin", "value": "hanoi"},
{"type": "destination", "value": "hcmc"},
{"type": "duration", "value": {"days": 14, "nights": 13}},
{"type": "transport", "value": "motorbike"},
{"type": "budget", "value": {"amount": 20000000.0, "currency": "VND"}},
{"type": "travel_style", "value": "backpacker"},
],
},
{
"text": "Tuần trăng mật Maldives 6 ngày 5 đêm, villa nổi trên mặt nước, $5000",
"language": "vi",
"entities": [
{"type": "destination", "value": "maldives"},
{"type": "duration", "value": {"days": 6, "nights": 5}},
{"type": "hotel_type", "value": "villa"},
{"type": "travel_style", "value": "honeymoon"},
{"type": "budget", "value": {"amount": 5000.0, "currency": "USD"}},
],
},
{
"text": "Nhóm 4 bạn phượt Đà Lạt cuối tuần, thuê xe máy, ở hostel",
"language": "vi",
"entities": [
{"type": "location", "value": "da-lat"},
{"type": "destination", "value": "da-lat"},
{"type": "people", "value": {"adults": 4, "children": 0, "infants": 0}},
{"type": "duration", "value": {"days": 2, "nights": 1}},
{"type": "transport", "value": "motorbike"},
{"type": "hotel_type", "value": "hostel"},
{"type": "travel_style", "value": "backpacker"},
],
},
{
"text": "Hành trình Châu Âu: Paris 3 ngày, Rome 3 ngày, Amsterdam 2 ngày",
"language": "vi",
"entities": [
{"type": "location", "value": "paris"},
{"type": "location", "value": "rome"},
{"type": "location", "value": "amsterdam"},
{"type": "destination", "value": "paris"},
{"type": "destination", "value": "rome"},
{"type": "destination", "value": "amsterdam"},
{"type": "duration", "value": {"days": 8, "nights": 7}},
],
},
{
"text": "Vợ chồng đi Nhật 10 ngày, ăn chay, đi tàu bullet train khắp nơi",
"language": "vi",
"entities": [
{"type": "location", "value": "tokyo"},
{"type": "destination", "value": "tokyo"},
{"type": "people", "value": {"adults": 2, "children": 0, "infants": 0}},
{"type": "duration", "value": {"days": 10, "nights": 9}},
{"type": "dietary", "value": "vegetarian"},
{"type": "transport", "value": "train"},
],
},
]
assert len(NER_EVAL_ADDITIONAL) == 56, f"Expected 56 additional NER samples, got {len(NER_EVAL_ADDITIONAL)}"
def main():
# ---------- Task 1: Append compare_destinations to intent dataset ----------
print(f"Loading intent dataset: {INTENT_FILE}")
with open(INTENT_FILE, "r", encoding="utf-8") as f:
intent_data = json.load(f)
existing_intents = set(item["intent"] for item in intent_data)
if "compare_destinations" in existing_intents:
existing_count = sum(1 for item in intent_data if item["intent"] == "compare_destinations")
print(f"compare_destinations already has {existing_count} samples, skipping generation.")
else:
new_samples = (
[{"text": t, "intent": "compare_destinations"} for t in COMPARE_DESTINATIONS_VI]
+ [{"text": t, "intent": "compare_destinations"} for t in COMPARE_DESTINATIONS_EN]
)
intent_data.extend(new_samples)
with open(INTENT_FILE, "w", encoding="utf-8") as f:
json.dump(intent_data, f, ensure_ascii=False, indent=2)
print(f"Added {len(new_samples)} compare_destinations samples -> {INTENT_FILE}")
print(f"New total: {len(intent_data)} samples, {len(existing_intents) + 1} intents")
# ---------- Task 2: Expand ner_eval.json ----------
print(f"\nLoading NER eval fixture: {NER_FILE}")
with open(NER_FILE, "r", encoding="utf-8") as f:
ner_data = json.load(f)
original_count = len(ner_data)
existing_texts = {item["text"] for item in ner_data}
to_add = [s for s in NER_EVAL_ADDITIONAL if s["text"] not in existing_texts]
ner_data.extend(to_add)
with open(NER_FILE, "w", encoding="utf-8") as f:
json.dump(ner_data, f, ensure_ascii=False, indent=2)
print(f"NER eval: {original_count} -> {len(ner_data)} samples (+{len(to_add)} added) -> {NER_FILE}")
if len(ner_data) < 80:
print(f"WARNING: only {len(ner_data)} samples (target: 80+). Add more manually if needed.")
if __name__ == "__main__":
main()