본문 바로가기
과학/딥러닝

자연어 처리3 - 텍스트를 읽고 긍정 부정 예측

by 루민즈 2023. 11. 2.

안녕하세요 

자연어 처리를 하기위해서는 먼저 문장을 단어 단위로 토큰화하고 그 토큰화 된 단어를 임베딩 해줍니다. 

해당내용은 아래 포스팅을 참고해주세요 

https://ruminz.tistory.com/287 (자연어 처리1 - 문장의 토큰화) 

https://ruminz.tistory.com/288 (자연어 처리2 - 단어의 원핫 인코딩 임베딩) 

 

텍스트를 읽고 긍정 부정을 예측하기 위해서는 앞서 토큰화랑 원핫 인코딩 임베딩을 거쳐 학습을 진행시켜주어야 됩니다. 

 

텍스트를 읽고 긍정 부정 예측하기

 

이글이 긍정인지 부정인지 예측하기 위해서는 먼저 영화 간단한 리뷰를 불러오겠습니다. 

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])

 

그리고 앞서 포스팅한 토큰화를 진행해줍니다.

 

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}
 

 

이제 토큰에 지정된 인덱스로 새로운 배열을 생성합니다. 

 

 

x = token.texts_to_sequences(docs)
print("\n리뷰 텍스트, 토큰화 결과:\n",x)

 

실행을 해보면 새로운 배열로 토큰화 결과가 출력되는걸 확인할수있습니다. 

 

리뷰 텍스트, 토큰화 결과:
 [[1, 2], [3], [4], [5, 6, 7], [8, 9, 10, 11], [12], [13], [14, 15], [16, 17], [18]]

 

각 단어가 1부터 18까지 토큰화 되었습니다. 해당 결과를 살펴보면 

[1,2] ,[3] 이런식을 나타내고 있습니다. 즉 문장별로 나누었다는걸 확인할수있는데 "재밌게 잘봤습니다." ,"최고입니다." 각각 [1,2] ,[3] 이렇게 표현했습니다. 

 

하지만 딥러닝에서는 이를 동일하게 맞춰주어야됩니다. 길이를 똑같이 맞추어 주는 작업을 패딩 과정이라고 합니다. 케라스 에서는 패딩 과정을 진행해 주기 위해 pad_sequences()함수를 제공합니다. 

 

padded_x = pad_sequences(x,4) 
print("\n패딩 결과:\n",padded_x)

 

해당 코드를 실행시켜보면 패딩 결과 4개의 토큰으로 이루어진 배열을 확인할수 있습니다. 

 

패딩 결과:
 [[ 0  0  1  2]
 [ 0  0  0  3]
 [ 0  0  0  4]
 [ 0  5  6  7]
 [ 8  9 10 11]
 [ 0  0  0 12]
 [ 0  0  0 13]
 [ 0  0 14 15]
 [ 0  0 16 17]
 [ 0  0  0 18]]

 

이제 마무리로 임베딩에 입력될 단어의 수를 지정하고 딥러닝 모델을 만들어 출력합니다. 

임베딩 함수에 필요한 3가지 파라미터는 총 몇 개의 단어 집합에서 몇개의 임베딩 결과를 사용할것인지 글기고 매번 입력될 단어 수는 몇개로 할지 정해야됩니다. 

 

먼저 총 몇 개의 인덱스가 입력되어야 하는지 정합니다. 

 

word_size = len(token.word_index) + 1

 

여기서 + 1을 해주는 이유는 전체 단어의 맨 앞에 0이 먼저 나와야 되기 때문입니다. 

 

이제 몇 개의 임베딩 결과를 사용할 것인지 정할 차례 입니다. 그다음 매번 입력될 단어수를 정합니다. 앞서 패딩 과정을 거쳐 네 개의 길이로 맞추어 주었으므로 네 개의 단어가 들어가게 설정합니다. 

 

이를 코드로 표현하면 다음과 같습니다. 

 

Embedding(word_size,8,input_length=4)

 

마지막으로 이를 활용해 모델을 만들어 줍니다. 

model = Sequential()
model.add(Embedding(word_size,8,input_length=4))
model.add(Flatten())
model.add(Dense(1,activation='sigmoid'))
model.summary()

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]))

 

긍정적인 리뷰와 부정적인 리뷰의 학습이 진행되는것을 확인할수있습니다.

728x90
반응형