ကျွန်တော်တို့ စာရေးတဲ့အခါမှာ အင်္ဂလိပ်စာလိုမျိုး စာလုံးတွေကို ဖြတ်ပြီးရေးလေ့မရှိတာကြောင့်၊ NLP/AI အလုပ်တွေအတွက် မြန်မာစာကြောင်းတွေကို စာလုံးဖြတ်ရတဲ့အလုပ်က တကယ်ခက်ခဲပါတယ်။ အဲဒါကြောင့် ကျွန်တော်ဦးဆောင်နေတဲ့ Language Understanding Lab. မှာ Word Segmentation သုတေသနအလုပ်တွေကို အချိန်ရရင်ရသလို ဆက်တိုက်လုပ်ဖြစ်နေပါတယ်။ တချို့အလုပ်တွေအတွက် sylbreak နဲ့ ဝဏ္ဏဖြတ်ပြီး လုပ်တယ်၊ တချို့အလုပ်တွေအတွက် myWord နဲ့ စာလုံးဖြတ်တယ်။ ဒါ့အပြင် ငါးပိလို့ နာမည်ပေးထားတဲ့ semantic chunking လိုမျိုး စာလုံးတွေကို ဗက်တာပြောင်းပြီး အဓိပ္ပါယ်ပါ ဆွဲယူဖို့ ဖြစ်နိုင်တဲ့ စာလုံးဖြတ်နည်းတွေကိုလည်း လေ့လာစမ်းသပ်ဖြစ်ခဲ့ပါတယ်။ ဒီရက်ပိုင်းတွေအတွင်းမှာ Lab ရဲ့ internship ကျောင်းသားတွေကို word segmentation နဲ့ပတ်သက်တာလည်း စာသင်ဖို့ပြင်ရင်းနဲ့ ဟိုးအရင်က စမ်းခဲ့ဖူးတဲ့ DAG (directed acyclic graph) ဘက်ကို ပြန်လှည့်ဖြစ်ခဲ့ပါတယ်။ အိုက်ဒီရာအနေနဲ့ကတော့ ARPA n-gram language model ရယ် syllable frequency count တွေရယ်နဲ့ မြန်မာစာ စာလုံးတွေကို ဖြတ်တဲ့ နည်းလမ်းပါ။ သူက OOV ကိုလည်း backoff နဲ့ ရှောင်လို့ ရတာမို့ ကျွန်တော်က စိတ်ဝင်စားတယ်။ လက်တွေ့မှာက မြန်မာစာအတွက် တကယ်ကောင်းတဲ့ language model ဆောက်ဖို့ဆိုတာက မလွယ်ကူပါဘူး။ အမျိုးမျိုး ကြိုးစားကြည့်လည်း ရလဒ်က ထင်သလောက် တက်မလာပါဘူး။ အဲဒါနဲ့ နောက်ဆုံးတော့ အဘိဓာန် နဲ့ bidirectional maximum matching ကိုပါ တွဲလိုက်ပြီး score လုပ်တာ fallback လုပ်တာတွေနဲ့ တွဲဖြစ်သွားပါတယ်။ ရလဒ်က --bimm-boost နဲ့ tuning လုပ်ရင်း F1-score 90+ ထိ တက်အောင် လုပ်လို့ရတာကို ရှာဖွေတွေ့ရှိခဲ့တယ်။ အဲဒါနဲ့ပဲ ကျောင်းသား၊ ကျောင်းသူတွေကိုလည်း Hybrid DAG + Bi-MM + LM architecture ကိုအခြေခံတဲ့ word segmentation ကို မိတ်ဆက်ပေးရင်း ဒီ oppaWord ကို အများသုံးလို့ရဖို့အထိ coding ဆက်လုပ်ဖြစ်ခဲ့တယ်။
oppaWord ဆိုတဲ့ နာမည်လား။ အစက ARPA LM ကို သုံးထားတာမို့လို့ arpaWord ဆိုပြီး နာမည်ပေးဖို့ စဉ်းစားခဲ့တာ။ တကယ်တမ်းက hybrid_dag_bimm_lm.py ဆိုပြီး ပေးရင်တော့ သုံးထားတဲ့ approach အားလုံးလိုလိုကို ခြုံငုံမိပါတယ်။ ခက်တာက အများအတွက် မှတ်မိဖို့ ခက်ပါလိမ့်မယ်။ လက်ရှိ ကိုရီးယား စကားလုံး oppa (오빠) ဆိုရင်တော့ မြန်မာလူငယ်တိုင်းလိုလို ရင်းနှီးပြီးသား ဖြစ်ပါလိမ့်မယ်။ ပြီးတော့ ၁၀တန်းအပြီးမှာ နှစ်တော်တော်ကြာကြာ တိုက်ကွမ်ဒိုအားကစားကို လုပ်ဖြစ်ခဲ့တဲ့ ငယ်ဘဝ အမှတ်တရတွေရယ်၊ ကျွန်တော်ရဲ့ တိုက်ကွမ်ဒိုဆရာတွေအများကြီးထဲကတစ်ဦးဖြစ်တဲ့ ကမ္ဘာ့ချန်ပီယံ ဆရာဂျွန် ကိုလည်း သတိရတာနဲ့ oppaWord လို့ပဲ နာမည်ပေးဖြစ်ခဲ့ပါတယ်။
လက်ရှိအချိန်ထိ အမျိုးမျိုး experiment တွေ လုပ်ကြည့်ခဲ့ပြီး စာကြောင်းရေ လေးသောင်းကျော်ကို (e.g. myPOS corpus တစ်ခုလုံး) စာလုံးဖြတ်ကြည့်တာ ၃ စက္ကန့်တောင် မကြာပါဘူး။ အဲဒါကြောင့် လက်ရှိအချိန်ထိ မြန်မာစာအတွက် အမြန်ဆုံး word segmenter ပါပဲ။ 오ppa빠ord ကို အားပေးကြပါဦးလို့။
ရဲကျော်သူ
4 Aug 2025
Myanmar language lacks strict word boundary rules, making word segmentation essential for NLP tasks. While existing tools like sylbreak (syllable segmenter) and myWord (multi-level segmenter) exist, oppaWord fills the critical need for a fast, training-free word segmenter with domain adaptation capabilities through:
- Hybrid DAG + Bi-MM + LM architecture
- Post-editing rule support
- Visual debugging tools
- Syllable-level processing
Key Advantages:
- Faster than Neural Network based segmenters
- No training required - just provide a dictionary
- Tunable segmentation strategies via simple parameters
oppaWord combines three core techniques:
-
DAG Construction:
- Builds all possible segmentations (3-12 syllable lengths)
- Scores paths using dictionary, frequency, and language model features
-
Bidirectional Maximum Matching (Bi-MM):
- Fallback mechanism when DAG paths are uncertain
- Configurable score boosting (
--bimm-boost)
-
Multi-Feature Scoring:
Total_Score = Dict_Weight + Syllable_Freq + LM_Score + (Bi-MM_Boost)
git clone https://github.com/ye-kyaw-thu/oppaWord.git
cd oppaWord
7z x data/5gramLM.7z.001 # Extract language model
python oppa_word.py \
--input input.txt \
--dict data/myg2p_mypos.dict \
--output segmented.txt
oppaWord achieves remarkable processing speeds even on large corpora. Here's a benchmark from segmenting the entire myPOS corpus (43,196 sentences) without using a language model:
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ time python oppa_word.py \
--input ../../corpus_info/tool/dagWord/data/mypos-ver.3.0.shuf.notag.nopunc.txt.seg_normalized2 \
--dict data/myg2p_mypos.dict \
--space-remove-mode my_not_num \
--use-bimm-fallback \
--bimm-boost 150 \
--output ./mypos-ver.3.0.noLM.norules.token.txt
real 0m2.586s # Total elapsed time (including space removal preprocessing)
user 0m2.555s
sys 0m0.024sFor best accuracy with current 5-gram LM:
python oppa_word.py \
--input text.txt \
--dict data/myg2p_mypos.dict \
--arpa data/myMono_clean_syl.trie.bin \
--use-bimm-fallback \
--bimm-boost 150 \
--space-remove-mode "my_not_num"
$ python ./oppa_word.py --help
usage: oppa_word.py [-h] --input INPUT [--output OUTPUT] --dict DICT [--sylfreq SYLFREQ] [--arpa ARPA]
[--postrule-file POSTRULE_FILE] [--max-order MAX_ORDER] [--dict-weight DICT_WEIGHT]
[--use-bimm-fallback] [--bimm-boost BIMM_BOOST] [--visualize-dag] [--dag-output-dir DAG_OUTPUT_DIR]
[--space-remove-mode {all,my,my_not_num}] [--max-word-len MAX_WORD_LEN]
oppa_word, Hybrid DAG + BiMM + LM Myanmar Word Segmenter with optional Aho-Corasick support
options:
-h, --help show this help message and exit
--input INPUT, -i INPUT
Input file with one sentence per line (UTF-8)
--output OUTPUT, -o OUTPUT
Optional output file path (default: stdout)
--dict DICT, -d DICT Word dictionary file (one word per line)
--sylfreq SYLFREQ, -s SYLFREQ
Syllable frequency file (syllable<TAB>frequency, for scoring)
--arpa ARPA, -a ARPA ARPA-format syllable-level language model (optional)
--postrule-file POSTRULE_FILE
Optional post-processing rules (e.g., merging, corrections)
--max-order MAX_ORDER
Max LM n-gram order (default: 5)
--dict-weight DICT_WEIGHT
Dictionary path weight in scoring (default: 10.0)
--use-bimm-fallback Enable Bi-directional Maximum Matching as fallback
--bimm-boost BIMM_BOOST
Boost score added to Bi-MM fallback path (default: 0.0)
--visualize-dag Generate DAG visualization (PDF per sentence)
--dag-output-dir DAG_OUTPUT_DIR
Directory to save DAG PDFs if --visualize-dag is used (default: 'dag_viz')
--space-remove-mode {all,my,my_not_num}
Preprocessing mode to remove spaces: 'all', 'my' (Myanmar only), or 'my_not_num (Myanmar but not
including Myanmar numbers'
--max-word-len MAX_WORD_LEN
Maximum word length in syllables (3-12, default:6)
Debug segmentation decisions using DAG visualizations:
python oppa_word.py \
--input ./data/10lines.ref \
--dict ./data/myg2p_mypos.dict \
--space-remove-mode "my_not_num" \
--use-bimm-fallback \
--bimm-boost 150 \
--visualize-dag \
--dag-output-dir debug_viz2
Visualization Demo:
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ python oppa_word.py \
> --input ./data/10lines.ref \
> --dict ./data/myg2p_mypos.dict \
> --space-remove-mode "my_not_num" \
> --use-bimm-fallback \
> --bimm-boost 150 \
> --visualize-dag \
> --dag-output-dir debug_viz2
၁၉၆၂ ခုနှစ် ခန့်မှန်း သန်းခေါင်စာရင်း အရ လူဦး ရေ ၁၁၅၉၃၁ ယောက် ရှိ သည်
လူ တိုင်း တွင် သင့်မြတ် လျော်ကန် စွာ ကန့်သတ် ထား သည့် အလုပ်လုပ်ချိန် အပြင် လစာ နှင့်တကွ အခါ ကာလ အားလျော်စွာ သတ်မှတ် ထား သည့် အလုပ် အားလပ်ရက် များ ပါဝင် သည့် အနားယူခွင့် နှင့် အားလပ်ခွင့် ခံစားပိုင်ခွင့် ရှိ သည်
ဤ နည်း ကို စစ်ယူ သော နည်း ဟု ခေါ် သည်
စာပြန်ပွဲ ဆို တာ က အာဂုံဆောင် အလွတ်ကျက် ထား တဲ့ ပိဋကတ်သုံးပုံ စာပေ တွေ ကို စာစစ် သံဃာတော်ကြီး တွေ ရဲ့ ရှေ့မှာ အလွတ် ပြန် ပြီး ရွတ်ပြ ရ တာ ပေါ့
ဒီ မှာ ကျွန်တော့် သက်သေခံကတ် ပါ
၂၀ ရာစု မြန်မာ့ သမိုင်း သန်း ဝင်း လှိုင် ၂၀၀၉ ခု မေ လ ကံကော်ဝတ်ရည် စာပေ
ကျွန်တော် မျက်မှန် တစ် လက်လုပ် ချင်ပါတယ်
ကျွန်တော် တို့ က ဒီ အမှု ရဲ့ ကြံရာပါ ကို ဖမ်းမိ ဖို့ ကြိုးစား ခဲ့ တယ်
ကလေး မီးဖွား ဖို့ ခန့်မှန်း ရက် က ဘယ်တော့ ပါ လဲ
အရိုးရှင်းဆုံး ကာဗိုဟိုက်ဒရိတ် မှာ ဂလူးကို့စ် ဂလက်တို့စ် ဖရပ်တို့စ် စသည့် မိုနိုဆက်ကရိုက် များ ဖြစ် သည်
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ ls debug_viz2/
dag_line_0000.dot dag_line_0002.dot dag_line_0004.dot dag_line_0006.dot dag_line_0008.dot
dag_line_0000.pdf dag_line_0002.pdf dag_line_0004.pdf dag_line_0006.pdf dag_line_0008.pdf
dag_line_0001.dot dag_line_0003.dot dag_line_0005.dot dag_line_0007.dot dag_line_0009.dot
dag_line_0001.pdf dag_line_0003.pdf dag_line_0005.pdf dag_line_0007.pdf dag_line_0009.pdf
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$
Example output:
oppaWord/
├── data/ # Resource files
│ ├── myg2p_mypos.dict # Main dictionary
│ ├── myg2p_mypos_name.dict # Extended dictionary with Myanmar names
│ ├── myMono.freq # Syllable frequency counts
│ ├── myMono_clean_syl.trie.bin # 5-gram syllable LM (optimized binary)
│ └── rules.txt # Post-processing correction rules
├── doc/ # Documentation
├── tools/ # Evaluation and preprocessing scripts
└── oppa_word.py # Main segmenter code
Note: exp_1, exp_2, and exp_20250727_1553 are output folders from some earlier experiments.
- One sentence per line
- Space removal optional (handled by
--space-remove-mode)
oppaWord supports post-segmentation corrections through a rules file. This helps fix systematic errors and improve readability.
WRONG_FORM|||CORRECT_FORM
-
Exact Word Replacements:
ပါတယ်|||ပါ တယ် မရှိ|||မ ရှိ- Merges or splits exact word matches
- Example:
"ပါတယ်"→"ပါ တယ်"
-
Regular Expressions:
(\S)([၊။])|||\1 \2- Uses regex patterns to handle:
- Punctuation attachment (
"ပါ။"→"ပါ ။")
- Punctuation attachment (
- Regex syntax follows Python's re module
- Uses regex patterns to handle:
-
Best Practices
- Order Matters: Rules are applied top-to-bottom
- Balance Specificity:
- Prefer exact matches (
ပါဘူး|||ပါ ဘူး) over broad regex when possible
- Prefer exact matches (
- For speed: Use
--dict-only --bimm-boost 150 - For accuracy: Add
--arpa data/myMono_clean_syl.trie.bin - Domain adaptation:
- Customize
data/rules.txtfor post-editing - Add domain terms to dictionary
- Customize
We provide eval_segmentation.py - a comprehensive evaluation tool that offers:
-
Multi-Level Metrics:
- Word-Level: Precision, Recall, F1 (exact word matches)
- Boundary-Level: Accuracy of word boundaries
- Vocabulary-Level: Type-based analysis
-
Error Analysis:
- Categorizes errors into:
- Over-Segmentation: System incorrectly splits words
- Under-Segmentation: System incorrectly merges words
- Complex Errors: Mixed boundary mistakes
- Shows top-K most frequent errors (configurable with
--top-k)
- Categorizes errors into:
-
Efficient Processing:
- Handles large files (>500k words) in seconds
- Optional
--no-errorsflag for faster metric-only evaluation
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ python ./tools/eval_segmentation.py --help
usage: eval_segmentation.py [-h] -r REFERENCE [-H HYPOTHESIS] [--top-k TOP_K] [--no-errors]
Enhanced Word Segmentation Evaluator with Error Analysis
options:
-h, --help show this help message and exit
-r REFERENCE, --reference REFERENCE
Reference (gold standard) file (default: None)
-H HYPOTHESIS, --hypothesis HYPOTHESIS
Hypothesis (system output) file (use - for stdin) (default: -)
--top-k TOP_K Show top K most frequent errors (default: 10)
--no-errors Skip error analysis to save time (default: False)
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$
python ./tools/eval_segmentation.py \
-r reference.txt \
-H hypothesis.txt > results.txtWord segmentation evaluation on the mypos-ver.3.0 corpus (43,196 sentences) using the following parameters: --dict, --space-remove-mode, --use-bimm-fallback, --bimm-boost, and --postrule:
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ time python oppa_word.py --input ../../corpus_info/tool/dagWord/data/mypos-ver.3.0.shuf.notag.nopunc.txt.seg_normalized2 \
--dict data/myg2p_mypos.dict --space-remove-mode my_not_num --use-bimm-fallback \
--bimm-boost 150 --postrule-file ./data/rules.txt --output ./mypos-ver.3.0.noLM.rules.token.txt
real 0m2.721s
user 0m2.688s
sys 0m0.026s
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$Running eval_segmentation.py to compare reference and hypothesis files, with output saved to result_noLM_Rule2.txt:
ye@lst-hpc3090:~/exp/myTokenizer/oppaWord$ python ./tools/eval_segmentation.py -r ../../corpus_info/tool/dagWord/data/mypos-ver.3.0.shuf.notag.nopunc.txt.seg_normalized2 \
-H ./mypos-ver.3.0.noLM.rules.token.txt > result_noLM_Rule2.txtContents of the evaluation output file (result_noLM_Rule2.txt):
Word Segmentation Evaluation Results
============================================================
Metric Score
------------------------------------------------------------
Word Precision 0.9120
Word Recall 0.8889
Word F1-score 0.9003
------------------------------------------------------------
Boundary Precision 0.6475
Boundary Recall 0.6311
Boundary F1-score 0.6392
------------------------------------------------------------
Vocab Precision 0.8754
Vocab Recall 0.9398
Vocab F1-score 0.9065
============================================================
Additional Statistics:
Reference words: 510437
Hypothesis words: 497503
Correct words: 453708
Reference vocabulary size: 24257
Hypothesis vocabulary size: 26042
Common vocabulary: 22797
Top Segmentation Errors Analysis
============================================================
Total errors: 57106
Most Frequent Over-Segmentation Errors (System split where it shouldn't):
120 × REF: 'သို့မဟုတ်' → HYP: 'သို့မ|ဟုတ်'
101 × REF: 'ဒါမှမဟုတ်' → HYP: 'ဒါမှမ|ဟုတ်'
81 × REF: 'ဒေါ်လာ' → HYP: 'ဒေါ်|လာ'
76 × REF: 'နာရီ' → HYP: 'နာ|ရီ'
57 × REF: 'ကျွန်တော်' → HYP: 'ကျွန်|တော်'
54 × REF: 'အသက်' → HYP: 'အ|သက်'
50 × REF: 'မိနစ်' → HYP: 'မိ|နစ်'
49 × REF: 'ညနေ' → HYP: 'ည|နေ'
47 × REF: 'မနက်' → HYP: 'မ|နက်'
42 × REF: 'အမှတ်' → HYP: 'အ|မှတ်'
Most Frequent Under-Segmentation Errors (System joined what should be separate):
247 × REF: 'မ|ရ' → HYP: 'မရ'
175 × REF: 'တစ်|ခု|ခု' → HYP: 'တစ်ခုခု'
137 × REF: 'ယဉ်ကျေး|မှု' → HYP: 'ယဉ်ကျေးမှု'
137 × REF: 'နိုင်ငံ|ရေး' → HYP: 'နိုင်ငံရေး'
124 × REF: 'ဘာ|လဲ' → HYP: 'ဘာလဲ'
111 × REF: 'စ|၍' → HYP: 'စ၍'
110 × REF: 'တစ်|လုံး' → HYP: 'တစ်လုံး'
107 × REF: 'ပါ|ဦး' → HYP: 'ပါဦး'
104 × REF: 'တစ်|ပတ်' → HYP: 'တစ်ပတ်'
103 × REF: 'မ|တွေ့' → HYP: 'မတွေ့'
Most Frequent Complex Boundary Errors:
350 × REF: 'ပေါ်' → HYP: 'ပေါ်မှာ'
230 × REF: 'ဖြစ်' → HYP: 'သည်'
218 × REF: 'သည်' → HYP: 'သည်မှာ'
192 × REF: 'ဟုတ်' → HYP: 'ဟုတ်တယ်'
188 × REF: 'နိုင်ငံ' → HYP: 'နိုင်'
167 × REF: '၏' → HYP: 'ငံ၏'
162 × REF: 'ဦး' → HYP: 'ဦး'
150 × REF: 'ဖြစ်' → HYP: 'ဖြစ်၏'
146 × REF: 'ကြ' → HYP: 'ကြ၏'
120 × REF: 'တောင်းပန်' → HYP: 'တောင်းပန်ပါ'
MIT License - Full terms available at:
https://github.com/ye-kyaw-thu/oppaWord/blob/main/LICENSE
The dictionary combines words from multiple sources:
- myG2P dictionary (originally from Myanmar Language Commission)
- myPOS corpus
- Personal names from myRoman corpus and LU Lab's Myanmar names collection (for R&D)
- myMono monolingual corpus (not publicly released)
Usage Restrictions:
- ✅ Allowed: Myanmar language NLP/AI research and development
- ❌ Not Allowed: Commercial use without explicit permission
For those interested in oppaWord's segmentation methodology and development process:
-
Technical Introduction
- Presentation slides:
oppaWord_Intro.pdf
oppaWord_Intro.pptx - Covers: Core algorithm, visualization examples, and performance benchmarks
- Presentation slides:
-
Experimental Notebooks
Contains Jupyter notebooks demonstrating:- Different segmentation strategies
- Error analysis workflows
- Parameter tuning examples
-
Research Publications (Coming Soon)
- Planned journal paper on the hybrid segmentation approach
If you use oppaWord in your work, please cite it as follows:
(oppaWord ကို အသုံးပြုပါက အောက်ပါအတိုင်း ကိုးကားဖော်ပြပေးပါ။)
@misc{oppaWord_2025,
author = {Ye Kyaw Thu},
title = {{oppaWord: Hybrid DAG+Bi-MM+LM Myanmar Word Segmenter}},
version = {1.0},
month = {August},
year = {2025},
publisher = {GitHub},
url = {https://github.com/ye-kyaw-thu/oppaWord},
note = {Accessed: YYYY-MM-DD},
institution = {Language Understanding Lab (LU Lab), Myanmar}
}


