이 글은 Wikidocks의 딥 러닝을 이용한 자연어 치리 입문을 공부한 내용을 정리 한 글입니다.
✔️ 자연어 처리를 하다 보면 각 문장(문서)의 길이가 서로 다를 수 있는데 기계는 길이가 전부 동일한 문서들에 대하여 하나의 행렬로 보고, 한꺼번에 묶어 처리하기에 padding으로써 빈 부분을 채워준다.
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
sentences = [['barber', 'person'], ['barber', 'good', 'person'], ['barber', 'huge', 'person'], ['knew', 'secret'], ['secret', 'kept', 'huge', 'secret'], ['huge', 'secret'], ['barber', 'kept', 'word'], ['barber', 'kept', 'word'], ['barber', 'kept', 'secret'], ['keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy'], ['barber', 'went', 'huge', 'mountain']]
tokenizer = Tokenizer()
tokenizer.fit_on_texts(sentences)
encoded = tokenizer.texts_to_sequences(sentences)
print(encoded)
[[1, 5], [1, 8, 5], [1, 3, 5], [9, 2], [2, 4, 3, 2], [3, 2], [1, 4, 6], [1, 4, 6], [1, 4, 2], [7, 7, 3, 2, 10, 1, 11], [1, 12, 3, 13]]
#길이가 가장 긴 문장의 길이 추출 후 길이가 짧은 문장에 대하여 나머지 부분을 0으로 채워줌
max_len = max(len(item) for item in encoded)
for item in encoded:
while len(item) < max_len:
item.append(0)
padded_np = np.array(encoded)
padded_np
array([[ 1, 5, 0, 0, 0, 0, 0],
[ 1, 8, 5, 0, 0, 0, 0],
[ 1, 3, 5, 0, 0, 0, 0],
[ 9, 2, 0, 0, 0, 0, 0],
[ 2, 4, 3, 2, 0, 0, 0],
[ 3, 2, 0, 0, 0, 0, 0],
[ 1, 4, 6, 0, 0, 0, 0],
[ 1, 4, 6, 0, 0, 0, 0],
[ 1, 4, 2, 0, 0, 0, 0],
[ 7, 7, 3, 2, 10, 1, 11],
[ 1, 12, 3, 13, 0, 0, 0]])
⭐️ 이로써 행렬로써 처리를 할 수 있으며 0번 단어는 아무런 의미가 없는 단어이기 때문에 자연어 처리 과정에서 0번 단어를 무시하고 작업을 진행하게 된다. 숫자 0으로 패딩을 진행하는 것을 제로 패딩(zero padding)이라고 한다.
from tensorflow.keras.preprocessing.sequence import pad_sequences
encoded = tokenizer.texts_to_sequences(sentences)
padded = pad_sequences(encoded)
padded
array([[ 0, 0, 0, 0, 0, 1, 5],
[ 0, 0, 0, 0, 1, 8, 5],
[ 0, 0, 0, 0, 1, 3, 5],
[ 0, 0, 0, 0, 0, 9, 2],
[ 0, 0, 0, 2, 4, 3, 2],
[ 0, 0, 0, 0, 0, 3, 2],
[ 0, 0, 0, 0, 1, 4, 6],
[ 0, 0, 0, 0, 1, 4, 6],
[ 0, 0, 0, 0, 1, 4, 2],
[ 7, 7, 3, 2, 10, 1, 11],
[ 0, 0, 0, 1, 12, 3, 13]], dtype=int32)
이때, 넘파이 패딩과 다른 점은 앞 부분을 0으로 채워주게 되는데 padding 파라미터에 post를 주게 되면 numpy로 처리했을 때와 동일한 효과를 줄 수 있다.
padded = pad_sequences(encoded, padding = 'post')
❗️ 또한, 어느 특정 문장의 길이 하나가 특별히 크게 100정도이고 나머지 문장의 길이가 5가 안된다면 굳이 100길이로 패딩을 주지 않고 길이 제한을 주워 패딩을 할 수 있다.
padded = pad_sequences(encoded, padding = 'post', maxlen = 5)
패딩의 수를 굳이 0으로 할 필요 없이 임의로 지정하여 패딩값을 넣어 줄 수 있다.(예를 들어 지금 사용된 정수들과 겹치지 않도록, 단어 집합 크기보다 큰 수를 패딩 값으로도 사용 할 수 있다.)