File size: 36,561 Bytes
6feeee8 | 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 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | """
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()
|