Spaces:
Sleeping
Sleeping
| """ | |
| 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() | |