본문 바로가기
자연어(LLM)

[AI활용 자연어처리 챗봇프로젝트] 케라스를 이용한 전처리

by 바다의 공간 2024. 12. 5.

■ keras의 텍스트 전처리

 

케라스에서도 텍스트에 대한 전처리가 가능합니다.

 

https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/text/Tokenizer
tf.keras.preprocessing.text.Tokenizer(
    num_words=None,
    filters=&#x27;!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
    lower=True,
    split=&#x27; ',
    char_level=False,
    oov_token=None,
    analyzer=None,
    **kwargs
)

 

 

역시나 먼저 임포트를 해줍니다.

위에있는 매개변수들은 자연어처리하면서 굉장히 많이 봐야하는 것들임으로 눈에 익혀두기..

from tensorflow.keras.preprocessing.text import Tokenizer

 

또 예시를 가지고 해보겠습니다..

여러문장으로 되어있는 raw_text변수입니다.

 

raw_text = "A barber is a person. a barber is good person. a barber is huge person. he Knew A Secret! The Secret He Kept is huge secret. Huge secret. His barber kept his word. a barber kept his word. His barber kept his secret. But keeping and keeping such a huge secret to himself was driving the barber crazy. the barber went up a huge mountain."


#문장 토큰화
sentences = sent_tokenize(raw_text)
sentences

결과
['A barber is a person.',
 'a barber is good person.',
 'a barber is huge person.',
 'he Knew A Secret!',
 'The Secret He Kept is huge secret.',
 'Huge secret.',
 'His barber kept his word.',
 'a barber kept his word.',
 'His barber kept his secret.',
 'But keeping and keeping such a huge secret to himself was driving the barber crazy.',
 'the barber went up a huge mountain.']

 

불용어 - > 소문자 제거 등 을 한 결과값이 나오게됩니다.

 

이제 이 부분을 정제하고 정규화하고 단어 토큰화해서 전처리를 좀 더 해보겠습니다.

 

# 정제작업 + 정규화 작업 + 단어 토큰화
vocab = {}
preprocessed_sentences = []
stop_words = set(stopwords.words('english'))

for sentence in sentences:
  # 단어 토큰화
  tokenized_sentence = word_tokenize(sentence)
  result = []

  for word in tokenized_sentence:
    word = word.lower()  # 모든 단어들을 소문자로 --> 단어의 개수를 줄임
    if word not in stop_words:  # 불용어 제거
      if len(word) > 2:  # 단어 길이가 2이하이면 제거
        result.append(word)
        # 빈도수 체크
        if word not in vocab:
          vocab[word] = 0
        vocab[word] += 1

  preprocessed_sentences.append(result)

preprocessed_sentences

 

를하게되면 정제가 좀 돼서

 

이러한 결과가 나오게 됩니다.

 

이제 앞으로 자주 볼 객체인데 토큰화를 해줄 수 있는 객체를 불러옵니다.

tokenizer = Tokennizer()

tokenizer.fit_on_text(prerocessed_sentences)

tokenizer.word_index
결과
{'barber': 1,
 'secret': 2,
 'huge': 3,
 'kept': 4,
 'person': 5,
 'word': 6,
 'keeping': 7,
 'good': 8,
 'knew': 9,
 'driving': 10,
 'crazy': 11,
 'went': 12,
 'mountain': 13}

 

 

전체적으로 다시 보자면 객체를 불러오고 preprocessed_sentences 문장을 넣어서 토큰화를 시킵니다.

토큰화를 시키고 fit_on_text()를 하게 되면 빈도술대로 인덱스를 생성해줍니다.

여기서 인덱스는 1이 가장 많은 빈도수를 의미하게됩니다.

# 각 단어의 총 등장 빈도수
tokenizer.word_counts
OrderedDict([('barber', 8),
             ('person', 3),
             ('good', 1),
             ('huge', 5),
             ('knew', 1),
             ('secret', 6),
             ('kept', 4),
             ('word', 2),
             ('keeping', 2),
             ('driving', 1),
             ('crazy', 1),
             ('went', 1),
             ('mountain', 1)])

 

각 단어의 빈도수입니다. barber이 가장 많으니 빈도수도 8로 나오는걸 볼 수 있습니다.

이걸 fit_on_text()로하게되면 barber이 1이 되는거죠.

 

 

#text_to_sequences()
#입력으로 들어온 코퍼스에 대해 각 단어를 정해진 인덱스로 변환함

tokenizer.texts_to_sequences(preprocessed_sentences)

# 즉 정수인코딩 된 결과입니다.
# barber =1 .... 이런식~

 

이렇게 하게되면 이제 정수로 인코딩이 된 결과값을 받게 됩니다.

[[1, 5],
 [1, 8, 5],
 [1, 3, 5],
 [9, 2],
 [2, 4, 3, 2],
 [3, 2],
 [1, 4, 6],
 [1, 4, 6],
 [1, 4, 2],
 [7, 7, 3, 2, 10, 1, 11],
 [1, 12, 3, 13]]

이렇게되면 

1은 barber이고 5는 person 라는것까지 알 수 있겠죠.

 

여기서 vocab_size를 5로 설정해주면 5개의 어휘만 사용한다는 말입니다.

#5개 어휘만 사용
vocab_size = 5
tokenizer =Tokenizer(num_words = vocab_size + 1) #상위 5개 단어만 사용!
tokenizer.fit_on_texts(preprocessed_sentences)

 

 

그리고 또 torkenizer.word_inedex를 뽑아보면

 

위와같은 결과값이 나오게 됩니다.  

# num_words= 가 적용되는 것은 texts_to_sequences()를 사용할때 적용됨!

preprocessed_sentences
결과
[['barber', 'person'],
 ['barber', 'good', 'person'],
 ['barber', 'huge', 'person'],
 ['knew', 'secret'],
 ['secret', 'kept', 'huge', 'secret'],
 ['huge', 'secret'],
 ['barber', 'kept', 'word'],
 ['barber', 'kept', 'word'],
 ['barber', 'kept', 'secret'],
 ['keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy'],
 ['barber', 'went', 'huge', 'mountain']]
tokenizer.texts_to_sequences(preprocessed_sentences)

결과
[[1, 5],
 [1, 5],
 [1, 3, 5],
 [2],
 [2, 4, 3, 2],
 [3, 2],
 [1, 4],
 [1, 4],
 [1, 4, 2],
 [3, 2, 1],
 [1, 3]]

 

 

이렇게 되면 1번단어부터 5번단어까지만 보존되고 나머지는 제거 되었다는것을 볼 수 있습니다.

 

그러면 단어집합에 없는단어는 뭐라고할까요?

oov라고 하는데 OOV에 관해서는 따로 또 정리를 했습니다! (넘 길어짐)