🎯 학습 목표
- 한글 텍스트 전처리 방법을 이해하고 실습한다.
- 토큰화, 인코딩, 임베딩 과정을 익힌다.
- 네이버 영화 리뷰 데이터를 이용해 감성 분류 모델을 학습한다.
- DNN, LSTM, BiLSTM, Attention, Transformer, BERT 계열 모델의 차이를 이해한다.
- KoBERT / KoELECTRA / KoBART 등의 한국어 사전학습 모델을 활용한다.
- 최신 LLM(대규모 언어모델)의 종류를 살펴본다.
🧩 1️⃣ 텍스트 전처리 개요
💡 한글 텍스트의 특징
- 조사, 어미, 어간 변화가 다양함
- 형태소 분석(morphological analysis) 필요
- 띄어쓰기 오류, 오탈자 등 비정형성이 높음
- 단순 띄어쓰기 기준 토큰화로는 의미 단위 구분이 어려움
🧰 2️⃣ 텍스트 전처리 기술 단계
| 단계 |
설명 |
예시 |
| 문장 세분화 |
말뭉치를 문장 단위로 나눔 |
“오늘 날씨가 좋다. 산책가자!” → [“오늘 날씨가 좋다.”, “산책가자!”] |
| 토큰화(Tokenization) |
문장을 단어/형태소 단위로 분리 |
“영화가 너무 재밌어요” → [“영화”, “너무”, “재밌어요”] |
| 정규화/오류 수정 |
불필요한 특수문자, 공백, 오탈자 제거 |
“ㅋㅋㅋ굿굿!!” → “굿굿” |
| 결측치 처리 |
NaN 데이터 제거 |
document가 없는 행 삭제 |
| 필요한 내용 분리 |
한글, 영어, 숫자 등만 남김 |
re.sub('ㄱ-ㅎㅏ-ㅣ가-힣 ', '', text) |
| 불용어 제거 |
의미 없는 단어 제거 (예: “이”, “그”, “저”) |
“이 영화는 정말 최고야” → “영화 최고야” |
| 어간/표제어 추출 |
단어의 기본형으로 변환 |
“먹었다” → “먹다” |
| POS 태깅 |
품사 분석 (명사, 동사 등) |
“사랑/Noun, 하/V, 다/Verb” |
| 청킹(Chunking) |
의미 단위 구문으로 분리 |
“아름다운 꽃이 핀다” → [“아름다운 꽃”, “핀다”] |
| NER (Named Entity Recognition) |
고유명사 식별 |
“서울시청” → 지역명 |
| 상호참조 해결 |
동일 인물/사물 식별 |
“그녀는 학생이다. 그녀는 공부를 잘한다.” → “그녀(=학생)” |
🔠 3️⃣ 토큰화 → 인코딩 → 임베딩
🪄 토큰화
- 텍스트를 단어 또는 형태소 단위로 분리
- 한글은
KoNLPy의 Okt, Mecab 등의 형태소 분석기를 사용
from konlpy.tag import Okt
okt = Okt()
tokens = okt.morphs("이 영화 정말 최고야!")
print(tokens)
# ['이', '영화', '정말', '최고', '야', '!']
🔢 인코딩 (Encoding)
예시
from tensorflow.keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer()
tokenizer.fit_on_texts(["이 영화 정말 최고야", "이 영화 별로야"])
print(tokenizer.word_index)
# {'이':1, '영화':2, '정말':3, '최고야':4, '별로야':5}
encoded = tokenizer.texts_to_sequences(["이 영화 정말 최고야"])
print(encoded)
# [[1, 2, 3, 4]]
🧭 패딩 (Padding)
from tensorflow.keras.preprocessing.sequence import pad_sequences
padded = pad_sequences(encoded, maxlen=5, padding='post')
print(padded)
# [[1, 2, 3, 4, 0]]
🧩 임베딩 (Embedding)
- 인코딩된 단어를 의미 벡터로 변환
- 학습 과정에서 단어의 의미적 관계를 학습
from tensorflow.keras.layers import Embedding
Embedding(input_dim=5000, output_dim=100, input_length=100)
| 파라미터 |
의미 |
input_dim |
단어 사전 크기 |
output_dim |
임베딩 차원 수 |
input_length |
문장 길이 (패딩된 길이) |
🎬 4️⃣ 네이버 영화 리뷰 감성 분류
📁 데이터
💻 데이터 로드 예시
import pandas as pd
train_data = pd.read_table("./data/ratings_train.txt")
test_data = pd.read_table("./data/ratings_test.txt")
print(len(train_data), len(test_data))
# 150000 50000
🔍 데이터 확인
train_data.info()
test_data.info()
train_data['label'].value_counts()
# 0 75000
# 1 75000
✅ 라벨이 균형 잡혀 있음 → 편향된 예측 우려 낮음
🧠 5️⃣ 감성분류 모델 비교
| 모델 |
특징 |
장점 |
| DNN |
입력층-은닉층-출력층 단순 구조 |
빠름, 기본 모델 |
| LSTM |
RNN의 장기 의존성 문제 해결 |
긴 문맥 학습 가능 |
| BiLSTM |
순방향 + 역방향 동시 학습 |
문장 전체 의미 파악 우수 |
| Attention |
중요한 단어에 더 큰 가중치 |
문맥 이해 향상 |
| Transformer |
Attention 기반 병렬처리 구조 |
빠르고 정확도 높음 |
| BERT |
양방향 Transformer 기반 사전학습 모델 |
문맥 이해, 분류 정확도 최고 수준 |
| KoBERT / KoELECTRA / KoBART |
한국어 특화 모델 |
한글 문법 반영, 성능 우수 |
🧩 6️⃣ 대규모 언어모델 (LLM)
| 모델 |
특징 |
| GPT 시리즈 (OpenAI) |
텍스트 생성, 요약, 번역, 질의응답 등 범용 |
| LLaMA (Meta) |
경량화된 오픈소스 LLM |
| Claude (Anthropic) |
대화 안정성과 윤리 중심 |
| Gemini (Google) |
검색 기반 대형 언어모델 |
| Mistral / Mixtral |
효율적 멀티 전문가 모델 (Mixture of Experts) |
📊 7️⃣ 시각화 예시 — 라벨 분포 확인
import matplotlib.pyplot as plt
train_data['label'].value_counts().plot(kind='bar', color=['tomato','skyblue'])
plt.title('감성 레이블 분포 (0=부정, 1=긍정)')
plt.xlabel('감성')
plt.ylabel('리뷰 개수')
plt.show()
📈 8️⃣ 판다스로 변환 및 정렬 예시
import pandas as pd
# 예측 결과 예시
pred = [[0.9, 0.1]] # 긍정 0.9, 부정 0.1
class_names = ['긍정', '부정']
pred_df = pd.DataFrame(pred, columns=class_names)
sorted_pred = pred_df.T.sort_values(by=0, ascending=False)
display(sorted_pred)
| 출력 예시 |
확률 |
| 긍정 |
0.9000 |
| 부정 |
0.1000 |
📘 정리 요약
| 단계 |
핵심 내용 |
| 토큰화 |
텍스트를 단어 단위로 분리 |
| 인코딩 |
토큰을 숫자 인덱스로 변환 |
| 패딩 |
입력 길이를 동일하게 맞춤 |
| 임베딩 |
단어를 의미 벡터로 변환 |
| 모델링 |
DNN → LSTM → BERT 등 |
| LLM |
한국어 및 다국어 지원 대형 언어모델 활용 |
✨ 한 줄 요약
한글 텍스트 전처리는 형태소 분석 기반의 정제 과정이며, 임베딩 → RNN/LSTM → Transformer/BERT로 발전하며 한국어 감성 분석, 문장 분류, 요약 등에 핵심적으로 사용된다.