[NLP] 자연어처리와 친해지기 : 머신러닝과 딥러닝 모델은 코드적으로 어떻게 다를까? (feat. 네이버 영화 리뷰 데이터(nsmc) 감성 분석)
지난 두달동안 머신러닝과 딥러닝을 차례로 공부하다보니 두 기술이 동일한 테스크를 처리하는데 파이썬 코드 관점에서 어떤 차이가 있을까 궁금해졌다.
그래서 오늘 이렇게 알아본다.
오늘의 학습 목표 :
**네이버 영화 리뷰 데이터를 사용하여 머신러닝과 딥러닝 모델(분류모델)을 비교하기**
비교 항목 :
1. 데이터 전처리
2. EDA(탐색적 데이터 분석)
3. 모델 설정 및 학습
4. 성능 평가 과정
사용한 데이터셋 :
**네이버 영화 리뷰 데이터**
- ratings_train.txt
- ratings_test.txt
출처 URL : https://github.com/e9t/nsmc
사용한 모델 :
- 머신러닝 모델 : **TF-IDF + Naive Bayes**
- 딥러닝 모델 : **LSTM**
비교1. 데이터 전처리 및 준비
해당 실험에서 두 모델이 같은 데이터셋을 사용하기에 데이터 전처리는 두 모델 모두 동알합니다.
먼저, 데이터는 훈련, 검증, 테스트 세 묶음으로 분할합니다. 이와 함께 결측치 제거, 중복 제거 등의 전처리를 수행합니다.
import pandas as pd
from sklearn.model_selection import train_test_split
데이터 불러오기
train_data = pd.read_csv("ratings_train.txt", sep='\t')
test_data = pd.read_csv("ratings_test.txt", sep='\t')
결측치 및 중복 제거
train_data = train_data.dropna(how='any').drop_duplicates(subset=['document'])
test_data = test_data.dropna(how='any').drop_duplicates(subset=['document'])
데이터 분할: 훈련, 검증, 테스트
train_data, val_data = train_test_split(train_data, test_size=0.2, random_state=42)
X_train, y_train = train_data['document'], train_data['label']
X_val, y_val = val_data['document'], val_data['label']
X_test, y_test = test_data['document'], test_data['label']
비교 2. EDA(탐색적 데이터 분석)
같은 데이터셋 사용하니 EDA 역시 두 모델이 다르지 않습니다.
데이터의 샘플 길이 분포를 시각화해봅니다.
import matplotlib.pyplot as plt
X_train_length = X_train.apply(lambda x: len(str(x)))
plt.hist(X_train_length, bins=50, alpha=0.75, color='blue')
plt.title("Train Data Review Length Distribution")
plt.show()
비교 3. 모델 설정 및 학습 (차이 발생 구역✨)
머신러닝과 딥러닝의 차이는 주로 데이터 처리 방식과 모델 학습 과정에서 발생합니다. 아래에 두 접근법의 차이를 정리해봅니다.
3.1. 머신러닝 모델: TF-IDF + Naive Bayes Classifier
머신러닝 모델은 "벡터화 -> 모델 학습 -> 검증 및 테스트 정확도 계산" 순으로 과정이 전개됩니다.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, f1_score
3.1.1 TF-IDF 벡터화
TF-IDF와 같은 벡터화 방법을 사용해 문서를 수치 벡터로 변환함
텍스트를 수치로 변환한 후 바로 모델에 넣을 수 있음
tfidf = TfidfVectorizer(max_features=10000)
X_train_tfidf = tfidf.fit_transform(X_train)
X_val_tfidf = tfidf.transform(X_val)
X_test_tfidf = tfidf.transform(X_test)
3.1.2 Naive Bayes 모델 학습
머신러닝 알고리즘(예: Naive Bayes, SVM 등)으로 학습함
일반적으로 훈련 속도가 빠르고 계산이 간단함
nb_model = MultinomialNB()
nb_model.fit(X_train_tfidf, y_train)
3.1.3 검증 및 테스트 정확도 계산
학습된 모델로 검증과 테스트 데이터를 예측하고, 정확도 및 F1 Score를 평가함
y_val_pred = nb_model.predict(X_val_tfidf)
y_test_pred = nb_model.predict(X_test_tfidf)
print("Naive Bayes Validation Accuracy:", accuracy_score(y_val, y_val_pred))
print("Naive Bayes Test F1 Score:", f1_score(y_test, y_test_pred))
3.2. 딥러닝 모델: LSTM 기반 분류기
딥러닝 모델은 "토근화 및 시퀀스변환 -> 토크나이저 설정 및 학습 -> 시퀀스 변환 및 패딩 -> 딥러닝 모델 정의 -> 모델 학습 -> 테스트 데이터 성능 평가" 순으로 과정이 전개됩니다.
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
# 3.2.1 토큰화 및 시퀀스 변환
## 텍스트 데이터를 "단어의 시퀀스(Sequence)"로 변환함
## 각 단어를 인덱스 번호로 변환해 "토큰화(Tokenization)"함
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 3.2.2 토크나이저 설정 및 학습
## 딥러닝 모델에 맞게 Tokenizer 객체를 설정함
## 텍스트를 토큰 리스트로 변환하는 학습이 포함됨
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(X_train)
# 3.2.3 시퀀스 변환 및 패딩
## 모든 시퀀스의 길이를 동일하게 패딩(Padding)함
## 3긴 시퀀스는 잘라내고, 짧은 시퀀스는 0으로 채워 넣어 입력 크기 통일함
X_train_seq = pad_sequences(tokenizer.texts_to_sequences(X_train), maxlen=100)
X_val_seq = pad_sequences(tokenizer.texts_to_sequences(X_val), maxlen=100)
X_test_seq = pad_sequences(tokenizer.texts_to_sequences(X_test), maxlen=100)
# 3.2.4 딥러닝 모델 정의
Embedding, LSTM, Dense 등의 층으로 구성된 딥러닝 모델을 정의
model = Sequential([
Embedding(input_dim=10000, output_dim=128, input_length=100),
LSTM(128, dropout=0.2, recurrent_dropout=0.2),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 3.2.5 모델 학습
## 딥러닝 모델에 데이터를 학습시킵니다. 학습에는 오랜 시간이 걸릴 수 있음
model.fit(X_train_seq, y_train, validation_data=(X_val_seq, y_val), epochs=5, batch_size=64)
# 3.2.6 테스트 데이터 성능 평가
## 학습된 모델을 사용해 테스트 데이터의 성능을 평가함
F1 Score와 정확도 등의 성능 지표를 계산함
y_test_pred_dl = (model.predict(X_test_seq) > 0.5).astype("int32")
print("LSTM Test F1 Score:", f1_score(y_test, y_test_pred_dl))
비교 4. 성능 평가 과정
# 정확도 및 F1 점수 비교
ml_accuracy = accuracy_score(y_test, y_test_pred)
dl_accuracy = accuracy_score(y_test, y_test_pred_dl)
ml_f1 = f1_score(y_test, y_test_pred)
dl_f1 = f1_score(y_test, y_test_pred_dl)
# 성능 비교 시각화
import numpy as np
metrics = ['Accuracy', 'F1 Score']
ml_scores = [ml_accuracy, ml_f1]
dl_scores = [dl_accuracy, dl_f1]
x = np.arange(len(metrics))
width = 0.35
fig, ax = plt.subplots()
bar1 = ax.bar(x - width/2, ml_scores, width, label='Machine Learning')
bar2 = ax.bar(x + width/2, dl_scores, width, label='Deep Learning')
ax.set_xlabel('Metrics')
ax.set_ylabel('Scores')
ax.set_title('Comparison of ML vs DL')
ax.set_xticks(x)
ax.set_xticklabels(metrics)
ax.legend()
plt.show()
결론
머신러닝 모델과 딥러닝 모델은
1, 2번 데이터 전처리 및 EDA 과정은 동일합니다.
그러나, 그 이후의 데이터 처리 과정과 학습 과정은 머신러닝과 딥러닝에서 차이가 큽니다.
머신러닝은, 벡터화된 수치 데이터를 바로 사용해 빠르게 학습합니다.
딥러닝은, 토큰화와 시퀀스 변환 과정을 거쳐 신경망에 입력하고, 복잡한 구조를 학습합니다.
이 차이 때문에 데이터의 크기, 복잡도, 목적에 따라 머신러닝과 딥러닝 중 적절한 접근 방식을 선택해야 합니다.
꼬리생각
Q. 데이터양이 아주 많지는 않고, 각 셀별로 max_length가 짧으면 머신러닝이 성능이 더 좋게 나올 수 있을까?
A. (데이터 특성에 따라 다르지만 대체로) 그렇다.
머신러닝과 딥러닝 중 어떤 방법이 더 나은 성능을 보일지는 데이터의 특성에 따라 다릅니다만, 데이터 양과 텍스트 길이는 중요한 요소 중 하나입니다.
- 데이터 양이 적고, 텍스트 길이가 짧은 경우: 머신러닝 추천✨
- 간단한 텍스트:
- 각 문장이 짧고 문맥 이해가 많이 필요하지 않을 경우,
딥러닝 모델의 복잡한 구조가 오히려 성능에 이점을 제공하지 못합니다.
- 머신러닝 모델(예: Naive Bayes, SVM)은 단순한 빈도 기반 학습을 하기 때문에,
짧은 텍스트에서 빠르고 효과적으로 패턴을 잡아낼 수 있습니다.
- 데이터 양이 적을 때:
- 딥러닝은 큰 데이터셋에서 제대로 학습하는 경향이 있습니다.
데이터가 적을 경우 과적합(overfitting) 위험이 커지고, 성능이 불안정해질 수 있습니다. - 반면, 머신러닝 모델은 적은 데이터에서도 충분히 성능을 발휘할 수 있습니다.
- 딥러닝은 큰 데이터셋에서 제대로 학습하는 경향이 있습니다.
- TF-IDF와 SVM/Naive Bayes 조합은 짧은 텍스트 분류에서 매우 좋은 성능을 내는 경우가 많습니다.
특히 간단한 이진 분류 문제에서는 머신러닝이 종종 더 나은 성능을 보입니다.
- 데이터가 많고, 텍스트가 길거나 문맥 파악이 중요한 경우: 딥러닝 추천✨
- 딥러닝 모델(LSTM, Transformer 등)은 시퀀스 데이터와 복잡한 문맥을 잘 처리합니다.
- 문장이 길고, 문맥 정보를 이해해야 하는 경우(예: 리뷰의 감성 분석, 대화 분석) 딥러닝 모델이 더 적합합니다.
- 임베딩(Embedding)을 사용한 딥러닝 모델은 단어의 의미를 더 잘 파악할 수 있습니다.
- 특히, 텍스트 내 다양한 단어가 같은 의미로 쓰이는 경우(동의어 문제) 딥러닝이 강점을 보입니다.
꼬리생각 결론: 언제 머신러닝이 더 나을까?
- 데이터의 양이 적거나 각 셀의 텍스트가 매우 짧고 단순할 때(예: 채팅, 짧은 리뷰)는 _머신러닝 모델_이 더 나은 선택이 될 수 있습니다.
- 반면, 텍스트가 길거나 문맥 파악이 중요한 작업에서는 _딥러닝 모델_이 더 나은 성능을 발휘할 가능성이 높습니다.