komoran

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

komoran-go

shin285/KOMORAN 3.3.7 한국어 형태소 분석기의 순수 Go 포팅. cgo, JVM, 외부 프로세스 없이 동작한다.

원본 FULL 모델 파일을 그대로 로드하고(go:embed 내장, ~4.2MB) 분석 알고리즘을 재현하므로, 같은 입력에 대해 JVM KOMORAN 3.3.7과 동일한 토큰열을 반환한다. koalanlp-kmr 2.1.4가 감싸는 것과 같은 버전이라, koalanlp 기반 JVM 서비스가 색인한 코퍼스를 Go 서비스가 같은 토크나이즈 규칙으로 이어받을 수 있다.

import komoran "github.com/MyoungHaSong/komoran-go"

kom, err := komoran.Default() // 내장 FULL 모델, 최초 1회 로딩(~1초)
kom.Tokenize("감기는 자주 걸리는 병이다")
// → [감기 는 자주 걸리 는 병 이 다]

// 사용자 사전: 기동 시 고정 또는 요청 단위(전역 상태 변경 없음)
kom.SetUserDictEntries([]string{"코모란\tNNP"})
kom.TokenizeWith([]string{"신조어"}, "신조어를 넣었다")

출력 동일성

동률 점수의 타이브레이크까지 Java와 같아야 해서 다음을 맞췄다:

  • 문자열을 UTF-16 코드 유닛([]uint16)으로 처리 (Java String과 인덱스 1:1)
  • 트라이 검색 결과의 격자 삽입 순서 = Java HashMap.keySet() 순서 (javamap.go)
  • 점수 덧셈 순서 동일 → float64 비트 단위 일치
  • 짝 없는 서로게이트는 Java UTF-8 인코딩과 같이 ? 치환

검증: JVM KOMORAN 3.3.7(jitpack jar) 출력과의 골든 대조 (testdata/golden_*.txt, 약 14,700문장 — 일반/산문/엣지/퍼즈/사용자사전)

  • 네이티브 퍼저 + -race. 성능은 문장당 ~160µs (Apple M3 Max 단일 코어).

주의: koalanlp가 쓰는 3.3.7은 KOMORAN GitHub HEAD와 알고리즘이 다르다 (HEAD에는 결합규칙 체커가 추가되고 불규칙 처리 경로가 바뀜). 코드 대조는 반드시 3.3.7 태그 기준으로 할 것. 3.3.7↔3.3.9는 코드가 사실상 같지만 모델 파일 4종이 모두 다르다(pos.table ID 배치까지).

의도적으로 Java와 다른 부분 (Java 쪽이 죽거나 비결정적인 지점만):

  • 관측 트라이에 없는 불규칙 토큰을 Java는 NPE로 죽지만 Go는 건너뛴다
  • irregularExtends의 HashSet 순회는 Java에서 identity hash라 실행마다 다를 수 있는 지점 — 결정적 삽입 순서 사용
  • 사용자 사전의 알 수 없는 품사 라인은 전체 중단 대신 해당 라인만 스킵

구조

파일 내용
javaser.go 모델 파일용 Java Object Serialization 리더 (GZIP + ObjectOutputStream 서브셋)
model.go pos.table / transition / observation / irregular 로딩
trie.go 아호코라식 트라이 (shineware aho-corasick 1.1.0 대응)
javamap.go Java HashMap 순회 순서 시뮬레이션
unitparser.go 완성형 ↔ 호환 자모 분해/조합
lattice.go 격자 + 최대 전이 탐색 + 불규칙 삽입
komoran.go 분석 파이프라인, 심볼/연속기호/사용자 사전
models/ KOMORAN 3.3.7 FULL 모델 (go:embed)

골든 재생성

JVM 쪽 jar(jitpack): com.github.shin285:KOMORAN:3.3.7, com.github.shineware:commons:1.0.1, com.github.shineware:aho-corasick:1.1.0

골든 포맷은 라인당 <입력> U+0002 <morph> U+0001 <morph> U+0001 ...이며, 생성 코드 요지:

Komoran komoran = new Komoran(DEFAULT_MODEL.FULL);
// komoran.setUserDic(path);  // 사용자 사전 골든일 때
List<Token> tokens = komoran.analyze(line.trim()).getTokenList();
// 각 Token.getMorph()를 U+0001로 이어 붙인다.

라이선스

Apache License 2.0. KOMORAN 알고리즘과 models/의 모델 파일은 Copyright 2015 Shineware (https://github.com/shin285/KOMORAN)의 파생물이다.

Documentation

Overview

Java Object Serialization 스트림 리더 — KOMORAN 모델 파일이 쓰는 서브셋만 지원. 트라이 구조는 블록데이터(writeChar/writeInt), 노드 값은 TC_OBJECT 그래프로 인코딩되어 있다 (AhoCorasickNode.save 참고).

Komoran 분석기 포팅 (KOMORAN 3.3.7 core.Komoran). Tokenize는 Scala NLPManager.tokenizer(= analyze(trim).getTokenList의 morph 나열)와 동일한 출력을 낸다.

Lattice 포팅 (KOMORAN 3.3.7 core.model.Lattice). analyze는 항상 nbest=1이라 n-best 분기는 구현하지 않았다.

KOMORAN 모델 파일 로딩 (pos.table, transition.model, observation.model, irregular.model).

AhoCorasickDictionary 포팅 (shineware aho-corasick 1.1.0).

KoreanUnitParser 포팅. Java String과 인덱스가 1:1이 되도록 문자열을 UTF-16 코드 유닛([]uint16)으로 다룬다 — BMP 밖 문자도 Java처럼 서로게이트 쌍 2유닛으로 처리된다.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type IrrToken

type IrrToken struct {
	Morph []uint16
	PosID int32
}

IrrToken은 불규칙 노드의 구성 형태소다 (자소열 + 품사 ID).

type IrregularNode

type IrregularNode struct {
	FirstPosID int32
	Tokens     []IrrToken
}

type Komoran

type Komoran struct {
	// contains filtered or unexported fields
}

Komoran은 형태소 분석기다. 분석은 불변 리소스만 읽어 동시 사용이 안전하고, 사용자 사전 교체는 락으로 보호된다.

func Default

func Default() (*Komoran, error)

Default는 내장 모델로 초기화된 공유 인스턴스를 반환한다 (로딩은 1회 ~1초).

func New

func New(modelFS fs.FS, modelDir string) (*Komoran, error)

New는 modelFS/modelDir에서 KOMORAN FULL 모델을 로드한다.

func (*Komoran) SetUserDictEntries

func (k *Komoran) SetUserDictEntries(entries []string)

SetUserDictEntries는 기동 시점 사용자 사전을 교체한다.

func (*Komoran) Tokenize

func (k *Komoran) Tokenize(s string) []string

Tokenize는 형태소 표층형 토큰 나열을 반환한다 (기동 시 로드된 사용자 사전 사용).

func (*Komoran) TokenizeWith

func (k *Komoran) TokenizeWith(userDict []string, s string) []string

TokenizeWith는 요청 사전으로 기동 사전을 대체해 토크나이즈한다. 전역 상태를 바꾸지 않으므로 동시 요청 간 사전이 섞이지 않는다.

type ScoredTag

type ScoredTag struct {
	Tag   string
	TagID int32
	Score float64
}

type Tokenizer

type Tokenizer struct {
	// contains filtered or unexported fields
}

Tokenizer는 Tokenize(string) []string 형태의 토크나이저 어댑터다.

func NewTokenizer

func NewTokenizer(userDictPath string) (*Tokenizer, error)

NewTokenizer는 내장 FULL 모델로 토크나이저를 만든다. userDictPath 파일이 있으면 사용자 사전으로 로드하고, 없으면 스킵한다(Scala NLPManager와 동일). 파일이 존재하는데 읽지 못하면 잘못된 토크나이징으로 기동하지 않도록 실패한다.

func (*Tokenizer) Tokenize

func (t *Tokenizer) Tokenize(s string) []string

func (*Tokenizer) TokenizeWith

func (t *Tokenizer) TokenizeWith(userDict []string, s string) []string

TokenizeWith는 요청 단위 사용자 사전으로 토크나이즈한다. NLPManager.updateUserDict와 동일하게 항목의 단어 부분만 쓰고 NNP로 태깅하되, 전역 상태는 바꾸지 않는다.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL