Python 바인딩
MeCab-Ko는 PyO3를 사용하여 Python 바인딩을 제공합니다.
설치
pip install mecab-ko
소스에서 설치:
cd python
pip install maturin
maturin develop --release
빠른 시작
from mecab_ko import Tagger
# Tagger 생성
tagger = Tagger()
# 문장 분석
result = tagger.parse("안녕하세요")
print(result)
# 노드 단위 처리
for node in tagger.parse_nodes("형태소 분석"):
print(f"{node.surface}\t{node.pos}\t{node.feature}")
API 레퍼런스
Tagger 클래스
형태소 분석기의 메인 클래스입니다.
class Tagger:
"""MeCab-Ko 형태소 분석기"""
def __init__(
self,
dict_dir: str | None = None,
user_dict: str | None = None,
output_format: str = "mecab",
space_penalty: int = -1000,
):
"""
새로운 Tagger를 생성합니다.
Args:
dict_dir: 사전 디렉토리 경로
user_dict: 사용자 사전 파일 경로
output_format: 출력 포맷 ("mecab", "wakati", "json", "csv")
space_penalty: 띄어쓰기 패널티 (기본값: -1000)
Raises:
RuntimeError: 사전을 찾을 수 없거나 초기화 실패 시
"""
...
def parse(self, text: str) -> str:
"""
텍스트를 분석하고 문자열로 반환합니다.
Args:
text: 분석할 텍스트
Returns:
분석 결과 문자열
Raises:
RuntimeError: 파싱 실패 시
"""
...
def parse_nodes(self, text: str) -> list[Node]:
"""
텍스트를 분석하고 Node 리스트로 반환합니다.
Args:
text: 분석할 텍스트
Returns:
Node 객체 리스트
Raises:
RuntimeError: 파싱 실패 시
"""
...
def parse_to_dict(self, text: str) -> dict:
"""
텍스트를 분석하고 딕셔너리로 반환합니다.
Args:
text: 분석할 텍스트
Returns:
{"text": str, "nodes": [{"surface": str, "feature": str, ...}]}
Raises:
RuntimeError: 파싱 실패 시
"""
...
def parse_nbest(self, text: str, n: int = 3) -> list[str]:
"""
N-best 결과를 반환합니다.
Args:
text: 분석할 텍스트
n: 반환할 후보 개수
Returns:
N개의 분석 결과 문자열 리스트
Raises:
RuntimeError: 파싱 실패 시
"""
...
Node 클래스
분석된 형태소 노드를 나타내는 클래스입니다.
class Node:
"""형태소 분석 노드"""
@property
def surface(self) -> str:
"""표면형 (실제 텍스트)"""
...
@property
def feature(self) -> str:
"""품사 및 의미 정보"""
...
@property
def pos(self) -> str:
"""품사 태그"""
...
@property
def start(self) -> int:
"""시작 위치 (바이트 단위)"""
...
@property
def length(self) -> int:
"""길이 (바이트 단위)"""
...
@property
def cost(self) -> int:
"""비용"""
...
@property
def base_form(self) -> str | None:
"""기본형 (원형)"""
...
@property
def reading(self) -> str | None:
"""읽기 정보"""
...
def to_dict(self) -> dict:
"""딕셔너리로 변환"""
...
사용 예제
기본 사용
from mecab_ko import Tagger
tagger = Tagger()
# 텍스트 분석
text = "아버지가방에들어가신다"
result = tagger.parse(text)
print(result)
출력:
아버지 NNG,*,F,아버지,*,*,*,*
가 JKS,*,F,가,*,*,*,*
방 NNG,*,T,방,*,*,*,*
에 JKB,*,F,에,*,*,*,*
들어가 VV,*,F,들어가,*,*,*,*
시 EP,*,F,시,*,*,*,*
ㄴ다 EF,*,F,ㄴ다,*,*,*,*
EOS
Node 단위 처리
from mecab_ko import Tagger
tagger = Tagger()
nodes = tagger.parse_nodes("형태소 분석을 시작합니다")
for node in nodes:
print(f"표면형: {node.surface}")
print(f"품사: {node.pos}")
if node.base_form:
print(f"기본형: {node.base_form}")
print("---")
사전 형식 출력
from mecab_ko import Tagger
tagger = Tagger()
result_dict = tagger.parse_to_dict("안녕하세요")
print(result_dict["text"]) # 원본 텍스트
for node in result_dict["nodes"]:
print(node["surface"], node["pos"])
사용자 사전 사용
from mecab_ko import Tagger
tagger = Tagger(user_dict="user.csv")
result = tagger.parse("딥러닝과 머신러닝")
print(result)
user.csv 파일:
딥러닝,NNG,-1000,딥러닝
머신러닝,NNG,-1000,머신러닝
Wakati 출력 (형태소만)
from mecab_ko import Tagger
tagger = Tagger(output_format="wakati")
result = tagger.parse("형태소만 추출합니다")
print(result) # "형태소 만 추출 하 ㅂ니다"
JSON 출력
from mecab_ko import Tagger
import json
tagger = Tagger(output_format="json")
result = tagger.parse("JSON 형식으로 출력")
data = json.loads(result)
print(json.dumps(data, ensure_ascii=False, indent=2))
N-best 분석
from mecab_ko import Tagger
tagger = Tagger()
candidates = tagger.parse_nbest("아버지가방에들어가신다", n=3)
for i, candidate in enumerate(candidates, 1):
print(f"=== 후보 {i} ===")
print(candidate)
대용량 파일 처리
from mecab_ko import Tagger
tagger = Tagger()
with open("large_file.txt", "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line:
result = tagger.parse(line)
# 결과 처리
print(result)
멀티프로세싱
from mecab_ko import Tagger
from multiprocessing import Pool
import os
def analyze_text(text):
# 각 프로세스마다 별도의 Tagger 생성
tagger = Tagger()
return tagger.parse(text)
if __name__ == "__main__":
texts = [
"첫 번째 문장",
"두 번째 문장",
"세 번째 문장",
]
with Pool(processes=os.cpu_count()) as pool:
results = pool.map(analyze_text, texts)
for text, result in zip(texts, results):
print(f"Input: {text}")
print(f"Result: {result}\n")
데이터프레임과 통합
import pandas as pd
from mecab_ko import Tagger
tagger = Tagger()
df = pd.DataFrame({
"text": ["첫 번째 문장", "두 번째 문장", "세 번째 문장"]
})
# 형태소 분석 결과 추가
df["morphs"] = df["text"].apply(
lambda x: [node.surface for node in tagger.parse_nodes(x)]
)
# 품사 태그 추가
df["pos_tags"] = df["text"].apply(
lambda x: [node.pos for node in tagger.parse_nodes(x)]
)
print(df)
Flask 웹 서버
from flask import Flask, request, jsonify
from mecab_ko import Tagger
app = Flask(__name__)
tagger = Tagger() # 전역으로 한 번만 생성
@app.route("/analyze", methods=["POST"])
def analyze():
data = request.get_json()
text = data.get("text", "")
if not text:
return jsonify({"error": "No text provided"}), 400
result = tagger.parse_to_dict(text)
return jsonify(result)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
사용 예:
curl -X POST http://localhost:5000/analyze \
-H "Content-Type: application/json" \
-d '{"text": "안녕하세요"}'
동사/형용사 추출
from mecab_ko import Tagger
tagger = Tagger()
text = "저는 오늘 학교에 가서 공부를 했습니다."
nodes = tagger.parse_nodes(text)
# 동사(VV, VA) 추출
verbs = [node.surface for node in nodes if node.pos in ["VV", "VA"]]
print("동사/형용사:", verbs)
# 출력: ['가', '하']
# 명사(NNG, NNP) 추출
nouns = [node.surface for node in nodes if node.pos in ["NNG", "NNP"]]
print("명사:", nouns)
# 출력: ['오늘', '학교', '공부']
타입 힌트
Python 3.9+ 에서 타입 힌트를 사용할 수 있습니다:
from mecab_ko import Tagger, Node
from typing import List, Dict, Optional
def analyze_sentences(sentences: List[str]) -> List[List[Node]]:
tagger: Tagger = Tagger()
results: List[List[Node]] = []
for sentence in sentences:
nodes: List[Node] = tagger.parse_nodes(sentence)
results.append(nodes)
return results
성능 최적화
Tagger 재사용
# Bad - 매번 생성
for text in texts:
tagger = Tagger() # 비효율적
result = tagger.parse(text)
# Good - 재사용
tagger = Tagger() # 한 번만 생성
for text in texts:
result = tagger.parse(text)
배치 처리
대용량 데이터는 배치로 처리:
def batch_analyze(texts, batch_size=1000):
tagger = Tagger()
results = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i+batch_size]
batch_results = [tagger.parse(text) for text in batch]
results.extend(batch_results)
return results
예외 처리
from mecab_ko import Tagger
tagger = Tagger()
try:
result = tagger.parse("분석할 텍스트")
print(result)
except RuntimeError as e:
print(f"분석 실패: {e}")