Note
RNN을 이용한 텍스트 생성 1 본문
728x90
첫 번째 문장 : 경마장에 있는 말이 뛰고 있다
두 번째 문장 : 그의 말이 법이다
세 번째 문장 : 가는말이 고와야 오는 말이 곱다
1. X : 경마장에 Y: 있는
2. X : 경마장에 있는 Y : 말이
3. X : 경마장에 있는 말이 Y : 뛰고
4. X : 경마장에 있는 말이 뛰고 Y : 있다
5. X : 그의 Y : 말이
6. X : 그의 말이 Y : 법이다
7. X : 가는 Y : 말이
8. X : 가는 말이 Y : 고와야
9. X : 가는 말이 고와야 Y : 오는
10. X : 가는 말이 고와야 오는 Y : 말이
11. X : 가는 말이 고와야 오는 말이 Y : 곱다
1 ~ 11번은 모델이 문맥을 학습하기 위해 문장의 앞의 단어들을 전부 고려하여 학습하도록 데이터를 재구성한 모습.
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.utils import to_categorical
text = """경마장에 있는 말이 뛰고 있다\n
그의 말이 법이다\n
가는 말이 고와야 오는 말이 곱다\n"""
tokenizer = Tokenizer()
tokenizer.fit_on_texts([text])
vocab_size = len(tokenizer.word_index) + 1 # 패딩 0을 고려하여 + 1
print('단어 집합의 크기 : %d' % vocab_size) # 출력 결과 12
print(tokenizer.word_index)
# 출력 결과
{'말이': 1, '경마장에': 2, '있는': 3, '뛰고': 4, '있다': 5, '그의': 6, '법이다': 7, '가는': 8, '고와야': 9, '오는': 10, '곱다': 11}
훈련 데이터 생성
sequences = list()
for line in text.split('\n'):
encoded = tokenizer.texts_to_sequences([line])[0]
for i in range(1, len(encoded)):
sequence = encoded[:i+1]
sequences.append(sequence)
print('학습에 사용할 샘플의 개수: %d' % len(sequences)) # 출력 결과 11
print(sequences)
# 출력 결과
[[2, 3], [2, 3, 1], [2, 3, 1, 4], [2, 3, 1, 4, 5], [6, 1], [6, 1, 7], [8, 1], [8, 1, 9], [8, 1, 9, 10], [8, 1, 9, 10, 1], [8, 1, 9, 10, 1, 11]]
[2, 3]은 [경마장에, 있는]에 해당
[2, 3, 1]은 [경마장에, 있는, 말이]에 해당
전체 훈련 데이터에 대해서 맨 우측에 있는 단어(Y)에 대해서만 레이블로 분리해야 한다.
max_len = max(len(l) for l in sequences) # 모든 샘플에서 길이가 가장 긴 샘플의 길이 출력
print('샘플의 최대 길이 : {}'.format(max_len)) # 결과 출력 6
sequences = pad_sequences(sequences, maxlen=max_len, padding='pre')
pad_sequences()는 모든 샘플에 대해서 0을 사용하여 길이를 맞춰준다.
padding의 인자로 'pre'를 주면 길이가 6보다 짧은 샘플의 앞에 0으로 채운다.
print(sequences)
# 결과 출력
[[ 0 0 0 0 2 3]
[ 0 0 0 2 3 1]
[ 0 0 2 3 1 4]
[ 0 2 3 1 4 5]
[ 0 0 0 0 6 1]
[ 0 0 0 6 1 7]
[ 0 0 0 0 8 1]
[ 0 0 0 8 1 9]
[ 0 0 8 1 9 10]
[ 0 8 1 9 10 1]
[ 8 1 9 10 1 11]]
# 맨 오른쪽 값(Y)에 대한 분리
sequences = np.array(sequences)
X = sequences[:,:-1]
y = sequences[:,-1]
print(X)
# 결과 출력
[[ 0 0 0 0 2]
[ 0 0 0 2 3]
[ 0 0 2 3 1]
[ 0 2 3 1 4]
[ 0 0 0 0 6]
[ 0 0 0 6 1]
[ 0 0 0 0 8]
[ 0 0 0 8 1]
[ 0 0 8 1 9]
[ 0 8 1 9 10]
[ 8 1 9 10 1]]
print(Y)
# 결과 출력
[ 3 1 4 5 1 7 1 9 10 1 11]
# 원-핫 인코딩
y = to_categorical(y, num_classes=vocab_size)
print(y)
# 결과 출력
[[0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.] # 3에 대한 원-핫 벡터
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # 1에 대한 원-핫 벡터
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.] # 4에 대한 원-핫 벡터
[0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.] # 5에 대한 원-핫 벡터
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # 1에 대한 원-핫 벡터
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] # 7에 대한 원-핫 벡터
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # 1에 대한 원-핫 벡터
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.] # 9에 대한 원-핫 벡터
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.] # 10에 대한 원-핫 벡터
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # 1에 대한 원-핫 벡터
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]] # 11에 대한 원-핫 벡터
'Deep Learning > NLP' 카테고리의 다른 글
한글, 영어 구분 함수 (0) | 2022.06.16 |
---|---|
RNN을 이용한 텍스트 생성 2 (0) | 2022.05.25 |
Py-Hanspell (0) | 2022.05.15 |
PyKoSpacing (0) | 2022.05.11 |
FastText (패스트텍스트) (0) | 2022.05.08 |
Comments