"매 stem = word 의 morphological root, 매 prefix/suffix 제거". Porter (1980) → Snowball → Lancaster 의 evolution. 2026 LLM era 에선 매 BPE/SentencePiece tokenizer 가 자연스럽게 흡수 — stemming explicit 사용 매 classical IR/sparse search 만.
매 핵심
매 stem vs lemma
Stem: 매 surface-level chop ("running" → "run", "studies" → "studi"). Heuristic, 매 invalid word OK.
Lemma: 매 dictionary form ("ran" → "run", "better" → "good"). POS-aware, 매 valid word.
Tokenization (BPE/WordPiece/SentencePiece): 매 LLM era 의 default — sub-word 의 학습된 segmentation.
매 algorithms
Porter Stemmer (1980, Martin Porter): 매 5-step rule cascade — English 의 de-facto.
Snowball / Porter2 (2002): 매 multi-language framework — Porter 의 cleaner re-design.
Lancaster (Paice/Husk): 매 aggressive — 매 over-stemming 위험.
Lovins (1968): 매 first published, 매 longest-match 의 single pass.
Korean (Hannanum/Mecab/Khaiii): 매 morphological analyzer — 매 stemming 보다 morpheme segmentation 이 적합.
매 응용
Classical IR / BM25: Elasticsearch / OpenSearch analyzer chain — 매 Snowball default.
Domain search 의 keyword expansion: 매 e-commerce, legal, medical.
💻 패턴
Porter / Snowball (NLTK)
fromnltk.stemimportPorterStemmer,SnowballStemmerporter=PorterStemmer()snow=SnowballStemmer("english")words=["running","ran","runs","studies","studying","easily","fairly"]forwinwords:print(w,"->",porter.stem(w),"/",snow.stem(w))# running -> run / run# studies -> studi / studi# easily -> easili / easili (heuristic, not a real word)
Lemmatization (spaCy, POS-aware)
importspacynlp=spacy.load("en_core_web_lg")# 2026: spacy 4.xdoc=nlp("The runners ran more easily than the studies suggested.")fortokindoc:print(tok.text,tok.lemma_,tok.pos_)# runners runner NOUN# ran run VERB# easily easily ADV# studies study NOUN
fromrank_bm25importBM25Okapifromnltk.stemimportSnowballStemmerimportrestem=SnowballStemmer("english").stemdeftokenize(text):return[stem(t)fortinre.findall(r"\w+",text.lower())]corpus=["The cat is running","Cats run fast","Dogs bark loudly"]tokenized=[tokenize(d)fordincorpus]bm25=BM25Okapi(tokenized)query=tokenize("running cats")print(bm25.get_scores(query))# Cat/cats + run/running stems collapse → relevant docs score higher
Modern hybrid: BPE token (LLM-era default)
fromtransformersimportAutoTokenizertok=AutoTokenizer.from_pretrained("meta-llama/Llama-3.3-70B-Instruct")print(tok.tokenize("running runners studies"))# ['Ġrunning', 'Ġrunners', 'Ġstudies'] — 매 sub-word, 매 stemming 의 implicit# 매 LLM 은 매 surface form 의 학습 — explicit stemming 의 X 필요.
Over-stemming detection
fromnltk.stemimportLancasterStemmerlan=LancasterStemmer()# 매 Lancaster aggressive 의 exampleprint(lan.stem("organization"))# 'org' — 매 too aggressiveprint(lan.stem("organic"))# 'org' — 매 false conflation# 매 Snowball preferred over Lancaster 의 production.
매 결정 기준
상황
Approach
매 LLM-based search (dense / RAG)
매 stemming X — embedding 이 흡수
BM25 / lexical search
Snowball stemmer 기본
Topic modeling / 매 sparse features
Snowball + 매 stopword
매 한국어 / 일본어 / 중국어
매 morphological analyzer (Mecab, Khaiii)
Aggressive 의 conflation 필요
Lancaster — 매 over-stem 주의
기본값: 매 Snowball (English/multi-lang) + spaCy lemmatizer (POS 가 중요한 경우). 매 dense retrieval 시 stemming X.
언제: 매 legacy IR pipeline, hybrid (sparse+dense) retrieval 의 sparse leg, domain-specific keyword expansion (legal/medical).
언제 X: 매 modern dense retrieval (E5, BGE, Voyage 3), LLM RAG — 매 BPE tokenizer 가 흡수. 매 explicit stemming 의 over-engineering.
❌ 안티패턴
Stemming dense embeddings 전: 매 embedding model 이 surface form 의 학습 — stemming 이 정보 파괴.
Lancaster 의 production: 매 over-stemming 의 false-positive 폭증.
English stemmer 매 한국어 적용: 매 nonsense 결과 — language-specific analyzer 필수.
Lemma 의 POS X: "saw" (verb→see / noun→saw) 의 ambiguity — POS tag 없이 lemmatize 의 부정확.