본문 바로가기
NLP

[NLP] 트랜스포머 사용 시 숫자 텍스트 데이터 전처리에 대해

by Tiabet 2024. 4. 18.

최근에 텍스트데이터를 임베딩 벡터로 변환하는 태스크를 하다가 문득 이런 궁금증이 들었다. 

'숫자는 어떤 토큰으로 변환되는거지?'

왜냐면 토크나이저의 Map 에는 제한된 개수의 단어들(물론 엄청 많은 수지만)이 정수에 매핑이 되어 있는 걸로 아는데, 1,2,3... 등 양의 정수를 넘어 4.5, -103, 등 숫자끼리 조합하면 정말 무수히 많은 새로운 숫자들이 계속 탄생하기 때문이다.

그래서 한 번 직접 일부 모델의 토크나이저를 사용하여 숫자가 어떻게 처리되는지를 알아보고, 결론을 정리해보고자 한다.

 

 

Integer, Float 토크나이징 해보기

우선 간단하게 정수와 소수가들이 어떻게 토크나이징되고 매핑되는지 체크해봤다. 모델은 가장 보편적인 Bert의 uncased 버전을 사용했다.

tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')

text = "The room temperature is 23.5 degrees, and there are 15 people inside."

tokens = tokenizer.tokenize(text)
token_ids = tokenizer.convert_tokens_to_ids(tokens)

print("Tokens:", tokens)
print("Token IDs:", token_ids)

 

결과는 아래와 같았다.

Tokens: ['the', 'room', 'temperature', 'is', '23', '.', '5', 'degrees', ',', 'and', 'there', 'are', '15', 'people', 'inside', '.']
Token IDs: [1996, 2282, 4860, 2003, 2603, 1012, 1019, 5445, 1010, 1998, 2045, 2024, 2321, 2111, 2503, 1012]

 

확인결과 23은 2603, 5는 1019, 15는 2321에 각각 매핑되어 있었다. 특이한 점은 23.5를 23, ., 5 세 개로 토큰화했다는 것이다. 여기서 짐작할 수 있는 바는 Bert는 소수점의 무한히 많은 경우를 이런 식으로 Subword로 토큰화하여 처리한다는 것이다.

 

하지만 더 확실히 해보기 위해 Bert의 토크나이저 맵을 직접 열어보았다.

https://huggingface.co/google-bert/bert-base-uncased/tree/main

 

google-bert/bert-base-uncased at main

 

huggingface.co

 

숫자는 숫자끼리 모여있을 줄 알았는데 특이한 점을 발견했다.

"dark":2601,"election":2602,"23":2603,"board":2604,

 

뜬금없게도 23은 election, board 사이에 껴있었다.

"once":2320,"15":2321,"20":2322,"should":2323,"18":2324,"2015":2325,

15는 2321, 20은 2322, 18은 2324에 매핑되어있었으며 특이하게도 아주 큰 숫자인 2015는 2325에 매핑이 되어있었다. 뭔진 잘 모르겠으나 아무튼 숫자가 숫자끼리 모여있지 않으며, 큰 숫자들은 매핑이 되어 있지 않은데 단, 2021까지는 매핑이 되어 있다. 추측컨대 2021년까지의 텍스트로 맵을 만들다보니 연도를 표기할 때 사용되는 (2021년, 2015년) 숫자들까진 매핑이 된 것 같다. bert의 토크나이저 맵이 마지막 업데이트가 3~4년 전인 것도 이 추측과 일치한다. 

 

tokens = tokenizer.tokenize("2022")
token_ids = tokenizer.convert_tokens_to_ids(tokens)

print("Tokens:", tokens)
print("Token IDs:", token_ids)
Tokens: ['202', '##2']
Token IDs: [16798, 2475]

 

역시 2022를 넣어보니 두 202와 #2로 갈라진 모습을 확인할 수 있었다.

 

Tokens: ['123', '##49', '##59', '##7', '##23']
Token IDs: [13138, 26224, 28154, 2581, 21926]

 

이번엔 어마어마하게 큰 숫자를 넣어봤더니 무수히 많은 작은 subword로 분리된 것을 알 수 있었다. 이런 subword tokenizer는 내가 이전에 정리한 BPE Tokenizer와 원리가 같은 걸로 알고 있다.

https://tiabet0929.tistory.com/53

 

[NLP] BPETokenizer 이해하기

최근에 캐글에서 열린 LLM 대회의 최적 솔루션은 아주 인상적이었다. https://www.kaggle.com/code/datafan07/train-your-own-tokenizer Train your own Tokenizer Explore and run machine learning code with Kaggle Notebooks | Using data from

tiabet0929.tistory.com

 

결론 : 텍스트 데이터 전처리 시 숫자를 제거해야 하는가?

텍스트 데이터 전처리 코드들을 보면 숫자를 제거하시는 분들이 많다. 하지만 직접 토크나이징을 해본 결과 내가 내린 결론은 '제거하지 않아도 된다'이다. 최소한 트랜스포머를 사용할 때는 말이다. 물론 어떤 태스크를 다루고 있냐에 따라서 결론이 다소 달라질 수도 있을 것 같다. 어떤 분은 한 문장에서 사용된 숫자와 다른 문장에서 사용된 숫자의 척도나 의미가 달라서 제거해야 한다고 말씀할 수도 있을 것 같다. 하지만 트랜스포머는 많은 인코더와 디코더 레이어들을 쌓고, Multi-Head Attention Layer를 통해 동음이의어를 잘 처리하곤 한다. 따라서 숫자에 대해서도 그 부분을 걱정할 필요가 없을 것 같다는 게 내 생각이다.

'NLP' 카테고리의 다른 글

[NLP] Transformer의 Input은 어떻게 Embedding Vector로 변환되나?  (0) 2024.06.06
[NLP] Transformer의 Positional Encoding 정리  (0) 2024.06.06
[NLP Study] - LSTM  (2) 2024.03.22
[NLP Study] - RNN  (0) 2024.02.06
[NLP] BPETokenizer 이해하기  (2) 2024.02.03