Project/캡스톤디자인2

[NLP Project] BERT 인풋 만들기 - 1. 문장 전처리

sillon 2022. 11. 9. 22:27
728x90
반응형

전처리한 데이터를 바탕으로 태그와 문장을 토큰화 해보겠습니다.

 

문장 토큰화

tokenization.py

from transformers import BertTokenizer
from transformers import BertTokenizer



def tokenize_and_preserve_labels(sentence, text_labels):

  tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')
  tokenized_sentence = []
  labels = []

  for word, label in zip(sentence, text_labels):

    tokenized_word = tokenizer.tokenize(word)
    n_subwords = len(tokenized_word)

    tokenized_sentence.extend(tokenized_word)
    labels.extend([label] * n_subwords)

  return tokenized_sentence, labels

이제 문장을 토큰화 했으니, 태그를 토큰화 할 차례죠..

 

태그 토큰화

def tag_tokenize(ner_tags):
    tar_tokenizer = Tokenizer()
    tar_tokenizer.fit_on_texts(ner_tags)
    tag_size = len(tar_tokenizer.word_index) + 1
    tag_dict = tar_tokenizer.word_index
    tag_dict.update({"[PAD]":0})
    index_to_ner = {i:j for j, i in tag_dict.items()}

    # 영어 태그명을 인덱싱한 딕셔너리를 이용해 인덱스로 변환
    
    idx_ner_tags = []

    for tags in ner_tags:
        tagging_list = []
        for tag in tags:
            tag= tag.lower()
            tagging_list.append(tag_dict[tag])
        idx_ner_tags.append(tagging_list)

    return idx_ner_tags,index_to_ner,tag_size

이후에 패딩을 하여 입력값을 맞춰주는 과정이 있을 것이기 때문에 pad 태그도 넣었습니다.

 

토큰화 결과는 다음과 같습니다.

{1: '-', 2: 'cvl_b', 3: 'num_b', 4: 'per_b', 5: 'org_b', 6: 'dat_b', 7: 'loc_b', 8: 'trm_b', 9: 'evt_b', 10: 'num_i', 11: 'dat_i', 12: 'anm_b', 13: 'evt_i', 14: 'per_i', 15: 'org_i', 16: 'afw_b', 17: 'cvl_i', 18: 'trm_i', 19: 'tim_b', 20: 'fld_b', 21: 'afw_i', 22: 'tim_i', 23: 'plt_b', 24: 'mat_b', 25: 'loc_i', 26: 'anm_i', 27: 'fld_i', 28: 'mat_i', 29: 'plt_i', 0: '[PAD]'}

토큰화 결과 0번이 없었어서 0을 PAD값으로 넣었습니다.

 

 

 

main.py

일단 앞의 10개의 문장만 토큰화 해주었습니다.

(시간이 꽤 걸려서 10개만 테스트..)

 

from data_load import file_load, tag_split
from tokenization import tokenize_and_preserve_labels,tag_tokenize



if __name__ == "__main__":
    file_path = "data/train_data.txt"
    tagged_sentences = file_load(file_path)
    sentences, ner_tags = tag_split(tagged_sentences)
    idx_ner_tags,index_to_ner,tag_size = tag_tokenize(ner_tags)
    tokenized_texts_and_labels = [tokenize_and_preserve_labels(sent, labs) for sent, labs in zip(sentences[:10], idx_ner_tags)]
[(['[CLS]', '비', '##토', '##리', '##오', '양', '##일', '만', '##에', '영', '##사', '##관', '감', '##호', '용', '##퇴', '항', '##룡', '압', '##력', '##설', '의', '##심', '##만', '가', '##율', '[SEP]'], [1, 4, 4, 4, 4, 6, 6, 1, 1, 5, 5, 5, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), (['[CLS]', '이', '음', '##경', '##동', '##맥', '##의', '직', '##경', '##이', '8', '19', '##mm', '##입', '##니다', '.', '[SEP]'], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1]), (['[CLS]', '9', '##세', '##이브', '##로', '구', '##완', '30', '##위', '##인', 'LG', '박', '##찬', '##형', '##은', '평', '##균', '##자', '##책', '##점', '##이', '16', '.', '45', '##로', '준', '##수', '##한', '편', '##이지', '##만', '22', '##이', '##닝', '동안', '피', '##홈', '##런', '##이', '31', '##개', '##나', '된다', '.', '[SEP]'], [1, 3, 3, 3, 3, 1, 1, 3, 3, 3, 5, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1]), (['[CLS]', '7', '##승', '25', '##패', '##는', '상', '##트', '##페', '##테', '##르', '##부', '##르', '##크', '##가', '역', '##대', '월', '##드', '##리그', '##에', '출', '##진', '##한', '분', '##별', '최', '##선의', '성', '##적', '##이다', '.', '[SEP]'], [1, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), (['[CLS]', '퍼', '##거', '##슨', '씨', '##족', '##의', '꾀', '[SEP]'], [1, 4, 4, 4, 2, 2, 2, 1, 1]), (['[CLS]', '유', '##로', '##200', '##8', '공', '##인', '##구', '##가', '변', '##할', '기', '##록', '시', '##정', '##조', '##치는', '죽', '##을', '맛', '[SEP]'], [1, 9, 9, 9, 9, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1]), (['[CLS]', '로마', '##올', '##림', '##픽', '##에서', '육', '##미', '##지', '##황', '##탕', '이', '##남', '##지', '##역', '##으로', '동', '##메', '##달', '##에', '머', '##문', '추', '##경', '##대는', '차', '##년', '파', '##리', '##오', '##픈', '결', '##승', '##전에서', '진', '동', '##영', '##의', '탄', '##셰', '차', '##우', '##세', '##스', '##쿠', '##를', '비', '##롯', '##해', '몽', '##골', '##의', '이', '##창', '##동', '차', '##간', '##바', '발', '##보', '##나', '##의', '리', '##자', '##루', '##드', '박', '##혜', '##미', '##셔', '좌', '##타', '##자를', '놓', '##고', '추', '##축', '##한다', '.', '[SEP]'], [1, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 18, 18, 18, 18, 18, 2, 2, 2, 2, 1, 1, 4, 4, 4, 6, 6, 9, 9, 9, 9, 13, 13, 13, 1, 7, 7, 7, 4, 4, 14, 14, 14, 14, 14, 14, 1, 1, 1, 7, 7, 7, 4, 4, 4, 14, 14, 14, 7, 7, 7, 7, 4, 4, 4, 4, 14, 14, 14, 14, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1]), (['[CLS]', '금', '##반', '명', '##기', '통', '##합', '##우', '##승', '24', '10', '##회', '##차', '##는', '8일', '상', '##오', '6', '##시', '50', '##분', '상', '##오', '11', '##시', '50', '##분에', '발', '##태', '##가', '끝', '##마', '##감', '##되며', '비', '##공', '##식', '적', '##중', '##결', '##과', '##는', '5일', '공', '##표', '##된다', '.', '[SEP]'], [1, 1, 1, 2, 2, 17, 17, 17, 17, 3, 10, 10, 10, 10, 6, 19, 19, 22, 22, 22, 22, 19, 19, 22, 22, 22, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1]), (['[CLS]', '권', '##뢰', '##가', '있는', '곳', '##에', '직', '##경', '##에', '따라', '달', '##라', '##지는', '##데', '##요', '.', '[SEP]'], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), (['[CLS]', '때', '##로는', '##은', '귀', '##여', '##운', '가', '##스', '##나', '##기', '##인', '비', '##담', '세', '##상', '##일', '##에는', '무', '##관', '##심', '.', '[SEP]'], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])]

이렇게 버트 입력에 맞게 변환된 모습을 볼 수 있습니다.

 

90000 개라서 꽤 걸리는 듯 합니다.. 

매번 코드를 돌릴 때 마다 토큰화 하기에는 시간이 걸려서 토큰화 한값을 데이터로 따로 저장하도록 하겠습니다.

 

피클 라이브러리를 통해 저장할 수 있습니다!

예제 코드

 

def file_save(f_list):
    filePath = 'data/token_data.txt'
    with open(filePath, 'wb') as lf:
        pickle.dump(f_list, lf)


def file_open(filePath):
    with open(filePath, 'rb') as lf:
        readList = pickle.load(lf)
        print(readList)

main.py

from data_load import file_load, tag_split
from tokenization import tokenize_and_preserve_labels,tag_tokenize


import pickle

def file_save(f_list):
    filePath = 'data/token_data.txt'
    with open(filePath, 'wb') as lf:
        pickle.dump(f_list, lf)


def file_open(filePath):
    with open(filePath, 'rb') as lf:
        readList = pickle.load(lf)
        print(readList)



if __name__ == "__main__":
    file_path = "data/train_data.txt"
    tagged_sentences = file_load(file_path)
    sentences, ner_tags = tag_split(tagged_sentences)
    idx_ner_tags,index_to_ner,tag_size = tag_tokenize(ner_tags)
    tokenized_texts_and_labels = [tokenize_and_preserve_labels(sent, labs) for sent, labs in zip(sentences, idx_ner_tags)]
    file_save(tokenized_texts_and_labels) # 파일 저장
    # file_open('data/token_data.txt') # 파일 열기

 

728x90
반응형