본문 바로가기
멋쟁이사자처럼 AIS7/오늘코드

[1214] KoNLPy와 RNN(1)

by YeonGun M 2022. 12. 14.

KoNLPy

필요성

  • 대표적인 자연어 처리 도구인 NLTK, Spacy는 한국어를 지원하지 않음

설치

=> 복잡하다!

1) 자바 설치
2) Jpype를 설치하여 파이썬과 연결
3) 최종 설치

품사 태깅 클래스 간 비교

 

=> Komoran은 자바용이라서 소속 개발자들이 울분을 토하고 있음.

 

Pecab

from pecab import PeCab
pecab = PeCab()
pecab.pos("점심 메뉴 추천 받습니다.")
>>> [('점심', 'NNG'), ('메뉴', 'NNG'), ('추천', 'NNG'), ('받', 'VV'), ('습니다', 'EF'), ('.', 'SF')]

 

Okt

  • 어간 추출(stemming, 원형 보존X)과 표제어 표기법(lemmatization, 원형 보존)

 

Tokenizer

  1. 이 클래스를 사용하면 각 텍스트를 일련의 정수(각 정수는 사전에 있는 토큰의 인덱스임) 또는 단어 수에 따라 각 토큰의 계수가 이진일 수 있는 벡터로 변환하여 텍스트 말뭉치를 벡터화할 수 있습니다.(tf-idf 기반)
  2. 흐름
tf.keras.preprocessing.text.Tokenizer(
    num_words=None,
    filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
    lower=True,
    split=' ',
    char_level=False,
    oov_token=None,
    analyzer=None,
    **kwargs
)

 

파라미터

  • num_words: 단어 빈도에 따른 사용할 단어 개수의 최대값. 가장 빈번하게 사용되는 num_words - 1개의 단어만 보존합니다.
  • filters: 문자열로, 각 성분이 텍스트에서 걸러진 문자에 해당됩니다. 디폴트 값은 모든 구두점이며, 거기에 탭과 줄 바꿈은 추가하고 ' 문자는 제외합니다.
  • lower: 불리언. 텍스트를 소문자로 변환할지 여부.
  • split: 문자열. 단어 분해 용도의 분리기.
  • char_level: 참인 경우 모든 문자가 토큰으로 처리됩니다.
  • oov_token: 값이 지정된 경우, text_to_sequence 호출 과정에서 단어색인(word_index)에 추가되어 어휘목록 외 단어를 대체합니다.

 

실습내용

corpus = ["SEOUL 서울 코로나 상생지원금 문의입니다.?",
"인천 지하철 운행시간 문의입니다.!",
"Bus 버스 운행시간 문의입니다.#"]
from tensorflow.keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer(num_words=5)
tokenizer.fit_on_texts(corpus)

✅ word_index를 사용하여 key value로 이루어진 딕셔너리를 생성

word_to_index = tokenizer.word_index
word_to_index

✅ 특수문자 제거(filters 기본값)와 소문자 변환(lower=True)이 이루어진 걸 확인할 수 있음

{'문의입니다': 1,
 '운행시간': 2,
 'seoul': 3,
 '서울': 4,
 '코로나': 5,
 '상생지원금': 6,
 '인천': 7,
 '지하철': 8,
 'bus': 9,
 '버스': 10}

num_words=5 이므로 4개의 숫자만 반환

corpus_sequences = tokenizer.texts_to_sequences(corpus)
corpus_sequences
>>> [[3, 4, 1], [2, 1], [2, 1]]

num_words를 키우거나, oov_token를 지정하면 아래와 같은 결과가 나옴.

tokenizer = Tokenizer(num_words=10, oov_token='<oov>')
tokenizer.fit_on_texts(corpus)
corpus_sequences = tokenizer.texts_to_sequences(corpus)
corpus_sequences
>>> [[4, 5, 6, 7, 2], [8, 9, 3, 2], [1, 1, 3, 2]]

 

Padding

1. 필요성

import numpy as np
np.array(corpus_sequences)
<ipython-input-10-780148bae857>:2: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.array(corpus_sequences)
array([list([4, 5, 6, 7, 2]), list([8, 9, 3, 2]), list([1, 1, 3, 2])],
      dtype=object)

위의 실습에서 생성한 corpus_sequences 는 각기 다른 값을 가진다. 그러나 기계는 길이가 전부 동일한 문서를 하나의 행렬로 보며 한 번에 묶어서 처리 가능하다 즉, 병렬 연산을 위해서는 여러 문장의 길이를 동일하게 맞춰주는 방법이 필요하며 방법은 아래와 같다.

 

1️⃣ 원핫 인코딩

  •  정수 배열을 0과 1로 이루어진 벡터로 변환
  • 실수 벡터 데이터를 다룰 수 있는 층-Dense 층-을 신경망의 첫 번째 층으로 사용
  •  num_words * num_reviews 크기의 행렬이 필요하기 때문에 메모리를 많이 사용

 

2️⃣ 패딩(Padding)

  • 정수 배열의 길이가 모두 같도록 패딩(padding)을 추가
  • max_length * num_reviews 크기의 정수 텐서를 만듦
  • 이런 형태의 텐서를 다룰 수 있는 임베딩(embedding) 층을 신경망의 첫 번째 층으로 사용

 

2. 실습

from tensorflow.keras.preprocessing.sequence import pad_sequences
pad_sequences(sequences, maxlen=None, dtype='int32', padding='pre', truncating='pre', value=0.0)
sequence = [[1], [2, 3], [4, 5, 6]]
tf.keras.preprocessing.sequence.pad_sequences(sequence)
>>>    array([[0, 0, 1],
           [0, 2, 3],
           [4, 5, 6]], dtype=int32)
tf.keras.preprocessing.sequence.pad_sequences(sequence, value=-1)
>>> array([[-1, -1,  1],
           [-1,  2,  3],
           [ 4,  5,  6]], dtype=int32)
tf.keras.preprocessing.sequence.pad_sequences(sequence, padding='post')
>>> array([[1, 0, 0],
           [2, 3, 0],
           [4, 5, 6]], dtype=int32)
tf.keras.preprocessing.sequence.pad_sequences(sequence, maxlen=2)
>>> array([[0, 1],
           [2, 3],
           [5, 6]], dtype=int32)

 

RNN

순환 신경망(Recurrent neural network, RNN)

  • 인공 신경망의 한 종류로, 유닛간의 연결이 순환적 구조를 가짐
  • 시변적 동적 특징을 모델링 할 수 있도록 신경망 내부에 상태를 저장할 수 있게 해줌
  • 순방향 신경망과 달리 내부의 메모리를 이용해 시퀀스 형태의 입력을 처리 가능
  • 필기 인식이나 음성 인식과 같이 시변적 특징을 지니는 데이터를 처리하는데 적용 가능
  • 층을 그리 깊게 쌓지 않음
  • RNN 계층은 for 루프를 사용하여 시퀀스의 시간 단계를 반복 => 인코딩하여 내부 상태 유지
  • Keras RNN API 는 사용 편리성과 사용자 정의 용이성을 중점을 두고 설계됨
    • 사용 편리성 : 내장 keras.layers.RNN, keras.layers.LSTM, keras.layers.GRU 레이어
    • 사용자 정의 용이성 : 체 RNN 셀 계층 ( for 루프의 내부 부분)을 정의하고 일반 keras.layers.RNN 계층 ( for 루프 자체)과 함께 사용가능

댓글