파이썬 분류 코드 - paisseon bunlyu kodeu

okt.morphs의 기능 중 stem과 norm이 있는데, stem이란 다양한 형태로 표현되는 단어들을 하나로 통일하고, norm의 경우 정규화 기능을 통해 혼재된 한글 단어 표현들을 묶어줍니다.

#모듈 임포트
import sklearn.model_selection
from tensorflow.keras.preprocessing.text import Tokenizer

#시드 설정
np.random.seed(777)
#케라스 토크나이저 사용
tokenizer = tf.keras.preprocessing.text.Tokenizer(filters='')

tokenizer.fit_on_texts(toxic['token'])

#train, validation, test 데이터 분할, 7:1:2
train, val, test = np.split(toxic.sample(frac=1), [int(.6*len(toxic)), int(.8*len(toxic))])

#train 데이터 벡터 행렬화
sequences = tokenizer.texts_to_sequences(train['token'])
x_train = keras.preprocessing.sequence.pad_sequences(sequences, maxlen = maxlen)

sequences = tokenizer.texts_to_sequences(val['token'])
x_val = keras.preprocessing.sequence.pad_sequences(sequences, maxlen = maxlen)

sequences = tokenizer.texts_to_sequences(test['token'])
x_test = keras.preprocessing.sequence.pad_sequences(sequences, maxlen = maxlen)

모델 학습을 위해 데이터를 train, validation, test로 구분합니다.

단어에 임의의 숫자를 부여하고, 딥러닝 모델에 임베딩할 수 있도록 변환합니다.

x_train
파이썬 분류 코드 - paisseon bunlyu kodeu

데이터를 확인했을 때 행렬의 오른쪽 부분에 채워지는 형식으로 구성되는 것을 볼 수 있습니다.

가장 기본적인 워드 임베딩 방식입니다.

다른 사전 학습 워드 임베딩 기법은 추후에 포스팅하도록 하겠습니다.

y_train = pd.get_dummies(train['악성댓글'].apply(str)).values
y_val = pd.get_dummies(val['악성댓글'].apply(str)).values
y_test = pd.get_dummies(test['악성댓글'].apply(str)).values

분류를 할 수 있도록 출력 데이터들을 dummy 형태로 변환합니다.

#텍스트 데이터에 포함된 총 단어 수를 지정
words_count = len(tokenizer.word_counts)

#임베딩 차원 수 125
embed_dim = 125

#임베딩 입력 변수 지정
inputs = tf.keras.layers.Input(shape = (maxlen, ))
emb = tf.keras.layers.Embedding(words_count+1, embed_dim)(inputs)
emb = tf.keras.layers.Reshape((maxlen, embed_dim, 1))(emb)

#Highway Network 입력 연결
random_layer = layers.Embedding(words_count+1, embed_dim, mask_zero=True, trainable = True)
x1 = random_layer(inputs)

총 단어 수(words_count) 변수를 딥러닝 모델의 입력으로 설정한 후 reshape를 통해 행렬 차원을 재조정합니다.

highway network를 활용하기 위해 입력 변수를 reshape하지 않고 임베딩하여 random_layer의 변수로 지정합니다.

#Conv 레이어 설정
cnn1 = layers.Conv2D(activation= 'relu',filters=25, kernel_size=(1,embed_dim), strides=(1,1))(emb)
#Maxpooling
cnn1_pool = layers.MaxPool2D(strides=(1,1), pool_size=(maxlen,1))(cnn1)
#Activation Map Flatten
cnn1_pool = layers.Flatten()(cnn1_pool)

cnn2 = layers.Conv2D(activation= 'relu',filters=25, kernel_size=(2,embed_dim), strides=(1,1))(emb)
cnn2_pool = layers.MaxPool2D(strides=(1,1), pool_size=(maxlen-1,1))(cnn2)
cnn2_pool = layers.Flatten()(cnn2_pool)

cnn3 = layers.Conv2D(activation= 'relu',filters=25, kernel_size=(3,embed_dim), strides=(1,1))(emb)
cnn3_pool = layers.MaxPool2D(strides=(1,1), pool_size=(maxlen-2,1))(cnn3)
cnn3_pool = layers.Flatten()(cnn3_pool)

cnn4 = layers.Conv2D(activation= 'relu',filters=25, kernel_size=(4,embed_dim), strides=(1,1))(emb)
cnn4_pool = layers.MaxPool2D(strides=(1,1), pool_size=(maxlen-3,1))(cnn4)
cnn4_pool = layers.Flatten()(cnn4_pool)

cnn5 = layers.Conv2D(activation= 'relu',filters=25, kernel_size=(5,embed_dim), strides=(1,1))(emb)
cnn5_pool = layers.MaxPool2D(strides=(1,1), pool_size=(maxlen-4,1))(cnn5)
cnn5_pool = layers.Flatten()(cnn5_pool)

#통합
cnn_concated = layers.concatenate([cnn1_pool,cnn2_pool,cnn3_pool, cnn4_pool, cnn5_pool])

cnn1~5의 레이어는 각각 1~5 글자를 n-gram 형식으로 인식하면서 학습합니다.

각 레이어는 maxpooling 후 activation map이 flatten되는 형태로 통합(concate)됩니다.

# 1차원 형태로 global average pooling
gap = layers.GlobalAvgPool1D()(x1)

#변환 게이트 레이어
trans = layers.Dense(embed_dim, activation="sigmoid", use_bias=True)(cnn_concated)
#통과 게이트 레이어
carry = 1 - trans

#변환 게이트는 모델의 학습 결과를 예측에 활용
gap = layers.Multiply()([trans,gap])
#통과 게이트는 모델의 학습을 거치지 않고 그대로 결과 값에 반영됨
concated = layers.Multiply()([carry, cnn_concated])

#전체 레이어 통합
concated = layers.Add()([concated, gap])

#dropout
dr = layers.Dropout(0.1)(concated)

#예측 결과 값 출력
outputs = layers.Dense(2, activation="sigmoid")(dr)

하이웨이 네트워크 적용 및 모델링 통합 과정입니다.

과적합을 방지하기 위해 입력 값의 신호를 그대로 전달할 수 있는 경로를 연결하는 방식입니다.

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import os
0

모델 정의 및 epoch 최적화를 위한 adam optimizer를 사용합니다.

현재는 default 값으로 설정되어 있으나 하이퍼 파라미터를 변경 시 모델의 성능에 영향을 줄 수 있습니다.

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import os
1

여러 epoch 수행 중 가장 최고의 모델을 저장하기 위해 callback 변수를 정의합니다.

"val_loss"가 가장 낮은 지점에서 모델이 저장됩니다.

파이썬 분류 코드 - paisseon bunlyu kodeu
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import os
2

최종적으로 test 데이터의 결과를 가지고 모델의 성능을 평가했습니다.

f1 score 69% 수준으로 양호한 성능이 측정됩니다.

파이썬 분류 코드 - paisseon bunlyu kodeu
모델 성능 측정

예제의 기본 모델 구조에 하이웨이 네트워크, OOV 처리, 워드 임베딩 등의 추가 분석을 한다면 더욱 정밀한 분석이 가능할 것입니다.

하이웨이 네트워크의 경우 데이터의 양이 많지 않고 모델링이 크게 복잡하지 않기 때문에 큰 효과를 보이지는 못하는 것으로 나타납니다.

OOV 처리의 경우 외부 데이터를 사용하지 않는 경진대회 환경에서 모델의 성능을 높이기 위해 word2vec을 활용한 것으로 사전학습된 워드 임베딩 모델을 활용하면 모델의 성능을 더욱 높일 수 있습니다.