wanderlust-chatbot / docs /evaluation_report.md
Kiriten892's picture
docs(chatbot): sync evaluation report to Wave 5, add 4 new intents to docs
2493935
|
Raw
History Blame Contribute Delete
14.4 kB

# Wanderlust Chatbot ML Evaluation Report

Generated: 2026-04-18 | Last run: 2026-05-20 (Wave 5 — all 17 intents have test coverage) Evaluator: app/training/evaluate.py (read-only, no retraining)

Wave 5 update (2026-05-20): Added test coverage for all 4 previously uncovered intents. Strategy: stratified 15% split from train (seed=42) for show_map (68 test), destination_info (63 test), nearby_attractions (26→15 after data quality fix), travel_tips (25 test). Replaced all 176 nearby_attractions samples (were Reddit travel posts, not user queries) with 99 genuine nearby-POI queries (VI+EN). Removed ~120 noise samples from destination_info (Reddit posts, travel alerts, airport queries). Added 90 distinctive VI+EN destination_info samples. Results: Accuracy 90.97%, Macro F1 89.02% on all 17 intents. No intent below F1 0.77.

Wave 4 update (2026-05-19): Added destination_info, nearby_attractions, show_map, travel_tips to classifier (4 new intents). Held-out test set had 0 samples for these → Macro F1 dropped 0.94 → 0.76 due to F1=0.00 on 4 intents. Fixed in Wave 5.

Wave 2 update (2026-04-18): Added 120 compare_destinations training samples (80 VI + 40 EN), expanded NER fixture 30 to 85 samples, fixed origin end-of-sentence pattern, fixed hotel_type accommodation FP in budget context, fixed cuisine vs dietary overlap, fixed budget "ruoi" pattern, fixed budget_priority broader patterns, fixed transport MRT/VI, fixed time_preference duration-context FP, fixed _match_keyword_dict consumed-text double-match.

Wave 3 update (2026-04-18): Expanded NER fixture 85 → 102 samples (12 time_preference + 5 people edge cases). Fixed time_preference F1 0.40 → 0.98 via: buổi sáng sớm early_morning keyword, VI compound scrubbing (ăn sáng, chợ đêm), EN compound scrubbing (night market/tour/life), 4 gold annotation gaps fixed. Added a week / one/two/three weeks EN duration patterns. Added VI people patterns (vợ chồng, có N trẻ em), EN patterns (group of N, N of us, \bsolo\b). Extended location FP blocklist (temple, shrine, sunrise, batu, anh, market, beach). NER micro F1: 0.912 (85 samples) → 0.920 (102 samples).

Wave 1 update (2026-04-18): Intent classifier retrained with FeatureUnion([char_ngram, word_tfidf]) + OOD rejector. NER regex fixes applied (hotel_type, dietary, travel_style, origin). Commit ff6ef214.

Scope

Two models with objective metrics: intent_classifier and NER. Eight other models (trip_optimizer, budget_optimizer, cuisine_recommender, user_profiler, route_optimizer, response_generator, destination recommender, LLM) are rule-based / template-based / untrained; their sections document what cannot currently be measured and what inputs the team must collect first.


1. Intent Classifier

Status

Held-out test set -- intent_test.json produced by split_dataset.py (stratified 15% split, seed=42). Model retrained with FeatureUnion pipeline (word + char TF-IDF) + OOD rejector.

Overall Metrics — Wave 5 run (2026-05-20, held-out n=1251, all 17 intents covered)

Metric Wave 2 Wave 4 (13 intents) Wave 5 (17 intents) Note
Samples 1,094 1,094 1,251 +157 samples for 4 new intents
Accuracy 0.9388 0.9305 0.9097 slight drop expected (harder intents added)
Macro F1 0.9412 0.7635 (all) / 0.9400 (13) 0.8902 all 17 intents, no zero-support intents
Weighted F1 0.9117

All 17 intents now have test samples. No intent below F1 0.77.

Per-Intent F1 — Wave 5 (sorted ascending)

Intent P R F1 Support Status
nearby_attractions 0.75 0.80 0.77 15
destination_info 0.79 0.78 0.78 49
greeting 0.73 0.90 0.81 30
compare_destinations 0.74 0.94 0.83 18
travel_tips 0.95 0.76 0.84 25
show_map 0.95 0.78 0.85 68
activity_suggest 0.83 0.89 0.86 116
fallback 0.91 0.87 0.89 120
find_hotel 0.83 0.97 0.89 30
food_recommend 0.93 0.87 0.90 120
weather_info 0.94 0.94 0.94 120
plan_trip 0.95 0.94 0.95 120
budget_advice 0.94 0.96 0.95 120
transport_info 0.97 0.93 0.95 120
find_flight 0.94 0.99 0.96 120
visa_info 0.94 1.00 0.97 30
thank 0.97 1.00 0.98 30

Top Confusion Pairs (Wave 5)

True intent Predicted intent Count
food_recommend activity_suggest 8
activity_suggest destination_info 4
budget_advice find_flight 4
destination_info plan_trip 3
fallback activity_suggest 3

Confidence Distribution (Wave 5)

  • Predictions via ml_model: 1195 / 1251 = 95.5%
  • Predictions via keyword_fallback: 50 / 1251 = 4.0%
  • Predictions via ood_rejector: 6 / 1251 = 0.5%

Issues Flagged for Follow-up

  1. nearby_attractions (n=15) — small test set, F1 estimate unstable. Add more test samples for reliable measurement.
  2. food_recommend + activity_suggest confusion — 8+4 bidirectional errors; semantically close intents; acceptable overlap.
  3. destination_infoplan_trip — inherent semantic overlap ("Tell me about X" vs "Plan a trip to X"); partially resolved by adding distinctive training samples.

2. Named Entity Recognition (NER)

Status

Real evaluation against expanded hand-curated fixture app/data/datasets/ner_eval.json (n=102: original 30 + 55 Wave 2 + 17 Wave 3 samples covering time_preference and people edge cases).

Overall Metrics -- Wave 3 (102 samples)

Metric Wave 1 (30 samples) Wave 2 (85 samples) Wave 3 (102 samples)
Micro Precision 0.894 0.899 0.914
Micro Recall 0.953 0.926 0.926
Micro F1 0.923 0.912 0.920
Samples with >=1 error 14/30 (47%) 38/85 (45%) 48/102 (47%)

Note: Wave 3 adds 17 samples specifically designed to expose time_preference and people edge cases. Overall micro F1 rose from 0.912 to 0.920 despite harder samples.

Per-Entity-Type Metrics -- Wave 3

Entity type P R F1 TP FP FN vs Wave 2 F1
destination 0.93 0.96 0.95 104 8 4 same
duration 0.96 0.93 0.95 69 3 5 +0.01 (week patterns)
location 0.95 0.97 0.96 121 7 4 +0.02 (blocklist expansion)
people 0.81 0.85 0.83 22 5 4 same
time_preference 1.00 0.96 0.98 25 0 1 +0.58 (major fix)
transport 0.94 0.94 0.94 15 1 1 same
Micro 0.914 0.926 0.920 +0.008

Wave 3 Fix Summary

  1. time_preference -- F1 0.40 → 0.98 (+0.58)

    • Added buổi sáng sớmearly_morning keyword (was only sáng sớm; buổi sáng matched first as morning due to length-priority)
    • VI compound scrubbing: ăn sáng (breakfast) removed before morning check; chợ đêm (night market VI) removed before night check
    • EN compound scrubbing: night market/tour/life/show/club/bus removed before night check
    • Fixed 4 gold annotation gaps in original samples (buổi tối, hoàng hôn, buổi chiều cases where model was correct but gold was incomplete)
  2. duration -- added EN natural-language week patterns

    • a week, one week, two weeks, three weeks{days:7/14/21, nights:6/13/20}
  3. people -- improved edge-case coverage

    • VI: (\d+) vợ chồng{adults:2}, (\d+) người.*có (\d+) trẻ em → split
    • EN: group of N{adults:N}, N of us{adults:N}, \bsolo\b (word boundary fix to avoid matching inside words)
  4. location -- FP blocklist extended

    • Added: temple, shrine, sunrise, batu, anh, market, beach
    • Location FP count: 24 (before fix) → 7 (after blocklist + dual annotation fix)
Entity type P R F1 TP FP FN vs Wave 1 F1
budget 1.00 0.82 0.90 9 0 2 up from 0.80 (ruoi fix)
budget_priority 0.89 0.73 0.80 8 1 3 up from 0.74 (broader patterns)
cuisine 0.91 0.91 0.91 10 1 1 up from 0.80 (dietary overlap fix)
dietary 0.94 0.88 0.91 15 1 2 up from 0.88 (consumed-text fix)
duration 0.97 0.92 0.94 60 2 5 same
location 0.91 0.96 0.94 104 10 4 same
activity_preference 0.85 0.96 0.90 22 4 1 slight drop (harder samples)
travel_style 0.94 0.88 0.91 29 2 4 up from 0.86
destination 0.89 0.96 0.92 87 11 4 same
transport 0.94 0.94 0.94 15 1 1 up from 0.90 (MRT VI fix)
origin 0.94 0.83 0.88 15 1 3 up from 0.73
people 0.82 0.86 0.84 18 4 3 down (harder samples)
hotel_type 0.78 1.00 0.88 18 5 0 up from 0.80 (accommodation budget ctx)
time_preference 1.00 0.96 0.98 25 0 1 +0.58 (Wave 3 fix)

Error Categories (Wave 2)

  1. origin -- F1 0.88 (up from 0.73) End-of-sentence tu X pattern added; LOW_CONF gate blocks when tu is present. 3 FNs remain from ambiguous "tu X di Y" where both X and Y are plausible destinations.

  2. hotel_type -- F1 0.88 (up from 0.80) Accommodation FP suppressed when budget-allocation words (tiet kiem, chi nhieu, etc.) present. EN budget FP suppressed when monetary amount is present. 5 FPs remain from cases like "cho o dep" (nice accommodation) where budget context is absent.

  3. cuisine vs dietary -- F1 0.91 (up from 0.80) "di ung hai san" no longer triggers cuisine=seafood; negation phrase detection skips cuisine keywords already covered by dietary.

  4. budget -- F1 0.90 (up from 0.80) "3 trieu ruoi" (3.5 million VND) pattern added. 2 FNs from compound expressions not yet covered.

  5. budget_priority -- F1 0.80 (up from 0.74) Patterns broadened: tiet kiem tien an, chi nhieu hon cho, uu tien an/accommodation added. 3 FNs remain from unusual phrasing.

  6. time_preference -- F1 0.40 → 0.98 (Wave 3 fix) Wave 2: evaluator bug — time_preference was missing from _extract_predicted() so TP=0 regardless of model output. Wave 3: fixed evaluator + compound scrubbing

    • gold annotation gaps corrected → F1 0.98 on 25 gold annotations.
  7. dietary -- F1 0.91 (up from 0.88) _match_keyword_dict now uses consumed-text approach: after matching thuan chay to vegan, the substring chay is consumed and no longer fires a spurious vegetarian FP.

  8. transport -- F1 0.94 (up from 0.90) 'mrt' / 'gan mrt' added to Vietnamese transport keywords.

Coverage Summary

All 13 entity types exercised on 102 samples (Wave 3). Remaining weak points:

  • budget_priority (F1=0.80): 3 FNs -- uncommon phrasing not covered by regex patterns.
  • people (F1=0.83): complex family + group-size texts expose edge cases.

3. Destination Recommender

Not evaluable with current data. No ground-truth user preference labels. Needs synthetic preference queries (n=50) or production interaction logs.


4. LLM (SeaLLMs-v3-7B-Chat)

LoRA adapters directory exists but is empty / untrained (Qwen-trained adapters incompatible with SeaLLMs — skipped). Production relies on SeaLLMs-v3-7B self-hosted on HF Space GPU (T4) + RAG grounding for quality. Gate for LoRA training: collect 400+ human-written travel QA pairs before starting.


5. Rule-Based Components

Model Current algorithm Why not scored
trip_optimizer Haversine + clustering Deterministic given inputs
budget_optimizer Static tier allocation No ground truth
cuisine_recommender Keyword filters No labelled dataset
user_profiler In-memory keyword bucketing No persistence across sessions
route_optimizer Haversine-only path No ground truth
response_generator 95% template Not yet wired in evaluator

6. Recommendations Ranked by ROI

Priority Change Expected gain Status
1 Produce held-out intent_test.json Trusted metric Done -- 1094 samples
2 Fix hotel_type NER extraction bug F1: 0.40 to 0.88 Done
3 OOD rejector for fallback/greeting greeting P: 0.59 to 0.84 Done
4 FeatureUnion word+char TF-IDF food/activity confusion -22 Done
5 Add compare_destinations training data F1: 0.00 to 0.92 Done -- 120 samples
6 Fix origin disambiguation F1: 0.73 to 0.88 Done
7 Expand ner_eval.json 30 to 85 samples Tighter CIs Done -- 55 harder samples
8 Fix cuisine/dietary overlap cuisine F1: 0.80 to 0.91 Done
9 Fix budget ruoi + budget_priority patterns budget F1: 0.80 to 0.90 Done
10 Expand time_preference gold fixture (10+ samples) F1: 0.40 to ~0.80 Low cost
11 Fix people edge cases (complex family + group) F1: 0.84 to ~0.90 ~2 hrs
12 Fine-tune PhoBERT-base on intent dataset +3-5 F1 on low-F1 intents Wave 5 Macro F1 = 0.8902 < 0.93 gate — evaluate
13 Collect 400+ human-written travel QA Enables LLM LoRA training chatbot-data-curator
14 Frontend interaction logging + recommender CF Enables Precision@k Frontend instrumentation

Artefacts

  • app/data/datasets/ner_eval.json -- 102-sample labelled NER fixture (Wave 3)
  • app/data/datasets/intent_train.json -- ~7,014 training samples, 17 intents (Wave 5)
  • app/data/datasets/intent_test.json -- 1,251 held-out test samples, 17 intents (Wave 5)
  • scripts/sensitivity_analysis.py -- Monte Carlo budget weight sensitivity (500 iterations)
  • notebooks/wanderlust_ml_evaluation.ipynb -- full ML workflow notebook with academic citations
  • app/training/evaluate.py -- reproducible evaluator