-
TensorFlow 기초 38 - 문자열(corpus - 자연어 데이터 집합) 토큰화 + LSTM으로 감성 분류TensorFlow 2022. 12. 13. 17:30
padding : 서로 다른 길이의 데이터를 가장 긴 데이터의 길이와 같게 만듦
Embedding에 입력될 단어의 수를 지정하는데 가능한 토큰 갯수는 단어 인덱스 최대값 + 1을 부여한다.
# 문자열(corpus - 자연어 데이터 집합) 토큰화 + LSTM으로 감성 분류 # 토큰(Token): text를 단어, 문장, 형태소 별로 나눌 수 있는데 이렇게 나뉜 조각들을 token이라고 한다. import numpy as np from keras.preprocessing.text import Tokenizer from keras.utils import pad_sequences docs = ['너무 재밌네요', '최고에요', '참 잘 만든 작품입니다', '추천하고 싶어요', '한 번 더 보고 싶군요', '글쎄요', '별로네요', '생각보다 너무 지루해요', '연기가 어색하더군요', '재미없어요'] labels = np.array([1,1,1,1,1,0,0,0,0,0]) token = Tokenizer() token.fit_on_texts(docs) # 정수 인코딩 print(token.word_index) # 각 단어에 대한 인덱싱 확인 x = token.texts_to_sequences(docs) # 텍스트를 정수 인덱싱하여 list로 반환 print(x) # padding : 서로 다른 길이의 데이터를 가장 긴 데이터의 길이와 같게 만듦 padded_x = pad_sequences(x, 5) print('padded_x :\n', padded_x) # model from keras.models import Sequential from keras.layers import Dense, Flatten, Embedding, LSTM word_size = len(token.word_index) + 1 # Embedding에 입력될 단어의 수를 지정. 가능한 토큰 갯수는 단어 인덱스 최대값 + 1 model = Sequential() model.add(Embedding(word_size, 8, input_length=5)) # (가능 토큰 수, 임베딩 차원, 입력 수) model.add(LSTM(32, activation='tanh')) # 자연어 처리 model.add(Flatten()) model.add(Dense(units=32, activation='relu')) model.add(Dense(units=1, activation='sigmoid')) print(model.summary()) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(padded_x, labels, epochs=20, verbose=2) print('evaluate :', model.evaluate(padded_x, labels)) print('predict :', np.where(model.predict(padded_x) > 0.5, 1, 0).ravel()) print('labels :', labels) <console> {'너무': 1, '재밌네요': 2, '최고에요': 3, '참': 4, '잘': 5, '만든': 6, '작품입니다': 7, '추천하고': 8, '싶어요': 9, '한': 10, '번': 11, '더': 12, '보고': 13, '싶군요': 14, '글쎄요': 15, '별로네요': 16, '생각보다': 17, '지루해요': 18, '연기가': 19, '어색하더군요': 20, '재미없어요': 21} [[1, 2], [3], [4, 5, 6, 7], [8, 9], [10, 11, 12, 13, 14], [15], [16], [17, 1, 18], [19, 20], [21]] padded_x : [[ 0 0 0 1 2] [ 0 0 0 0 3] [ 0 4 5 6 7] [ 0 0 0 8 9] [10 11 12 13 14] [ 0 0 0 0 15] [ 0 0 0 0 16] [ 0 0 17 1 18] [ 0 0 0 19 20] [ 0 0 0 0 21]] Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding (Embedding) (None, 5, 8) 176 lstm (LSTM) (None, 32) 5248 flatten (Flatten) (None, 32) 0 dense (Dense) (None, 32) 1056 dense_1 (Dense) (None, 1) 33 ================================================================= Total params: 6,513 Trainable params: 6,513 Non-trainable params: 0 _________________________________________________________________ None Epoch 1/20 1/1 - 1s - loss: 0.6936 - accuracy: 0.3000 - 1s/epoch - 1s/step Epoch 2/20 1/1 - 0s - loss: 0.6929 - accuracy: 0.6000 - 2ms/epoch - 2ms/step Epoch 3/20 1/1 - 0s - loss: 0.6924 - accuracy: 0.8000 - 2ms/epoch - 2ms/step Epoch 4/20 1/1 - 0s - loss: 0.6919 - accuracy: 0.8000 - 2ms/epoch - 2ms/step Epoch 5/20 1/1 - 0s - loss: 0.6915 - accuracy: 0.8000 - 1ms/epoch - 1ms/step Epoch 6/20 1/1 - 0s - loss: 0.6911 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 7/20 1/1 - 0s - loss: 0.6906 - accuracy: 0.9000 - 3ms/epoch - 3ms/step Epoch 8/20 1/1 - 0s - loss: 0.6902 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 9/20 1/1 - 0s - loss: 0.6897 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 10/20 1/1 - 0s - loss: 0.6891 - accuracy: 0.9000 - 997us/epoch - 997us/step Epoch 11/20 1/1 - 0s - loss: 0.6886 - accuracy: 0.9000 - 996us/epoch - 996us/step Epoch 12/20 1/1 - 0s - loss: 0.6879 - accuracy: 0.9000 - 997us/epoch - 997us/step Epoch 13/20 1/1 - 0s - loss: 0.6873 - accuracy: 0.9000 - 997us/epoch - 997us/step Epoch 14/20 1/1 - 0s - loss: 0.6865 - accuracy: 0.9000 - 3ms/epoch - 3ms/step Epoch 15/20 1/1 - 0s - loss: 0.6856 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 16/20 1/1 - 0s - loss: 0.6847 - accuracy: 0.9000 - 996us/epoch - 996us/step Epoch 17/20 1/1 - 0s - loss: 0.6837 - accuracy: 0.9000 - 996us/epoch - 996us/step Epoch 18/20 1/1 - 0s - loss: 0.6826 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 19/20 1/1 - 0s - loss: 0.6814 - accuracy: 0.9000 - 2ms/epoch - 2ms/step Epoch 20/20 1/1 - 0s - loss: 0.6802 - accuracy: 0.9000 - 996us/epoch - 996us/step 1/1 [==============================] - ETA: 0s - loss: 0.6788 - accuracy: 0.9000 1/1 [==============================] - 0s 271ms/step - loss: 0.6788 - accuracy: 0.9000 evaluate : [0.6788328289985657, 0.8999999761581421] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 301ms/step predict : [1 0 1 1 1 0 0 0 0 0] labels : [1 1 1 1 1 0 0 0 0 0]
텍스트를 정수 인덱싱하여 list로 반환하여 출력하였다.
# Embedding 클래스 : 문장 토큰화와 단어 토큰화를 위한 개념 이해용 소스
참고 : 케라스의 Embedding 레이어는 처음에 무작위로 초기화된 상태에서 정수로 오는 word를 정해진 크기의 벡터로 바꿔서 다음 레이어로 넘기고, 학습단계에서는 역전파되는 기울기를 바탕으로 해당 word의 임베딩 값을 조정한다. 즉 주변 문맥을 반영하지 않는다. 그럼 Dense레이어랑 같은거 아닌가 싶지만 차이점은 원핫벡터로 값을 안넣어줘도 되서 덕분에 메모리 절약할 수 있고, 케라스에서 지원하는 masking 기능을 사용할 수 있고, 꼭 문장뿐만아니라 추천 시스템 등에서 User 등을 벡터로 나타낼 때도 사용할 수 있다. 하지만 웬만하면 weights 지정 기능을 이용해서 pre-trained 된 word2vec 등을 지정해야 할 것이다.
'TensorFlow' 카테고리의 다른 글
뉴욕타임즈 뉴스 기사 중 헤드라인을 읽어 텍스트 생성 연습(LSTM) (0) 2022.12.14 TensorFlow 기초 39 - LSTM을 이용한 텍스트 생성, 문맥을 반영하여 다음 단어를 예측하기 (0) 2022.12.14 TensorFlow 기초 37 - RNN(Recurrent Neural Network) (0) 2022.12.13 TensorFlow 기초 36 - 네이버 영화 리뷰 데이터로 word2vec 객체 생성 후 특정 단에 대한 유사도 확인 (0) 2022.12.13 TensorFlow 기초 35 - naver 제공 영화 5편을 웹스크래핑 해서 평점을 읽어 영화 간 유사도 확인 (1) 2022.12.13