Upload README.md
Browse files
README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language: vi
|
| 3 |
+
tags:
|
| 4 |
+
- ner
|
| 5 |
+
- conditional-random-field
|
| 6 |
+
- crf
|
| 7 |
+
- sklearn-crfsuite
|
| 8 |
+
- vietnamese
|
| 9 |
+
- food-order
|
| 10 |
+
- cs221
|
| 11 |
+
metrics:
|
| 12 |
+
- f1
|
| 13 |
+
- precision
|
| 14 |
+
- recall
|
| 15 |
+
- accuracy
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
# CRF-FoodNER: Conditional Random Fields Baseline for Vietnamese Food Order Extraction
|
| 19 |
+
|
| 20 |
+
#### Table of contents
|
| 21 |
+
1. [Introduction](#introduction)
|
| 22 |
+
2. [Dataset Overview](#dataset)
|
| 23 |
+
3. [Empirical Evaluation](#evaluation)
|
| 24 |
+
4. [Architecture Characteristics (CRF vs Deep Learning)](#characteristics)
|
| 25 |
+
5. [Using CRF-FoodNER with Python](#usage)
|
| 26 |
+
6. [Authors & Citation](#citation)
|
| 27 |
+
|
| 28 |
+
---
|
| 29 |
+
|
| 30 |
+
## <a name="introduction"></a> 1. Introduction
|
| 31 |
+
|
| 32 |
+
**`CS221DoAn/Do_an_group_CRF`** is a machine learning model based on **Conditional Random Fields (CRF)**. It is specifically trained for **Named Entity Recognition (NER)** on domain-specific Vietnamese unstructured text: **Online Food Delivery Orders and Messages**.
|
| 33 |
+
|
| 34 |
+
In our research project for the CS221.Q21 course (Natural Language Processing), this CRF model serves as a traditional statistical baseline to compare against modern deep-learning Transformer architectures (PhoBERT, mBERT). It computes the conditional probability distribution of the entire output label sequence given the input observation sequence, relying on Emission and Transition matrices.
|
| 35 |
+
|
| 36 |
+
## <a name="dataset"></a> 2. Dataset Overview
|
| 37 |
+
|
| 38 |
+
The model was trained on a custom, manually annotated dataset consisting of **2,325 real-world food ordering messages** extracted from Facebook comments (specifically from Sơn Nguyễn vegetarian restaurant).
|
| 39 |
+
* **Train Set:** 1,860 samples (80%)
|
| 40 |
+
* **Validation Set:** 232 samples (10%)
|
| 41 |
+
* **Test Set:** 233 samples (10%)
|
| 42 |
+
|
| 43 |
+
## <a name="evaluation"></a> 3. Empirical Evaluation
|
| 44 |
+
|
| 45 |
+
The model was evaluated on an unseen Test Set using strict **Entity-level F1-Scores** via the `seqeval` framework.
|
| 46 |
+
|
| 47 |
+
* **CRF Macro F1-Score:** `0.9889`
|
| 48 |
+
* **Comparison:** The CRF model achieved an impressively high Macro F1-score (0.9889), outperforming BiLSTM-CRF (0.9771) and slightly outperforming mBERT (0.9880). However, it remains lower than the PhoBERT architecture (0.9913).
|
| 49 |
+
|
| 50 |
+
## <a name="characteristics"></a> 4. Architecture Characteristics (CRF vs Deep Learning)
|
| 51 |
+
|
| 52 |
+
While CRF performs exceptionally well, our empirical analysis highlights its inherent limitations when processing social media text compared to architectures like PhoBERT:
|
| 53 |
+
|
| 54 |
+
* **Transition Constraints:** The Viterbi decoding algorithm allows CRF to strictly control the logical constraints of the BIO tagging scheme (e.g., the transition probability from `O` to `I-FOOD` is exactly 0).
|
| 55 |
+
* **Out-of-Vocabulary (OOV) Vulnerability:** CRF depends entirely on frequency matrices and manual Feature Engineering. When encountering social media text with heavy abbreviations, typos, or teencode, CRF struggles to find matching dictionary features.
|
| 56 |
+
* Unlike PhoBERT, which uses Byte-Pair Encoding (BPE) to break down OOV words into meaningful subwords, CRF lacks the ability to preserve vector representations for unknown linguistic noise.
|
| 57 |
+
|
| 58 |
+
## <a name="usage"></a> 5. Using CRF-FoodNER with Python
|
| 59 |
+
|
| 60 |
+
To use this model, you need to install the `huggingface_hub` and `sklearn-crfsuite` libraries.
|
| 61 |
+
|
| 62 |
+
### Installation
|
| 63 |
+
```bash
|
| 64 |
+
pip install huggingface_hub sklearn-crfsuite
|
| 65 |
+
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
### Example usage (Inference Pipeline)
|
| 69 |
+
|
| 70 |
+
> **⚠️ IMPORTANT:** You MUST replace the `word2features` function below with the exact feature extraction function you used during the training phase. Otherwise, the model will not understand the input data format.
|
| 71 |
+
|
| 72 |
+
```py3
|
| 73 |
+
import pickle
|
| 74 |
+
from huggingface_hub import hf_hub_download
|
| 75 |
+
|
| 76 |
+
# 1. Download and load the .pkl model from Hugging Face Hub
|
| 77 |
+
REPO_ID = "CS221DoAn/Do_an_group_CRF"
|
| 78 |
+
FILENAME = "crf_model.pkl"
|
| 79 |
+
|
| 80 |
+
print("Downloading and loading the CRF model...")
|
| 81 |
+
model_path = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
|
| 82 |
+
|
| 83 |
+
with open(model_path, "rb") as f:
|
| 84 |
+
crf_model = pickle.load(f)
|
| 85 |
+
|
| 86 |
+
# 2. Define the Feature Extraction Function (MUST MATCH YOUR TRAINING CODE)
|
| 87 |
+
def word2features(sent, i):
|
| 88 |
+
word = sent[i]
|
| 89 |
+
# --- REPLACE THIS BLOCK WITH YOUR ACTUAL FEATURE ENGINEERING LOGIC ---
|
| 90 |
+
features = {
|
| 91 |
+
'bias': 1.0,
|
| 92 |
+
'word.lower()': word.lower(),
|
| 93 |
+
'word.isupper()': word.isupper(),
|
| 94 |
+
'word.istitle()': word.istitle(),
|
| 95 |
+
'word.isdigit()': word.isdigit(),
|
| 96 |
+
'word[:2]': word[:2] if len(word) > 2 else word,
|
| 97 |
+
'word[-2:]': word[-2:] if len(word) > 2 else word,
|
| 98 |
+
}
|
| 99 |
+
# ---------------------------------------------------------------------
|
| 100 |
+
return features
|
| 101 |
+
|
| 102 |
+
def sent2features(sent):
|
| 103 |
+
return [word2features(sent, i) for i in range(len(sent))]
|
| 104 |
+
|
| 105 |
+
# 3. Predict Function
|
| 106 |
+
def predict_food_order(raw_text):
|
| 107 |
+
print(f"\nInput: {raw_text}")
|
| 108 |
+
print("=" * 60)
|
| 109 |
+
|
| 110 |
+
# Simple whitespace tokenization (Replace with VnCoreNLP if you used it during training)
|
| 111 |
+
tokens = raw_text.split()
|
| 112 |
+
|
| 113 |
+
# Extract features
|
| 114 |
+
features = [sent2features(tokens)]
|
| 115 |
+
|
| 116 |
+
# Predict
|
| 117 |
+
preds = crf_model.predict(features)[0]
|
| 118 |
+
|
| 119 |
+
# Display Extracted Entities
|
| 120 |
+
for token, label in zip(tokens, preds):
|
| 121 |
+
print(f"{token:<20} {label}")
|
| 122 |
+
|
| 123 |
+
# --- EXECUTE TEST CASES ---
|
| 124 |
+
test_cases = [
|
| 125 |
+
"1p cải xào, gà lát chiên giòn, chả giò, cơm thêm",
|
| 126 |
+
"giao rào b4, 11h30. 0773570xxx."
|
| 127 |
+
]
|
| 128 |
+
|
| 129 |
+
for sample in test_cases:
|
| 130 |
+
predict_food_order(sample)
|
| 131 |
+
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
## 6. Authors & Citation
|
| 135 |
+
|
| 136 |
+
This project was developed for the **Natural Language Processing (CS221.Q21)** course at the University of Information Technology (UIT) - VNU-HCM.
|
| 137 |
+
|
| 138 |
+
* **Students:** Võ Thành Lộc (24520989), Nguyễn Anh Nguyên (24521185)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
* **Instructor:** Ph.D. Nguyễn Trọng Chỉnh
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
* **Date:** July 2026
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
If you use this model in your academic research or projects, please cite our project:
|
| 149 |
+
|
| 150 |
+
```bibtex
|
| 151 |
+
@misc{cs221_food_order_ner_crf,
|
| 152 |
+
author = {Vo Thanh Loc and Nguyen Anh Nguyen},
|
| 153 |
+
title = {Food Order Extraction: Conditional Random Fields Baseline for Vietnamese NER},
|
| 154 |
+
year = {2026},
|
| 155 |
+
publisher = {Hugging Face},
|
| 156 |
+
howpublished = {(https://huggingface.co/CS221DoAn/Do_an_group_CRF)}
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
```
|
| 162 |
+
|
| 163 |
+
```
|