mòine
mòine is a Python and Rust library for romanization-aware string comparison.
It implements Lattice Path Edit Distance (Kaji, 2023), a distance metric that compares strings through possible reading paths rather than only through visible surface characters.
This is useful when romanized input and written Japanese or Chinese look far apart as strings, but stay close in reading space.
>>>
>>>
2
>>>
0
>>>
0
>>>
0
Name
The project name comes from Moine, a peated malt from Bunnahabhain and one of
the developer's favorite Scotch whiskies. In Japanese, the name has several
plausible katakana renderings, such as モイニャ, モーイン, and モアンヌ, which
makes it a fitting name for a project about readings, spelling variation, and
ambiguity in input sequences.
Features
- Japanese comparison with UniDic-CWJ-derived reading artifacts and separate SudachiDict-derived artifacts.
- Chinese comparison with CC-CEDICT-derived no-tone pinyin artifacts.
- Plain string Levenshtein-compatible distance helpers.
- Lattice-aware Damerau-Levenshtein distance for adjacent transpositions.
- Normalized similarity /
ratiohelpers in0.0..=1.0. - RapidFuzz-inspired APIs such as
cdistand partial matching helpers.
When To Use
mòine is best used after another system has produced candidates: lexical retrieval, n-gram search, BM25, embeddings, a product catalog, or an entity list. Use mòine to rescore those candidates in reading space.
| Good fit | Poor fit |
|---|---|
| Romanized, kana, kanji, or pinyin input mixed together | Same-script typo matching only |
| Query correction, search suggest, and candidate reranking | Replacing a full search engine |
| Japanese and Mandarin pinyin Chinese entity matching | Cantonese/Jyutping or arbitrary languages |
| Pipelines that can download dictionary artifacts explicitly | Install-only workflows with no data step |
| Hundreds or thousands of candidates after retrieval | Brute-force scoring over a whole corpus |
Installation
Install the Python package:
Install the Rust command-line tool:
The packages do not bundle dictionary data. Download the language artifacts you need explicitly:
# Default Japanese artifact: UniDic-CWJ
# Explicit Japanese sources
# Chinese artifact: CC-CEDICT
# Same selectors are available from the Rust CLI.
ja is the short default selector for the current Japanese artifact, which is
UniDic-CWJ. Use ja-unidic or ja-sudachi when the dictionary source should be
explicit.
Quick Start
Use the top-level Python API when you want mòine to load the default dictionary for a language:
# 0
# 0.7142857142857143
# 1.0
# 0
Load a dictionary explicitly when you want to control startup cost or artifact location:
=
# 0
Use cdist for query-by-choice matrices:
=
For search or entity matching, generate candidates with your existing system and use mòine as a reading-aware reranker:
=
=
=
=
# [('モイニャ', 2), ('モーイン', 2), ('モアンヌ', 3), ('ストイーシャ', 7)]
Score interpretation is intentionally simple: distance=0 means the best
reading paths are identical, distance metrics are smaller-is-better, ratio
and normalized_similarity are in 0.0..=1.0 and larger-is-better, and
score_cutoff filters in the RapidFuzz style.
Command Line
Most users only need the public runtime commands:
Use moine download ja-unidic for explicit UniDic-CWJ and
moine download ja-sudachi for SudachiDict-full.
The artifact bundle, verification, archive, and diagnostic commands are maintainer-facing tools for producing and checking release assets. They are documented in docs/development.md and docs/release_process.md.
Japanese comparison diagnostics can emit romaji lattice graphs with
--romaji-lattice <PATH> --output-format <dot|svg|png>. Writing SVG or PNG
graphs requires the Graphviz dot command to be available in PATH; DOT output
does not require that runtime dependency.
Documentation
- Project documentation
- Installation
- Python usage
- API reference
- Rust usage
- Dictionary artifacts
- Browser demo
- Rust docs
Developer and maintainer notes live under docs/, starting with docs/development.md and docs/release_process.md. See CONTRIBUTING.md before opening pull requests.
How It Differs From RapidFuzz
RapidFuzz is the better fit when both inputs should be compared directly as surface strings and you need a broad set of highly optimized fuzzy-matching scorers. mòine focuses on a narrower problem: comparing strings through possible reading paths before edit distance is computed.
Limitations
- mòine does not reproduce the original paper's private search-query-log evaluation.
- Dictionary-backed comparison requires separately distributed dictionary artifacts.
- UniDic matching intentionally does not use MeCab/Viterbi costs.
- Chinese support is Mandarin pinyin only; it does not model Cantonese/Jyutping or non-Mandarin readings.
processor,score_hint, NumPy dtype options, and worker parallelism are not part of the initialcdistAPI.
Reference
[!CAUTION] This project is not the official implementation by the paper author.
License
mòine source code is licensed under either MIT or Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.
Dictionary data is separate. UniDic-derived, SudachiDict-derived, and CC-CEDICT-derived artifacts carry their own license and attribution metadata, and should keep dictionary license information separate from the mòine source-code license. See THIRD_PARTY_NOTICES.md.