자연어처리의 새로운 패러다임
과거의 한국어 자연어처리 한계를 극복하고
워드임베딩을 중심으로 한 현대적 접근법과
R에서 활용 가능한 도구들을 소개합니다
과거 웹사이트에서 흔히 볼 수 있었던 한글 깨짐 현상
한국어 문장의 형태소 분석 과정 예시
분리는 가능하지만 결합은 어려움
아버지가방에들어가신다 → 아버지가 방에 들어가신다 ✓
아버지 가방을 고쳐드렸다 → 아버지가방을 고쳐드렸다 ✗
문장 형태의 개체명 - “이상한 변호사 우영우” - “오징어게임”
- “카라마조프가의 형제들”
장점 - 정보 검색에 적합 - 구현이 간단 - 해석이 용이
단점 - 단어 순서 무시 (Bag of Words) - 의미적 유사성 파악 어려움 - 희소 벡터 (Sparse Vector)
TF-IDF 계산 과정과 벡터 표현
library(dplyr)
library(tidytext)
# 문서별 단어 빈도 계산
book_words <- documents %>%
unnest_tokens(word, text) %>%
count(document, word, sort = TRUE)
# TF-IDF 계산
book_tfidf <- book_words %>%
bind_tf_idf(word, document, n) %>%
arrange(desc(tf_idf))
단어를 고차원 벡터 공간에 매핑하는 워드임베딩
CBOW (Continuous Bag of Words) - 주변 단어로 중심 단어 예측 - 작은 데이터셋에 적합
Skip-gram - 중심 단어로 주변 단어 예측 - 큰 데이터셋에 적합
CBOW와 Skip-gram 모델의 구조 비교
library(wordVectors)
# 모델 훈련
model <- train_word2vec(
train_file = "corpus.txt",
output_file = "word2vec_model.bin",
vectors = 100, # 벡터 차원
threads = 4, # 스레드 수
window = 5, # 윈도우 크기
iter = 5 # 반복 횟수
)
# 모델 로드 및 유사 단어 검색
model <- read.binary.vectors("word2vec_model.bin")
similar_words <- nearest_to(model, model[["마케팅"]], 10)
library(text2vec)
# 어휘 생성
vocab <- create_vocabulary(iterator)
vocab <- prune_vocabulary(vocab, term_count_min = 5)
# 동시 등장 행렬 생성
vectorizer <- vocab_vectorizer(vocab)
tcm <- create_tcm(iterator, vectorizer, skip_grams_window = 5)
# GloVe 모델 훈련
glove <- GlobalVectors$new(rank = 50, x_max = 10)
wv_main <- glove$fit_transform(tcm, n_iter = 10)
wv_context <- glove$components
word_vectors <- wv_main + t(wv_context)
FastText의 서브워드 기반 임베딩 생성 과정
library(fastText)
# 모델 훈련 설정
params <- list(
command = 'skipgram',
lr = 0.05,
dim = 100,
ws = 5,
epoch = 5,
minCount = 5,
neg = 5,
wordNgrams = 2,
loss = 'ns',
bucket = 2000000,
thread = 4,
lrUpdateRate = 100,
t = 1e-4,
verbose = 2
)
# 모델 훈련
model <- fasttext_interface(params, path_output = "fasttext_logs.txt")
BERT의 입력 표현과 아키텍처 구조
# TensorFlow 환경 설정
Sys.setenv(TF_KERAS = 1)
reticulate::use_python('/usr/bin/python3', required = TRUE)
# 필요한 패키지 로드
library(keras)
library(tensorflow)
library(reticulate)
# BERT 모델 로드 (사전 훈련된 모델)
bert_model <- load_model_hdf5("bert_model.h5")
벡터 기반 유사도 검색 시스템의 구조
cosine_similarity(A, B) = (A · B) / (|A| × |B|)
전통적 방법 - TF-IDF + 코사인 유사도 - 키워드 매칭 중심 - 표면적 유사성
임베딩 기반 - 의미적 유사성 - 문맥 고려 - 더 정확한 그룹화
지도학습 분류와 비지도학습 클러스터링의 차이
패키지 | 기능 | 특징 |
---|---|---|
wordVectors |
Word2Vec | 간단한 인터페이스 |
text2vec |
GloVe, LSA | 고성능, 메모리 효율 |
fastText |
FastText | 서브워드 지원 |
keras /tensorflow |
BERT, GPT | 딥러닝 모델 |
tidytext |
텍스트 마이닝 | tidyverse 연동 |
library(wordVectors)
library(dplyr)
# 한국어 텍스트 데이터 로드
korean_text <- readLines("korean_corpus.txt", encoding = "UTF-8")
# 전처리
clean_text <- korean_text %>%
# 특수문자 제거
gsub("[^가-힣a-zA-Z0-9\\s]", "", .) %>%
# 다중 공백 제거
gsub("\\s+", " ", .) %>%
# 앞뒤 공백 제거
trimws()
# 파일로 저장
writeLines(clean_text, "preprocessed_corpus.txt")
# 모델 훈련
model <- train_word2vec(
train_file = "preprocessed_corpus.txt",
output_file = "korean_word2vec.bin",
vectors = 200, # 임베딩 차원
threads = 4, # 병렬 처리
window = 5, # 윈도우 크기
iter = 5, # 반복 횟수
min_count = 10, # 최소 빈도
cbow = 0 # Skip-gram 사용
)
# 모델 로드
model <- read.binary.vectors("korean_word2vec.bin")
# 특정 단어와 유사한 단어들 찾기
similar_words <- nearest_to(model, model[["한국어"]], 10)
print(similar_words)
# 단어 간 유사도 계산
similarity <- cosineSimilarity(model[["컴퓨터"]], model[["기계"]])
print(paste("유사도:", similarity))
# 단어 벡터 시각화
library(Rtsne)
library(ggplot2)
# 주요 단어들 선택
key_words <- c("한국어", "언어", "컴퓨터", "기계", "학습", "데이터")
word_vectors <- model[key_words, ]
# t-SNE 적용
tsne_result <- Rtsne(word_vectors, dims = 2, perplexity = 3)
# 시각화
plot_data <- data.frame(
word = key_words,
x = tsne_result$Y[, 1],
y = tsne_result$Y[, 2]
)
ggplot(plot_data, aes(x = x, y = y, label = word)) +
geom_point(size = 3) +
geom_text(hjust = 0, vjust = 0, size = 4) +
theme_minimal() +
labs(title = "한국어 단어 임베딩 시각화")
library(RcppMeCab)
# 형태소 분석 후 임베딩
morphs <- pos(text, format = "data.frame")
noun_text <- morphs %>%
filter(pos %in% c("NNG", "NNP")) %>%
pull(token) %>%
paste(collapse = " ")
reticulate
패키지 활용감사합니다!
더 궁금한 점이 있으시면
언제든지 질문해 주세요