Mecab과 Keras를 이용한 뉴스 말뭉치 구분 모델 구현.2 (NLP)

 1. 기존 포스트 정리

1.1 국립국어원에서 내려받은 말뭉치가 Json 형태로 구성되어있어 따로 접근을 시도했다.

1.2 따로 학습을 시도하기보다는 라벨링 하나하나를 위해 데이터와 라벨링을 한번에 학습했다. 

1.3 데이터 전처리는 케라스에서 제공하는 모듈들을 이용했다.


2.데이터 전처리 

tokenizerr.fit_on_texts(topics)
topic_train = tokenizerr.texts_to_sequences(topics)

tokenizerr.fit_on_texts(newtext)
textdata_train = tokenizerr.texts_to_sequences(newtext)

fit_on_texts와 texts_to_sequences는 단어를 하나의 정수와 연결해 딥러닝에 사용될 수 있도록 해준다. 여기서는 각 말뭉치를 형태소 분석기로 분해한 본문과 주제를 하나하나의 정수와 매칭시켰고 확인 결과 약 1000개의 단어 종류를 확인할 수 있었다. 

textdata_train = pad_sequences(textdata_train, maxlen=170)
topic_train = pad_sequences(topic_train, maxlen=1)

여기서는 전체 길이를 맞춤과 동시에 빈자리를 Null 채우지 않기 위해 Padding하는 작업이다. 작업하는 방법으로는 pad_sequences를 이용하였다. maxlen는 기존의 본문을 분석한 결과 약 150~170단어 사이로 하나의 본문이 이루워져 있었고 따라서 최대 길이를 170으로 맞추어 Padding했다. 토픽(주제)은 하나의 정수로 이루어져 있었기에 1로 맞추었다.


3.모델 구현

model = Sequential()
model.add(Embedding(1000,128))
model.add(LSTM(128))
model.add(Dense(10, activation='softmax'))

일단 모델의 임베딩 레이어의 크기를 설정했다 임베딩 레이어의 크기는 위에서 분석했듯이 1000개 종류의 단어와 170개 길이의 문단이므로 1000으로 설정하고 Output은 128로 설정했다.

다음은 lstm모델링을 불러왔고 

마지막으로 출력층은 다중 확률이기 때문에 softmax함수를 이용해 총 10가지의 토픽(생활, 정치 등등)으로 분류하기위해 위와 같이 설정했다.

model.compile(optimizer='Adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
history = model.fit(textdata_train, topic_train, epochs=9, batch_size=1)

모델링의 오차는 다음과 같았다 일단. optimizer는 'Adam'을 사용했고 loss function은 다중 분류이면서 라벨링 상태가 정수 즉 

생활:1 정치:2 스포츠:3 이런 형태이기 때문에 sparse_categorical를 사용했다. 

그 후 훈련 데이터와 라벨을 넣어 모델을 돌렸다. 


4. 결과 

Epoch 9/9

100/100 [==============================] - 3s 30ms/step - loss: 0.5897 - acc: 0.7800

결과는 위와 같았다 78%정도로 모델을 구분할 수 있는 상태로 학습이 되었다고 판단할 수 있었다.


5. 보완점

이번 시도는 첫 시도여서 보완점이 많았다 하나하나 이야기 해보면 다음과 같다.

5.1 epoch 문제

첫 시도에서 데이터 값에 비해 epoch을 매우 적게 하여 정확도가 40%대가 나왔다. 다음에는 적정 수준으로 조정하는 것이 필요하다.

5.2 라벨링 문제

처음에는 loss 함수를 그냥 categorical_crossentropy로 진행했으나 오류가 나왔다 이는 본 함수가 one-hot 상태의 라벨링만 처리 할 수 있었기에 나온 에러였다. 따라서 코드를 이런 식으로 수정하면 정상 작동한다. 

topic_train=to_categorical(topic_train)
model.compile(optimizer='Adam', loss='categorical_crossentropy', metrics=['acc'])

하지만 성능에는 유의미한 차이를 보이지는 않았다.

5.3 데이터 셋 문제 

생각보다 성능이 예상한 것 만큼 나오지는 않았다 이는 부족한 데이터 셋 문제로 다음에는 더 많은 데이터를 읽어 들어오게 하도록 하겠다.


6. github

https://github.com/Gogumatang/pythonProject1.git

소스 자료이다. 데이터는 저작권과 용량 문제로 업로드 되어있지 않다. 

댓글

이 블로그의 인기 게시물

MongoDB와 VScode 이용한 드라이빙app 개발 일지 (2022.4.10)

다양한 계층 구현을 통한 오차역전파법 구현하기(2)