Metadata-Version: 2.4
Name: madipy
Version: 0.1.1
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Natural Language :: Korean
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Topic :: Text Processing :: Linguistic
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Summary: madi(마디): 순수 Rust 한국어 형태소 분석기
Keywords: korean,morphological analyzer,nlp,형태소 분석
License: MIT OR Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://p14jeffwest.github.io/madi-release/
Project-URL: Repository, https://github.com/p14jeffwest/madi-release

# madipy — madi (마디)

순수 Rust 로 만든 한국어 형태소 분석기의 Python 패키지입니다. 세종 품사 태그(NNG, VV, EF …)로 형태소를 나누고, 형태소 분석을 이용한 문장 분리도 합니다.

A Korean morphological analyzer written in pure Rust, with Python bindings (Sejong tag set, morpheme-aware sentence splitting).

## 설치

```
pip install madipy
```

설치 이름은 `madipy`, 코드에서는 `import madi` 입니다.

Windows·macOS(Intel·Apple Silicon)·Linux(x86_64·aarch64), Python 3.9 이상. 모델 파일은 패키지에 들어 있지 않고, 처음 쓸 때 한 번 받아 둡니다(기본 약 87 MB, 풀면 240 MB).

## 사용

```python
import madi

m = madi.Analyzer()                         # 처음 한 번 모델을 받는다
m.tokenize('아버지가 방에 들어가신다')
# [('아버지', 'NNG', 0, 3), ('가', 'JKS', 3, 4), ('방', 'NNG', 5, 6), ('에', 'JKB', 6, 7),
#  ('들어가', 'VV', 8, 11), ('시', 'EP', 11, 13), ('ㄴ다', 'EF', 11, 13)]
m.pos('감기는 무서운 병이다.')                  # [('감기', 'NNG'), ('는', 'JX'), ('무섭', 'VA'), …]
m.split_sentences('오늘 날씨가 참 좋네요 내일은 비가 온대요')
# ['오늘 날씨가 참 좋네요', '내일은 비가 온대요']
m.tokenize_batch(['문장 하나', '문장 둘'], threads=4)
```

- `madi.Analyzer(precise=True)` — 정밀 모드: 애매한 어절만 작은 신경망으로 다시 고릅니다(모델 +27 MB, 느림).
- `madi.Analyzer(nlm=False)` — 신경망 LM 없이 n-gram 만(빠르고 메모리가 작음).
- `madi.Analyzer(std_2025=True)` — 2025년판 형태 분석 지침식 출력.
- `madi.Analyzer(user=['my_dict.tsv'])` — 사용자 사전.
- `tokenize` 의 시작·끝은 입력 문자열의 글자 위치입니다(`text[start:end]`). 활용형이 축약된 곳(신다 = 시 + ㄴ다)은 여러 형태소가 같은 구간을 가리킵니다.

## 모델 파일

- 받는 곳: [madi-release](https://github.com/p14jeffwest/madi-release) 의 Release. 받은 뒤 sha256 을 확인합니다.
- 두는 곳: Windows `%LOCALAPPDATA%\madi\models\<태그>`, 그 밖 `~/.cache/madi/models/<태그>` (환경 변수 `MADI_MODEL_DIR` 로 바꿈).
- 인터넷이 막힌 곳: Release 의 `.xz` 파일을 따로 받아 그 디렉터리를 `MADI_MODEL_URL` 로 주거나, 받은 파일 경로를 직접 줍니다 — `madi.Analyzer('madi.dict', lm='knlm.bin', nlm='model.nlm')`.

명령줄: `python -m madi download [--precise]`, `python -m madi info`, `python -m madi verify`, `python -m madi version`(패키지·모델·엔진 판본), `python -m madi "문장"`.

## Kiwi 에서 옮겨 오기 (0.1.1 기준)

| Kiwi (kiwipiepy) | madi 0.1.1 | 비고 |
|---|---|---|
| `Kiwi()` | `madi.Analyzer()` | 모델은 처음 쓸 때 받음 |
| `tokenize(text)` → `Token` 목록 | `tokenize(text)` → `(형태, 태그, 시작, 끝)` 목록 | 0.2.0 에서 `Token` 객체(튜플로도 풀림) |
| `tokenize(texts)`(여러 문장) | `tokenize_batch(texts, threads)` | 0.2.0 에서 `tokenize` 도 목록을 받음 |
| `split_into_sents(text)` | `split_sentences(text)` → 문자열 목록 | 0.2.0 에서 `split_into_sents`(위치·토큰 포함) |
| `analyze(text, top_n)` | 없음 → `tokenize`/`pos` | 0.2.0 에서 제공 |
| `add_user_word` · `load_user_dictionary` | `Analyzer(user=[파일])` | 0.2.0 에서 같은 이름으로 |
| `split_complex=True` | 없음 | 0.2.0 |
| `join(morphs)` · `blocklist` · URL·이메일 통째 처리 | 없음 | 0.3 계획 |
| `space` · `typos` | 넣지 않음 | 띄어쓰기·오타 교정은 madi 맞춤법 검사기의 기능 |
| 형태소 유사도 · 다음 형태소 예측 | 넣지 않음 | Kiwi 고유 모델이 필요한 기능 |

- 태그는 같은 세종 체계(NNG, VV, EF …)입니다. Kiwi 의 불규칙 표시(`VA-I` 등)는 madi 에 없습니다.
- 분석 관행은 국립국어원 모두의 말뭉치 지침을 따르므로 결과가 Kiwi 와 다른 곳이 있습니다(복합 명사 단위, 숫자 등).
- 없는 메서드를 부르면 쓸 수 있는 메서드를 오류 문구로 알려 줍니다.

## 성능 요약

같은 잣대(세종 태그 사상, 관행 차이 정규화)로 다른 분석기와 비교했습니다. 차이는 Kiwi CoNg(kiwipiepy 0.24.0) 대비, 괄호는 95% 구간입니다.

| | madi 기본 | madi 정밀 | Kiwi CoNg |
|---|---|---|---|
| 모두의 말뭉치 형태 분석 2025 문어(학습과 독립, 6,953문장), 형태소 F1 | **0.9774** (+0.32p [+0.24, +0.39]) | 0.9784 (+0.42p) | 0.9742 |
| 같은 셋 구어(16,439문장) | **0.9640** (+0.53p [+0.44, +0.64]) | 0.9656 (+0.69p) | 0.9586 |
| 신문 1990~2025 평가셋(420문장, 손 교정), 중립 F1 | 0.9772 (+0.35p, 유의하지 않음) | 0.9786 (+0.49p) | 0.9737 |
| Kiwi 모호성 벤치마크 kiwi510, 정확도 | 0.7471 (**열세**, p 0.0002) | 0.8137 (차이 유의하지 않음) | 0.8275 |
| 속도(랩탑 1스레드, Python 바인딩, KB/s) | 284 | 26 | 268 |

- 기본 모드는 모호성 벤치마크에서 Kiwi 보다 낮고, 정밀 모드(`precise=True`)는 같은 수준입니다. 일반 문장의 형태소 F1 은 기본 모드도 앞섭니다.
- 공개판의 기본 설정은 위 측정 설정에 전후향 가지치기(τ 11)를 더한 것입니다. 측정 셋 1만 7천 문장 중 5문장만 출력이 달라지고, 2단계 LM 질의가 44% 줄어 랩탑 CLI 에서 약 17% 빨라집니다. 같은 정도의 시간 이득은 1단계 문턱(`--prefilter 6`)으로도 얻을 수 있으며, 전후향 가지치기의 몫은 LM 질의 수를 줄이는 데 있습니다.
- 자세한 표·방법은 논문(준비 중)에 싣습니다. 평가에는 국립국어원 모두의 말뭉치를 활용하였음.

## 이용 조건

- 패키지(코드): MIT 또는 Apache-2.0.
- 모델·사전 파일은 CC BY-SA 2.0 KR. 국립국어원 모두의 말뭉치(형태 분석 말뭉치 2018~2020, 형태 분석 말뭉치 2025, 어휘 의미 분석 말뭉치 2020)와 우리말샘을 활용하였음(국립국어원 공개 승인 2026-10-17). 말뭉치 원문을 담거나 복원할 수 없는 통계·가중치임. 신문 기사 원문으로 자기 라벨 학습.
- 사전은 mecab-ko-dic(Apache-2.0) 기반. 전문·학습 입력 목록: https://github.com/p14jeffwest/madi-release (`LICENSE-MODELS.txt`, `MODEL-PROVENANCE.md`).

Code: MIT OR Apache-2.0. Downloaded model files: CC BY-SA 2.0 KR (see the release repository).

## 기본 설정

`madi.Analyzer()` 의 기본은 점수 가중 3p, 전후향 가지치기 τ 11, 정밀 모드 τ 2.0·λ 0.3 입니다(판본 문자열 `….r3p.f11…`).
이전 운영 설정은 `madi.Analyzer(score_preset='rev3', fb_cutoff=0, precise_tau=2.5, precise_lambda=0.5)`.

