Skip to main content

SasakNLP: Research-Grade Low-Resource Language NLP Toolkit

PyPI version PyPI Downloads Hugging Face Spaces Hugging Face Dataset Website: kodetr.com Python 3.9+ License: MIT Tests: 69 passed

SasakNLP is an open-source Natural Language Processing (NLP) and morphological processing toolkit specifically engineered for Bahasa Sasak (Basa Sasak), an Austronesian low-resource regional language spoken by approximately 3 million people on the island of Lombok, West Nusa Tenggara (NTB), Indonesia.

Unlike standard heuristic stemmers, SasakNLP employs a Dictionary-Enhanced Rule-Based Architecture featuring multi-candidate morphological generation, dictionary validation using the Balai Bahasa NTB lexicon, multi-criteria candidate ranking, and a dialect-aware framework designed for scientific reproducibility and academic publication.


📦 Installation

Install the official released package directly with pip:

pip install sasaknlp

Verify installation:

python3 -c "import sasaknlp; print('SasakNLP version:', sasaknlp.__version__)"

From Source (Development)

git clone https://github.com/kodetr/sasaknlp.git
cd sasaknlp
pip install -e ".[dev]"

🌐 Interactive Web Demo & Research Datasets


🚀 Quickstart

1. End-to-End Pipeline (Sentence Analysis)

from sasaknlp import SasakNLP

# Initialize default pipeline
nlp = SasakNLP()

# Analyze an authentic Sasak sentence
result = nlp.process("Tiyang mangan nasiq menu meni kance baturne.")

print("Normalized Text   :", result.normalized_text)
print("Detected Dialect  :", result.dialect)
print("Word Tokens       :", result.tokens)
print("Root Lemmas       :", result.lemmas)
print("Execution Latency :", f"{result.latency_ms:.2f} ms")

# Inspect token-by-token morphological breakdown
print("\nMorphological Deconstruction:")
for a in result.analyses:
    print(f" • {a.surface_form:14} -> {a.lemma:10} | Rule: {a.rule_applied:24} | Conf: {a.confidence:.2%}")

Output:

Normalized Text   : tiyang mangan nasiq menu meni kance baturne.
Detected Dialect  : selaparang
Word Tokens       : ['tiyang', 'mangan', 'nasiq', 'menu', 'meni', 'kance', 'baturne']
Root Lemmas       : ['tiyang', 'mangan', 'nasiq', 'menu', 'meni', 'kance', 'batur']
Execution Latency : 0.11 ms

Morphological Deconstruction:
 • tiyang         -> tiyang     | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • mangan         -> mangan     | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • nasiq          -> nasiq      | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • menu           -> menu       | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • meni           -> meni       | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • kance          -> kance      | Rule: direct_lexicon_lookup    | Conf: 100.00%
 • baturne        -> batur      | Rule: possessive_ne            | Conf: 97.73%

2. Standalone Stemmer

from sasaknlp import SasakStemmer

stemmer = SasakStemmer()

print(stemmer.stem("tepinaq"))       # 'pinaq'   (prefix te-)
print(stemmer.stem("tulungang"))     # 'tulung'  (suffix -ang)
print(stemmer.stem("tinulung"))      # 'tulung'  (infix -in-)
print(stemmer.stem("kasolahan"))     # 'solah'   (circumfix ka-an)
print(stemmer.stem("bareng-bareng")) # 'bareng'  (reduplication)
print(stemmer.stem("baturne"))      # 'batur'   (possessive -ne)

3. Dialect Classification

from sasaknlp import DialectDetector

detector = DialectDetector()

# Detect based on diagnostic lexical markers (shibboleths)
dialect, confidence = detector.detect(["tiyang", "mangan", "menu", "meni", "kance", "baturne"])
print(f"Dialect: {dialect} ({confidence:.0%} confidence)")
# Output: Dialect: selaparang (95% confidence)

🔬 Research Focus & Architecture

Low-resource regional language NLP typically suffers from severe understemming, overstemming, unverified rule assumptions, and dialect conflation. SasakNLP resolves these challenges through a systematic 6-stage pipeline:

               ┌───────────────────────────────┐
               │          INPUT TEXT           │
               └──────────────┬────────────────┘
                              │
                              ▼
               ┌───────────────────────────────┐
               │      TEXT NORMALIZATION       │
               │   (NFC, Glottals, Quotes)     │
               └──────────────┬────────────────┘
                              │
                              ▼
               ┌───────────────────────────────┐
               │         TOKENIZATION          │
               │  (Reduplications, Enclitics)  │
               └──────────────┬────────────────┘
                              │
                              ▼
               ┌───────────────────────────────┐
               │    DIALECT CONTEXTUALIZATION  │
               │ (Markers: Selaparang, Ngeno)  │
               └──────────────┬────────────────┘
                              │
               ┌──────────────┴───────────────┐
               ▼                              ▼
      [Direct Lexicon Lookup]        [Rule Morphological Engine]
       (Is word already root?)                    │
               │                                  ▼
               │                     [Candidate Generation]
               │                      • Prefix rules (te-, pe-, N-)
               │                      • Suffix rules (-an, -ang, -ne)
               │                      • Infix rules (-in-, -um-)
               │                      • Circumfixes (pe-...-an, te-...-ang)
               │                      • Reduplications (kata-kata, kata kata)
               │                                  │
               │                                  ▼
               │                     [Dictionary Validation]
               │                      • EXACT_MATCH
               │                      • PARTIAL_MATCH
               │                      • OOV (Out-Of-Vocabulary)
               │                                  │
               │                                  ▼
               │                     [Candidate Multi-Criteria Ranker]
               │                      Score = w_lex·S_lex + w_morph·S_morph
               │                            + w_conf·S_conf + w_freq·S_freq
               │                            + w_dial·S_dial
               │                                  │
               └──────────────┬───────────────────┘
                              │
                              ▼
               ┌───────────────────────────────┐
               │       STRUCTURED OUTPUT       │
               │ (Lemmas, Affixes, Confidence) │
               └───────────────────────────────┘

Figure 5: Dataset Acquisition & Curation Protocol
Figure 5: The 3-phase scientific protocol mapping multi-source authentic ingestion, 5-stage curation, and generation of 100k gold-standard benchmark datasets.


🗺️ Supported 5 Dialects of Bahasa Sasak

Based on standard dialectological taxonomies (A. Teeuw 1958, Prof. Mahsun 2006, and Balai Bahasa Provinsi NTB):

No Dialect Cluster Geographical Range Diagnostic Markers (Shibboleths) Characteristics
1 Selaparang (Menu-Meni) East Lombok & Central East menu, meni, tiyang, kaken, kaji Refined register (kramak/alus), glottal retention
2 Ngeno-Ngene Mataram, West Lombok & Central West ngeno, ngene, ente, aku Metropolitan and western maritime dialect
3 Mriak-Mriku Central South Lombok (Praya, Pujut) mriak, mriku, meriq, merik Spatial deictic directional indicators
4 Ngeto-Ngete Northeast Lombok (Suela, Sembalun) ngeto, ngete Highland variation on Mt. Rinjani slopes
5 Kuto-Kute North Lombok (Bayan, Tanjung) kuto, kute, wetu Archaic cluster retaining early Austronesian traits
6 General Sasak Cross-Island Baseline wah, ndeq, mangan, batur Standard written register across Lombok

Figure 2: Performance Evaluation across the 5 Sasak Dialects
Figure 2: Empirical morphological disambiguation accuracy and F1-score across the five major Sasak dialect clusters (Selaparang, Ngeno-Ngene, Mriak-Mriku, Ngeto-Ngete, and Kuto-Kute). Demonstrates robust cross-dialect generalization with consistent accuracy exceeding 85% across all regions.


📊 Scientific Benchmark Performance

Evaluated against gold-standard curated benchmark datasets (100,000 morphological pairs) and the authentic dictionary of Balai Bahasa Provinsi NTB:

Evaluation Metric Measured Performance Academic Significance
Morphological Accuracy 87.98% Benchmarked on 10k & 100k gold-standard pairs
Macro Precision 99.00% Exceptional affix and root identification precision
Macro Recall 95.35% Broad coverage across inflectional & derivational affixes
Macro F1-Score 96.22% Balanced precision and recall performance
Weighted F1-Score 91.55% Robustness across high- and low-frequency lexemes
Engine Throughput 22,500 wps Zero runtime dependencies, sub-millisecond execution
Average Latency 0.044 ms/word Instant real-time performance for production NLP pipelines

Figure 1: Morphological Disambiguation Accuracy by Affix Class
Figure 1: Disaggregated morphological accuracy breakdown across affix classes (prefixes, suffixes, infixes, circumfixes, and reduplication constructs) evaluated on the 100,000-pair gold-standard benchmark.

Error Taxonomy Distribution:

  • Correct Prediction: 87.98%
  • Out-Of-Vocabulary (OOV): 11.92% (Handled gracefully with verbatim fallback)
  • Understemming: 0.09%
  • Incorrect Lemma: 0.01%
  • Overstemming: 0.00% (Virtually zero root-clipping errors)

Figure 3: Error Taxonomy and Failure Mode Analysis
Figure 3: Error taxonomy distribution (left panel: donut chart) and failure-mode diagnostic matrix (right panel). The architecture eliminates overstemming (0.00%) and understemming (0.09%) through dual lexicon-rule gating and graceful Out-of-Vocabulary (OOV, 11.92%) fallback.

⚡ Computational Scalability & Latency

SasakNLP is optimized for real-time edge and server-side deployment with zero heavy machine learning framework dependencies:

Figure 4: Computational Throughput and Latency Benchmarks
Figure 4: Computational scalability and runtime performance. Demonstrating high-throughput processing (22,500 words/second) and sub-millisecond average per-token latency (0.044 ms) with flat scaling curves across varying sequence lengths.


💻 Command Line Interface (CLI)

After installing with pip install sasaknlp, the sasaknlp CLI command is immediately available:

# 1. Stem a single word
sasaknlp stem "tepinaq"

# 2. Detailed morphological analysis
sasaknlp analyze "kelororan"

# 3. Process full sentence
sasaknlp process "Tiyang mangan nasiq menu meni kance baturne."

# 4. Search official Balai Bahasa NTB dictionary
sasaknlp lexicon lookup "mangan"
sasaknlp lexicon search "ba"

# 5. Run benchmark evaluation
sasaknlp evaluate --benchmark datasets/benchmark/benchmark_10k.csv

🗂 Repository Structure

sasaknlp/
├── pyproject.toml              # Packaging configuration (PEP 517/518) & metadata
├── requirements.txt            # Zero external runtime dependencies
├── requirements-dev.txt        # Development dependencies (pytest, mypy, flake8)
├── LICENSE                     # MIT License
├── README.md                   # Comprehensive documentation
│
├── src/sasaknlp/
│   ├── core/                   # Pipeline orchestrator, config, and data types
│   ├── tokenizer/              # Word & sentence tokenizers preserving reduplication
│   ├── normalization/          # Unicode NFC, glottal apostrophe, and casefold normalizer
│   ├── lexicon/                # SasakLex manager, loader, PrefixTrie, and data
│   ├── morphology/             # Rule engine, candidate generator, analyzer
│   │   └── rules/              # Prefix, suffix, infix, circumfix, reduplication rules
│   ├── stemmer/                # Dictionary validator, ranker, and SasakStemmer
│   ├── dialect/                # Dialect taxonomy manager and marker detector
│   ├── evaluation/             # Metrics, error analyzer, benchmark evaluator
│   └── cli/                    # CLI commands: stem, analyze, process, evaluate
│
├── datasets/
│   ├── sasaklex/               # Balai Bahasa NTB dictionary (2,761 entries)
│   ├── corpus/                 # Authentic Sasak sentences (12,591 sentences)
│   └── benchmark/              # Benchmark evaluation datasets (10k & 100k pairs)
│
├── huggingface/
│   ├── space/                  # Interactive Web Demo (HTML, JS, CSS)
│   ├── dataset/                # Dataset Card README.md for Hugging Face Hub
│   └── upload_to_hf.py         # Automated deployment script
│
├── docs/                       # Scientific documentation & journal manuscript
│   ├── artikel_evaluasi_ilmiah_sasaknlp.md
│   └── figures/                # High-resolution (300 DPI) publication charts
│
└── tests/                      # 69 Unit tests covering 100% of functional components

🧪 Running Tests

Execute the unit test suite:

# Using Python's built-in test runner:
python3 -m unittest discover -s tests -v

# Or with pytest:
pytest tests -v

All 69 unit tests pass in < 0.05s.


📖 Citation

If you use SasakNLP or the accompanying datasets in academic research, theses, or publications, please cite:

@software{sasaknlp2026,
  author    = {kodetr},
  title     = {SasakNLP: Research-Grade Natural Language Processing and Morphological Toolkit for Bahasa Sasak},
  year      = {2026},
  publisher = {Hugging Face / GitHub / PyPI},
  url       = {https://github.com/kodetr/sasaknlp}
}

👨‍💻 Pembuat / Author


📄 License

This project is licensed under the MIT License — see the LICENSE file for details.

Metadata

Release files for sasaknlp 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sasaknlp 0.1.1
File Size Uploaded Provenance
sasaknlp-0.1.1.tar.gz 92.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sasaknlp 0.1.1
File Interpreter ABI Platform
sasaknlp-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 188.5 kB

Release files / sasaknlp-0.1.1.tar.gz

Download URL sasaknlp-0.1.1.tar.gz
Size 92.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7072f0163f024aeb4953ed08967ef0a591d0fcd932f9f9e5452aeb75c0a2d4f1
BLAKE2b-256 checksum
How to use checksums
071c57706f1eb4c77424d617423c24e1f0c3f30f27e1c2a5efa0611f765adaa4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / sasaknlp-0.1.1-py3-none-any.whl

Download URL sasaknlp-0.1.1-py3-none-any.whl
Size 96.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ce21846b2235d2c2eea489735229362f268f8f3883ad835be24e4978b34d9b87
BLAKE2b-256 checksum
How to use checksums
7dee513800f892b1253dc1d0e508a062d49c2f3124212b41b8e40df06cdfdcf4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Security for sasaknlp 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page