#5-17. 자연어 처리
단계
1. 텍스트 토큰화
2. 단어의 원-핫 인코딩
3. 단어 임베딩 (차원 줄이기)
4. 텍스트 긍정/부정 예측하기
우선 실습하면서 추가적으로 설명을 서술하겠다뤼.
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Embedding
from tensorflow.keras.utils import to_categorical
from numpy import array
docs = ["너무 재밌네요", '최고예요', "참 잘 만든 영화예요", "추천하고 싶은 영화입니다", "한번 더 보고싶네요", "글쎄요", "별로예요", "생각보다 지루해요", "연기가 어색해요", "재미없어요"]
classes = array([1,1,1,1,1,0,0,0,0,0])
|
먼저 기본적인 패키지를 불러오고, 데이터를 입력한다. 데이터의 긍부정 데이터도 클래스로 우선 입력해준다.
1. 텍스트의 토큰화
케라스의 text_to_word_sequence() 함수를 사용하면 문장을 단어 단위로 나눌 수 있다.
해당 함수에서 사용할 수 있는 기능은 다음과 같다.
token.word_counts : 각 단어의 빈도수 계산 결과
token.document_count : 문장 카운트
token.word_docs : 각 단어들이 몇개의 문장에 출현하는 지 계산
token.word_index : 각 단어에 매겨진 인덱스 값
#token
token = Tokenizer() #
token.fit_on_texts(docs)
print(token.word_index)
|
{'너무': 1, '재밌네요': 2, '최고예요': 3, '참': 4, '잘': 5, '만든': 6, '영화예요': 7, '추천하고': 8, '싶은': 9, '영화입니다': 10, '한번': 11, '더': 12, '보고싶네요': 13, '글쎄요': 14, '별로예요': 15, '생각보다': 16, '지루해요': 17, '연기가': 18, '어색해요': 19, '재미없어요': 20}
2. 단어의 원-핫 인코딩
단어가 문장 내에서 다른 단어와 어떤 관계를 갖고 있는지 알기 위해 원핫인코딩을 단어의 배열에 적용할 수 있음.
x = token.texts_to_sequences(text): txt에 있는 단어들의 인덱스 끼리 한 문장으로 묶어 주는 새로운 배열을 생성함
word_size = len(token.word_index) + 1 : 단어의 개수를 세어주되, (왜인지몰겠지만) 단어 맨 앞에 0 인덱스가 위치해야 하므로 이를 포함하여 1을 더해줌
x = to_categorical(x,num_classes = word_size) : 문장을 이루고 있는 단어로 원핫인코딩 진행
x = token.texts_to_sequences(docs)
print(x)
|
[[1, 2], [3], [4, 5, 6, 7], [8, 9, 10], [11, 12, 13], [14], [15], [16, 17], [18, 19], [20]]
문장마다 포함하고 있는 토큰(단어)의 수가 달라 배열의 형태가 상이하기 때문에 이를 패딩으로 배열의 길이를 맞춰줌
#padding
padded_x = pad_sequences(x,4)
print(padded_x)
|
[[ 0 0 1 2]
[ 0 0 0 3]
[ 4 5 6 7]
[ 0 8 9 10]
[ 0 11 12 13]
[ 0 0 0 14]
[ 0 0 0 15]
[ 0 0 16 17]
[ 0 0 18 19]
[ 0 0 0 20]]
3. 단어임베딩
패딩한 결과를 그대로 넣을 경우, 긴 문장이나 문장 수가 많을 때 공간을 너무 많이 차지하게 됨. (0으로 잔뜩 이뤄진 배열이 가득).
이를 해결 하기위해 단어 임베딩을 진행함. 단어 임베딩이란 주어진 배열을 정해진 길이로 압축하는 것으로 16 차원을 4차원으로 줄이는 것이 가능함 (어떻게 하는지는...최적의 유사도를 계산하는...오차역전파 방식을 사용한다는데 자세한건 모르겠음...)
model.add(Embedding(입력될 총 단어 수, 임베딩 이후 출력되는 벡터의 크기, input_length=단어 입력 갯수))
#embed
word_size = len(token.word_index) + 1
model = Sequential()
model.add(Embedding(word_size, 8, input_length = 4)) #word_size는 20개의 토큰+1 이며 이를 8개의 차원으로 줄일거임. input_length는 패딩과정을 완료한 이후 설정된 4개로 하면 됨
model.add(Flatten())
model.add(Dense(1, activation = 'sigmoid'))
model.summary()
|
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param # =================================================================
embedding (Embedding) (None, 4, 8) 168
flatten (Flatten) (None, 32) 0
dense (Dense) (None, 1) 33
=================================================================
Total params: 201 Trainable params: 201 Non-trainable params: 0 _________________________________________________________________
4. 텍스트 긍정/부정 예측하기
만든 모델로 이제 긍정/부정 예측해보면 됨. 우선 이번에는 예측까진 진행하지 않고 학습만 진행했음.
좀 더 구글링해보니, 이렇게 학습한 모델 -> 다른 모델들처럼 오차값/정확도 계산해서 얼마나 테스트셋을 잘 맞추는지 추후 확인할 수 있을 것 같음
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics=['accuracy'])
model.fit(padded_x, classes, epochs=20)
print("\n Accuracy : %.4f" % (model.evaluate(padded_x, classes)[1]))
|
1/1 [==============================] - 0s 161ms/step - loss: 0.6464 - accuracy: 1.0000 Accuracy : 1.0000
'👩💻LEARN : ML&Data > Book Study' 카테고리의 다른 글
[모두의 딥러닝] #5-19. GAN (0) | 2023.02.26 |
---|---|
[모두의 딥러닝]#5-18. 순환신경망 (RNN) (0) | 2023.02.24 |
[모두의 딥러닝] #5-16. 컨볼루션 신경망 (CNN) (0) | 2023.02.22 |
[모두의 딥러닝] #4-15. 실제 데이터로 만들어보는 모델 (선형회귀) (0) | 2023.02.20 |
[모두의 딥러닝] #4-14. 모델 성능 향상시키 (0) | 2023.02.20 |