본문 바로가기
Python/NLP&LLM

Tokenizer 심화

by Mr.DonyStark 2024. 5. 3.

1. Tokenization : text를 word 또는 sub-word로 분리


2. Tokenizer 종류
  (1) 사전방식 : KoNLPy
  (2) sub-word 방식 : BPE, WordPiece, SentencePiece

3. Tokenizer 방법

  (1) 사전방식
      - rule-based tokenization : 공백 또는 구둣점으로 분리 by Keras
      - 띄어쓰기가 가능한 영어같은 경우에 가능
      - 단점 memory, time complexity 증가
  (2) subword tokenization  * 모두 학습이라는 과정이 필요함
      - 빈번히 사용되는 단어는 더 작은 subword로 나뉘어지면안됨
      - 가끔 사용되는 단어는 의미 있는 subword로 나뉘어 져야한다
      - 교착어(한국어,터키어, 일본어)의 token화에 유용
      - WPM(Word Piece Model) : 하나의 단어를 내부단어(subword) 통계에 기반하여 띄어쓰기로 분리. 하나의 단어는 의미있는 여러단어들의 조합으로 구성된 경우가 많기 때문에 단어를 여러 단어로 분리하여 보겠다는 전처리작업
      - Google SentencePiece : 사전 토큰화 작업 없이 단어 분리 토큰화를 수행하므로 언어에 종속되지 않음.(opensource) 언어에 종속안됨 떄문에 한국어 사용가능

 

4. 예제

#corps : 말뭉치
sentences_E = [
    'I love my dog',
    'I love my cat',
    'You love my dog!',
    'I was born in Korea and graduaged University in USA.',
]

sentences_K = [
    "코로나가 심하다",
    "코비드-19가 심하다",
    '아버지가방에들어가신다',
    '아버지가 방에 들어가신다',
    '너무너무너무는 나카무라세이코가 불러 크게 히트한 노래입니다'
]

 

  (1) keras tokenizer

#라이브러리
from tensorflow.keras.preprocessing.text import Tokenizer

#단어사전구축 : 사이즈는 100, 없는 단어는 oov로 처리 / 말뭉치 E 사용
tokenizer = Tokenizer(num_words=100, oov_token="<OOV>")
tokenizer.fit_on_texts(sentences_E)
tokenizer.word_index #토큰별 인덱스 확인

#단어사전구축 : 사이즈는 100, 없는 단어는 oov로 처리 / 말뭉치K 사용
tokenizer = Tokenizer(num_words=100, oov_token="<OOV>")
tokenizer.fit_on_texts(sentences_K)
vocabulary_keras_korean=tokenizer.word_index #토큰별 인덱스 확인

 

  (2) 사전방식 : KoNLPy

#라이브러리
from konlpy.tag import Okt

#객체생성
okt = Okt()

temp_X = list()#형태소 담을 리스트
for sent in sentences_K:
    print(sent)
    temp_X.append(okt.morphs(sent)) # .morphs 형태소 단위분석을 위해 활용

temp_X

#사전 기반 tokenize 후 Keras tokenizer 로 vocabulary 생성
tokenizer = Tokenizer(num_words=100, oov_token='<OOV>')  # 빈도수 상위 100 개로 구성

tokenizer.fit_on_texts(temp_X) #사전에 형태소 분리된 데이터 저장
vocabulary_okt_keras = tokenizer.word_index #tokenize별 인덱스 확인
print(vocabulary_okt_keras)

 

형태소 분리전과 후

 

tokenize별 인덱스번호

 

keras Tokenizer vs KoNLPy

#두 vocabulary 의 차이 비교
print(vocabulary_keras_korean)
print(vocabulary_okt_keras)

한국어는 KoNLPy를 통해 tokenize를 진행 한 것이 더 효율적으로 보임

 

  (3) 사전방식 : Google SentencePiece Tokenizer

#라이브러리 호출
import tensorflow as tf
import pandas as pd
import sentencepiece as spm

#데이터 호출
DATA_TRAIN_PATH = tf.keras.utils.get_file("ratings_train.txt",
        "https://github.com/ironmanciti/NLP_lecture/raw/master/data/naver_movie/ratings_train.txt")
        
#pandas.read_csv에서 quoting = 3으로 설정해주면 인용구(따옴표)를 무시
train_data = pd.read_csv(DATA_TRAIN_PATH, sep='\t', quoting=3)

print(train_data.shape)
train_data.head()

#전처리
train_data.isnull().sum()

train_data.dropna(inplace=True)

train_data.shape

전처리 후 행과 열 개수

#데이터 확인
train_data.document.values

데이터 149,995개 확인

#학습을 위해 text를 따로저장
with open('./nsmc.txt', 'w', encoding='utf-8') as f:
    for line in train_data.document.values:
        try:
            f.write(line + '\n')
        except:
            print("write error ---> ", line)
            
#write 가 잘 되었는지 확인
with open('./nsmc.txt', 'r', encoding='utf-8') as f:
    nsmc_txt = f.read().split('\n')

print(len(nsmc_txt))
print(nsmc_txt[0])

#vocabulary 학습
input_file = "./nsmc.txt"
vocab_size=30000
prefix = 'nsmc' #nsmc"라는 접두사를 사용하여 모델 파일이 "nsmc.model"로 저장

templates = '--input={} --model_prefix={} --vocab_size={}'
cmd = templates.format(input_file, prefix, vocab_size)
cmd

# SentencePiece 학습
spm.SentencePieceTrainer.Train(cmd)

sp = spm.SentencePieceProcessor()
sp.Load("nsmc.model") # "nsmc.model"이라는 이름의 SentencePiece 모델 파일을 로드

for s in train_data.document.values[:3]:
    print(s)
    print(sp.encode_as_pieces(s))
    print(sp.encode_as_ids(s)) #시퀀스로 수열로변환

지정한 템플릿 양식에 맞춰 tokenize 및 수열(Vector화) 확인

#말뭉치 중 sentences_K 로 테스트
for s in sentences_K:
    print(s)
    print(sp.encode_as_pieces(s))
    print(sp.encode_as_ids(s)) #시퀀스로 수열로변환

Konlpy 보다 더 성능이 좋은 것으로 보임

 

 

결론 : 상황과 목적에 맞게 적절한 Tokenizer 를 선택하고 활용하자!

'Python > NLP&LLM' 카테고리의 다른 글

영화리뷰 : 감정분석  (1) 2024.05.03
RNN(Recurrent Neural Network)  (0) 2024.05.02
Word Embedding과 Word2Vec  (0) 2024.05.02
문장 Vector 작업  (0) 2024.05.01
자연어 처리(Natural Language Processing) 및 발전단계  (0) 2024.04.30