Skip to main content

Lattice Path Edit Distance and romanization-aware string comparison

Project description

mòine

CI PyPI crates.io docs.rs

mòine is a Python and Rust library for romanization-aware string comparison.

It implements Lattice Path Edit Distance (LPED; 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.

With the package installed and language artifacts downloaded:

>>> import moine

>>> moine.distance("moine", "モイニャ", lang="ja")
2

>>> moine.distance("もいにゃ", "モイニャ", lang="ja")
0

>>> moine.distance("weishiji", "威士忌", lang="zh")
0

>>> moine.distance("布納哈奔", "布納哈本", lang="zh")
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.
  • Combined min(surface Damerau-Levenshtein, LPED) scorer for candidate reranking.
  • Normalized similarity / ratio helpers in 0.0..=1.0.
  • RapidFuzz-inspired APIs such as cdist and partial matching helpers.

Installation

Install the Python package:

pip install moine
uv pip install moine

Install the Rust command-line tool:

cargo install moine

The packages do not bundle dictionary data. Download the language artifacts you need explicitly:

# Default Japanese artifact: UniDic-CWJ
uv run python -m moine download ja

# Explicit Japanese sources
uv run python -m moine download ja-unidic
uv run python -m moine download ja-sudachi

# Chinese artifact: CC-CEDICT
uv run python -m moine download zh

# Same selectors are available from the Rust CLI.
moine download ja
moine download ja-unidic
moine download ja-sudachi
moine download zh

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:

import moine

print(moine.distance("もいにゃ", "モイニャ", lang="ja"))  # 0
print(moine.ratio("ピィート", "ピート", lang="ja"))  # 0.7142857142857143
print(moine.partial_ratio("ウイスキー", "ういすきーをのんでいます", lang="ja"))  # 1.0
print(moine.distance("weishiji", "威士忌", lang="zh"))  # 0

Load a dictionary explicitly when you want to control startup cost or artifact location:

import moine

dictionary = moine.load_dict(lang="ja")
moine.set_default_dictionary(dictionary)

print(moine.distance("もいにゃ", "モイニャ", lang="ja"))  # 0

Use cdist for query-by-choice matrices:

import moine

scores = moine.cdist(
    ["もいにゃ", "ぴーと", "ピィート"],
    ["モイニャ", "ピート", "ピーと", "ピィート"],
    lang="ja",
    metric="damerau_distance",
    score_cutoff=1,
)

For search or entity matching, generate candidates with your existing system and use mòine as a reading-aware reranker:

import moine

query = "moine"
candidates = ["モイニャ", "モーイン", "モアンヌ", "ストイーシャ"]

scores = moine.cdist(
    [query],
    candidates,
    lang="ja",
    metric="distance",
)[0]

ranked = sorted(zip(candidates, scores), key=lambda item: item[1])
print(ranked)
# [('モイニャ', 2), ('モーイン', 2), ('モアンヌ', 3), ('ストイーシャ', 7)]

Score interpretation is intentionally simple: distance=0 means the best reading paths are identical, combined_distance is the minimum of surface Damerau-Levenshtein and LPED, 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.

Dictionary reading expansion is bounded by controls such as max_paths, max_readings_per_segment, and longest_only. When those controls prune candidates, a score is exact for the retained reading paths but may differ from an exhaustive score over every dictionary reading. Candidate retention follows deterministic expansion order; it is not a frequency or probability ranking.

Command Line

Most users only need the public runtime commands:

moine download ja
moine download zh
moine list
moine where
moine compare --left "もいにゃ" --right "モイニャ" \
  --artifact-metadata /path/to/moine-unidic-cwj-202512/metadata.yaml
moine chinese-compare --left weishiji --right 威士忌 \
  --artifact-metadata /path/to/moine-cedict-20260520/metadata.yaml

Use moine download ja-unidic for explicit UniDic-CWJ and moine download ja-sudachi for SudachiDict-full.

The artifact bundle, verification, archive, and raw-dictionary inspection commands are maintainer-facing tools for producing and checking release assets. They are documented in docs/development.md and docs/release_process.md.

The public comparison commands can also emit lattice graphs: moine compare --romaji-lattice <PATH> --output-format <dot|svg|png> for Japanese romaji lattices, and moine chinese-compare --pinyin-lattice <PATH> --output-format <dot|svg|png> for Chinese pinyin lattices. Writing SVG or PNG graphs requires the Graphviz dot command to be available in PATH; DOT output does not require that runtime dependency. See CLI usage for rendered examples.

Documentation

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.

Benchmark

The scoring table was recorded on 2026-06-28. It reports scoring time only; dictionary loading is shown separately below.

[!IMPORTANT] RapidFuzz measures surface Levenshtein distance, so it is expected to be much faster. Treat this as a reference for mòine's dictionary-backed reading edit distance, not a same-task speed comparison.

uv run python -m moine download ja
uv run --python python3.14 --with rapidfuzz \
  python scripts/benchmark_distances.py \
  --loops 10000

This is a quick local benchmark command. The release-wheel command used for the recorded table lives in development notes.

Method mean (±std) relative
RapidFuzz Levenshtein 0.15 ± 0.01 us/call 1.00x
mòine ja distance 26.08 ± 33.82 us/call 177x

Fresh dictionary loads from the standard installed artifacts, recorded on 2026-06-28 and measured over 100 loads:

Dictionary mean (±std)
UniDic-CWJ 476.82 ms ± 14.09 ms
SudachiDict-full 2002.83 ms ± 42.17 ms
CC-CEDICT 176.68 ms ± 30.45 ms

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 current cdist API.

Reference

[!CAUTION] This project is not the official implementation by the paper author.

@inproceedings{kaji-2023-lattice,
    title = "Lattice Path Edit Distance: A {R}omanization-aware Edit Distance for Extracting Misspelling-Correction Pairs from {J}apanese Search Query Logs",
    author = "Kaji, Nobuhiro",
    editor = "Wang, Mingxuan  and
      Zitouni, Imed",
    booktitle = "Proceedings of the 2023 Conference on Empirical Methods in Natural Language Processing: Industry Track",
    month = dec,
    year = "2023",
    address = "Singapore",
    publisher = "Association for Computational Linguistics",
    url = "https://aclanthology.org/2023.emnlp-industry.24/",
    doi = "10.18653/v1/2023.emnlp-industry.24",
    pages = "233--242",
}

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moine-0.2.2.tar.gz (119.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

moine-0.2.2-cp314-cp314-win_amd64.whl (585.7 kB view details)

Uploaded CPython 3.14Windows x86-64

moine-0.2.2-cp314-cp314-manylinux_2_28_x86_64.whl (755.8 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

moine-0.2.2-cp314-cp314-macosx_11_0_arm64.whl (680.8 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

moine-0.2.2-cp313-cp313-win_amd64.whl (585.4 kB view details)

Uploaded CPython 3.13Windows x86-64

moine-0.2.2-cp313-cp313-manylinux_2_28_x86_64.whl (754.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

moine-0.2.2-cp313-cp313-macosx_11_0_arm64.whl (680.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

moine-0.2.2-cp312-cp312-win_amd64.whl (585.9 kB view details)

Uploaded CPython 3.12Windows x86-64

moine-0.2.2-cp312-cp312-manylinux_2_28_x86_64.whl (755.3 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

moine-0.2.2-cp312-cp312-macosx_11_0_arm64.whl (681.3 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

moine-0.2.2-cp311-cp311-win_amd64.whl (590.4 kB view details)

Uploaded CPython 3.11Windows x86-64

moine-0.2.2-cp311-cp311-manylinux_2_28_x86_64.whl (760.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

moine-0.2.2-cp311-cp311-macosx_11_0_arm64.whl (683.3 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file moine-0.2.2.tar.gz.

File metadata

  • Download URL: moine-0.2.2.tar.gz
  • Upload date:
  • Size: 119.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moine-0.2.2.tar.gz
Algorithm Hash digest
SHA256 4ab03a5aeb2d741450a5173d399c15144a0cb4551350f591eab3bc2591201a9a
MD5 606e40762a2c46e78152d2cf4c130ad6
BLAKE2b-256 a4350f26230ef9e6bc591fb52c5de8c54f6a2455ae0968ed8a0bba327e01b4ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2.tar.gz:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: moine-0.2.2-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 585.7 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moine-0.2.2-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 5ad8a7e966a09a49eb5604e6dfd38c9ab7875f68a3f5892fa50a247748768cc5
MD5 f1b024561e63ede954c3d4192c339d3a
BLAKE2b-256 f155274a1b1e18fc4c03eddf47c4c7acffe0e293c81ff17f711ffe325cdcadf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp314-cp314-win_amd64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4feb5e46a9c84e8b05e2bdd7f7ed2ca8d5d6477a1b8ff25f73cad724cb994955
MD5 2d8b33f2936bece74e9d8f62f3f024b4
BLAKE2b-256 007f8b0c2f0e82a31d6c6e0ff3682ff82adc38528ed6a5892c6df482258cb697

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp314-cp314-manylinux_2_28_x86_64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e2d8ff79f033b34168b665391bc70ca5627f07615d909c5a125e44a4e219db08
MD5 ffd4071a2c54424a3eba2489c7d67298
BLAKE2b-256 136d2d6cf90603a780faf682c879ac1daeed5b90bd3605e4ff3c97798f077653

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: moine-0.2.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 585.4 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moine-0.2.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 4b567b41601d04cb16f524f6181bd97258dfb8fac027d1756b940de4685a6ce6
MD5 42bbc2da015b3dfd68059edc41c392a1
BLAKE2b-256 b49d9a4ad597d908fdea1f44308df9cdf77f25c74f8c1c84033835ca338df6c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp313-cp313-win_amd64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4c9172ae26d45808d7bd728eec89cb0fe8c366df611b3c7566ca657adfa23f7f
MD5 e1cb1b6b1824b80dea3f481014fffd22
BLAKE2b-256 36fcec7ad6b118e2c0cad10db3ea073dffd2ed21504ff7e275db4b332fd05e7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9f1a3092efa8a67b6622de48199b7e4a57197f1b3d2c54778d33fb6de964ff78
MD5 90fd496ef959e5b5b996881f39fa7e45
BLAKE2b-256 30b56cf552a1d32403c2fdf5d85c98abbe5a4a662f1cbf3084e1a720073e4658

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: moine-0.2.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 585.9 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moine-0.2.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 399881d0cc947d71943b315b8f1aa2392be6e3e83bfb44cad0ad6a0e5635d21b
MD5 c32a99cb2b4f87384f43b6798a0b4f5f
BLAKE2b-256 3f27e783bd9aa640aef441449dd581a9343f85e2e9bd870e99c371e22403b1e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp312-cp312-win_amd64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1c9d8d701a07e9bbf777988d8e283306f4ea96b480f54e9601252e456beb130d
MD5 fb69b4cdf088f560c43e130d7f53ee0c
BLAKE2b-256 342f8f3b0396f45d5140de164b284b59819014f86eee91345f278efd385a25f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 499f847771fea58130d13fd56b89af0325c7fef740dc5dfce41ba58e2829e0a4
MD5 09133385fae9d5788382111d5e91d662
BLAKE2b-256 7eccbe9d23bec9dca1f0b3a9c51920761b8835782d383e2302f1f2985a2b4f32

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: moine-0.2.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 590.4 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moine-0.2.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 31ed4e4ad18839e12bdb7e5d6a79db9a7f999238a1b2d3f21dcf7699b9038594
MD5 919644fc15a42fdbdc3382aa292280d1
BLAKE2b-256 63f7630c9d31ee8d61d7c54a12b673c1f00ac1be2903d71cc70bcf98e23cccb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp311-cp311-win_amd64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a97666ebd19a26a55c56485b91e93750e6f42b50e27dd623b73b75f2780d8c08
MD5 da796da1ae09aa33b92d8577324065f9
BLAKE2b-256 96535b608bc87ace77110aaf0bdd5f69a41f7216099337a2d52af5b7051d6909

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moine-0.2.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moine-0.2.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2c5558e8031650902bf7fb714bd1e85cc11efb681fe28dc2ad8a54569f8c022c
MD5 fa7468904ad84ab62e60cc0d73022b63
BLAKE2b-256 7910b856576cb7338e11033a76a09a8b01b4061c4ed05f8c3373bc41d053fa62

See more details on using hashes here.

Provenance

The following attestation bundles were made for moine-0.2.2-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on tagucci/moine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page