토큰화에 대해서는 자연어 처리 공모전 참가를 위해 공부해 둔 것이 있으니 참조하자.
[자연어 스터디] 02. 텍스트 전처리
We will rock you라는 문장이 있을 때, 이 문장의 단어는 We, will, rock, you 4개로 토큰화할 수 있다.We=1, will=2, rock=3, you=4로 표기하자고 약속하면 위 문장은 [1, 2, 3, 4]로 나타낼 수 있다. -> 즉 자연어를 정수 숫자로 나타낸 것이다.Bags of Words는 문서에 많이 등장하는 단어가 중요한 단어일 것이라 가정하고, 단어의 등장 빈도로 문서를 벡터화하는 방법이다.
모델에 넣을 하나의 문서에서 각 단어가 몇번 등장하는지 카운팅한다.
a, that, you, it 과 같은 단어들은 모든 문서에서 빈번하게 등장할 것이다. 그러나 이는 실제로는 별로 중요하지 않은 단어들이다. Bags of Words에서는 이를 구분할 방법이 없다.I want to change my job과 Here's your change는 다른 의미를 갖지만, 단순히 빈도수로 계산하면 같은 단어로 묶이게 된다.We will rock you를 [0, 0, 0, 1, 2, 3, 4]로 변환했다고 하자.



제공받은 한국어 데이터를 전처리 수행한 코드이다. 전처리의 방법은 무궁무진하므로 정답이 없다.
## 토큰화
from tensorflow.keras.preprocessing.text import Tokenizer
max_words = 40000
tokenizer = Tokenizer(num_words=max_words, lower=True)
# 학습 텍스트 데이터를 바탕으로 토크나이징 (띄어쓰기 기반으로 기본적인 처리)
tokenizer.fit_on_texts(x_train)
## 단어 -> 인덱스
# 텍스트 순서를 토큰화된 인덱스 순서로 변환
x_train = tokenizer.texts_to_sequences(x_train)
x_test = tokenizer.texts_to_sequences(x_test)
## Padding & Truncate
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 문장의 길이를 40으로 설정
max_length = 40
# 두괄식을 가정하여 뒷부분을 삭제
x_train = pad_sequences(x_train, maxlen=max_length, padding='pre', truncating='post')
x_test = pad_sequences(x_test, maxlen=max_length, padding='pre', truncating='post')
# 모델이 처리할 수 있도록 numpy로 변환
x_train = np.array(x_train)
x_test = np.array(x_test)
# 모델링에 필요한 라이브러리 불러오기
import tensorflow as tf
from tensorflow import keras
from keras.backend import clear_session
from keras.models import Model
from keras.layers import Input, Embedding, Dense
from keras.layers import Conv1D, MaxPool1D, Flatten
from keras.layers import LSTM, GRU, SimpleRNN, Bidirectional
# 0. 필요 변수
max_words = 40000
max_length = 40
# 1. 세션 클리어
clear_session()
# 2. 레이어 연결
# 인풋레이어
il = Input(shape=(max_length,))
# 임베딩 레이어 : 임베딩차원은 128
embedding = Embedding(input_dim=max_words,
output_dim=128,
input_length=max_length)(il)
# 학습을 위한 히든레이어 (Conv1D + Bidirectional LSTM)
hl = Conv1D(filters=64,
kernel_size=5,
strides=1,
padding='valid',
activation='swish')(embedding)
forward_LSTM = LSTM(32, return_sequences=True)
backward_LSTM = LSTM(32, return_sequences=True, go_backwards=True)
hl = Bidirectional(layer=forward_LSTM, backward_layer=backward_LSTM)(hl)
forward_GRU = GRU(32, return_sequences=True)
backward_RNN = SimpleRNN(16, return_sequences=True, go_backwards=True)
hl = Bidirectional(layer=forward_GRU, backward_layer=backward_RNN)(hl)
hl = Conv1D(filters=32,
kernel_size=5,
strides=1,
padding='valid',
activation='swish')(hl)
hl = MaxPool1D(pool_size=2)(hl)
hl = Flatten()(hl)
hl = Dense(1024, activation='swish')(hl)
# Output
ol = Dense(1, activation='sigmoid')(hl)
# 3. 모델 선언
model = Model(il, ol)
# 4. 컴파일
model.compile(loss=keras.losses.binary_crossentropy,
metrics=['accuracy'],
optimizer='adam')
# 요약
model.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 40)] 0
embedding (Embedding) (None, 40, 128) 5120000
conv1d (Conv1D) (None, 36, 64) 41024
bidirectional (Bidirectiona (None, 36, 64) 24832
l)
bidirectional_1 (Bidirectio (None, 36, 48) 10704
nal)
conv1d_1 (Conv1D) (None, 32, 32) 7712
max_pooling1d (MaxPooling1D (None, 16, 32) 0
)
flatten (Flatten) (None, 512) 0
dense (Dense) (None, 1024) 525312
dense_1 (Dense) (None, 1) 1025
=================================================================
Total params: 5,730,609
Trainable params: 5,730,609
Non-trainable params: 0
_________________________________________________________________