Ssul's Blog

파인튜닝을 통한 감정단어 분류기(NER) 본문

AI & ML/학습하기

파인튜닝을 통한 감정단어 분류기(NER)

Ssul 2024. 9. 12. 16:05

최근 회사에서 작성한 AI관련 R&D사업 기획안이 선정되어, 해당 R&D의 총괄을 맡게 되었다.

추석이후 본격적으로 연세대와 함께 멘탈헬스관련 AI모델의 연구개발에 돌입한다.

추석 연휴가 시작되기전 전체적인 로드맵을 그리면서, 내가 써낸 기획안이 실현가능한 수준인지 체크하고 있다(선정을 위해 너무 지른것이 아닌가 체크 또 체크 ;;;)

 

크게 3가지 과업을 셋팅했는데, 그 중 하나가 감정단어 분류기이다.

자연어 데이터안에 있는 감정단어를 AI모델이 인식하여 찾아내고, 분류하는 모델.

 

0. 문제인식

자연어 데이터에서 내가 원하는 감정단어를 어떻게 AI모델이 찾을수 있을까?

우선 기계적인 코딩으로는 쉽다. 감정단어 리스트를 정리하고, 입력된 문장을 단어로 쪼개서, 리스트와 비교하면서 단어를 찾아내면 된다.

하지만 문제는 그렇게 간단하지가 않다.

내 감정단어 리스트에는 "우울한"이라는 단어로 저장되어 있지만,

정작 자연어 데이터에는 "어제 하루 우울하게 보냈어요"라는 문장이 입력된다면? 우울한과 우울하게는 동일한 감정단어이지만, 위 방식으로는 찾아내지를 못한다.

그럼 내 감정단어 리스트를 '우울한', '우울하게', '침울한'...이렇게 무한정 늘리기...그건 너무 비효율적이다. AI가 필요한 시점이다.

'우울한'과 비슷한 맥락의 단어는 모두 찾아낼수 있는 모델이 어디 없을까?

 

1. NER(Named Entity Recognition)

NER은 NLP쪽의 DownStream Task중 자주 나오는 것의 하나로, 문장속에 있는 단어 중 특정한 타입의 단어를 찾는 것이다.

감성분석, 객체명인식(NER) 등 언어모델평가 단골손님

 

예를 들면, "9월 12일에 서울에서 AI 컨퍼런스가 열릴 예정이다."라는 문장에서

9,월,12,일 - 날짜

서울 - 장소

AI컨퍼런스 - 이벤트

이런 형태로 문장을 입력하면 문장속에 있는 단어 중 특정한 장소/날짜 등을 의미하는 단어를 찾아내는 것이다.

 

조금 더 실무형 데이터로 표현해보면

[9월, 12일에, 서울에서, AI, 컨퍼런스가, 열릴, 예정이다] -> [DAT-B, DAT-I, LOC-B, EVT-B, EVT-I, O, O]

이런 형태이다. 간단히 해석해보면

9월 - DAT-B(날짜-Begin)

12일에 - DAT-I(날짜-Inside)

서울에서 - LOC-B(위치-Begin)

AI - EVT-B(이벤트-Begin)

컨퍼런스 - EVT-I(이벤트-Inside)

열릴 - O(Outside)

예정이다 - O(Outside)

(*NER에는 BIO형태의 표기와 BIOSE형태의 표기가 있다. 위에는 BIO표기 예시)

 

내가 목표로 했던 감정단어를 분류할수 있는 모델을 찾았다.

좋은 Pretrain LM을 선정하고, 그 친구를 NER Task로 파인 튜닝을 진행하면, 내가 원하는 감정단어를 자동으로 분류할수 있을 것이다.

 

2. NER 파인튜닝 벤치마킹 조사

적절한 방법론을 찾았으니, 실현 가능성을 테스트해 보기로 하였다.

나중에는 오픈 LLM까지 테스트 해보겠지만, 우선 NER에 적합한 Bert모델로 파인튜닝 해보기로.

한글 데이터로 단어를 분류해볼 예정이니, 해외모델은 제외.

한국의 Bert모델은 3개정도 있었다

SKT Brain에서 제작한 KoBERT, ETRI에서 제작한 KorBERT, 이준범님이 제작한 KcBERT

 

실력이 부족한 저같은 개발자를 위해서 실력자들이 파인튜닝한 코드를 공개해 주셨습니다.

제가 참고한 것은 
KoBERT를 파인튜닝 한 https://github.com/eagle705/pytorch-bert-crf-ner

 

GitHub - eagle705/pytorch-bert-crf-ner: KoBERT와 CRF로 만든 한국어 개체명인식기 (BERT+CRF based Named Entity Recogn

KoBERT와 CRF로 만든 한국어 개체명인식기 (BERT+CRF based Named Entity Recognition model for Korean) - eagle705/pytorch-bert-crf-ner

github.com

과 Beomi님의 KcBERT 파인튜닝 코드 https://github.com/Beomi/KcBERT-Finetune/blob/master/run.sh#L4

 

Beomi님의 파인튜닝 코드를 기반으로 분석해보면,

네이버 NER데이터셋으로 Bert모델을 파인튜닝하여, NER task에 대하여 84~86의 F1 스코어를 확인할 수 있다.

 

Naver NER데이터셋은 아래와 같이 분류되어서,

["O",
                "PER-B", "PER-I", "FLD-B", "FLD-I", "AFW-B", "AFW-I", "ORG-B", "ORG-I",
                "LOC-B", "LOC-I", "CVL-B", "CVL-I", "DAT-B", "DAT-I", "TIM-B", "TIM-I",
                "NUM-B", "NUM-I", "EVT-B", "EVT-I", "ANM-B", "ANM-I", "PLT-B", "PLT-I",
                "MAT-B", "MAT-I", "TRM-B", "TRM-I"]

BIO방식을 따르고, 우리가 알수 있는 PER(사람), NUM(숫자) 등으로 구성된것으로 확인할수 있다.

예시: 역전패' 단국 월드리그 7연패…장영달회장 인퇴 O EVT-B EVT-I NUM-B O

 

 

3. 내가 원하는 형태로 파인튜닝 테스트

BERT를 한글데이터를 이용해 NER과업을 파인튜닝 하는 방법은 확인하였다.

하지만, 내가 원하는 형태는 사람/숫자와 같은 분류가 아닌 감정단어를 분류하는 것이었다.

본격적인 R&D들어가기전 실현가능성을 확인하는 것이니, 감정단어만 찾아내는 NER과업을 파인튜닝 하기로 하였다.

본 R&D에서는 감정 분류체계에 따라 다양한 감정을 분류해야 할 것이다.

 

3-1. 데이터셋 구성

간단한 toy프로젝트이기 때문에, gpt를 활용하여 약1000개의 trainset, 200개의 testset을 구성

단어 태깅은 간단하게 감정단어(EmotionWord)와 그이외단어(Outside)로 구성하였다

[O, EW-B]

 

해당 구성에 맞춰 태깅된 데이터셋을 구성하였다.

그는 화에 빠져 있었다.	O EW-B O O
행복을 가득 안고 하루를 보냈다.	EW-B O O O O

화에 - 감정단어, 행복을 - 감정단어

이렇게 구성하면서 느낀 것은, 감정단어를 잘 찾아내는 AI모델을 만드는 것인데... 그럴려면 결국 감정단어를 잘 태깅한 데이터가 필요했다.(뭐지 이 모순은......)

뒤의 모델 결과를 확인해보면 알겠지만.... 양질의 감정단어 태깅 데이터셋을 구축하는 것이 이 프로젝트의 핵심임을 인식 할 수 있었다.

현재까지 AI는 이게 맞지 않나? 좋은데이터 -> 좋은 모델

 

3-2. 토크나이징 & 라벨링 유지

NER파인튜닝을 하면서 직면할 두번째 난관은 아마 이것일 것이다.

내가 보유한 데이터셋은 아래와 같다

input: 그의 생각은 무엇인지 모르겠고, 짜증만 났다
label: O, O, O, O, EW-B, O

하지만, 언어모델에 학습할때는 저대로 입력되지 않는다.

 

Tokenizer를 통해서, 형태소로 쪼개지면 아래와 같게 된다.

input: 그, 의, 생각, 은, 무엇, 인지, 모르, 겠, 고, 짜증, 만, 났, 다

당연히 나의 라벨링데이터도 아래와 같이 변경되어야 한다.

label: [O, O, O, O, O, O, O, O, O, EW-B, O, O, O]

 

위의 난관을 잘 뚫고, 학습을 시작하였다.

 

 

3-3. 파인튜닝 실행

데이터셋이 크지도 않고, Pretrained Model의 사이즈도 크지 않기에 약 1분이면 20epoch 학습이 끝난다.

그렇다면 과연 그결과는?

 

'짜증'과 '행복'이라는 두개의 감정단어가 있는 아래 문장을 입력했다.

"나는 오늘 굉장히 짜증이 났지만, 친구가 선물을 줘서 행복해졌다."

아래와 같은 출력이 나왔다.

나 => O
##는 => O
오늘 => O
굉장히 => O
짜증 => EW-B
##이 => O
났 => O
##지만 => O
, => O
친구 => O
##가 => O
선물 => O
##을 => O
줘서 => O
행복 => EW-B
##해졌 => O
##다 => O
. => O

오 생각보다 정확하다!!! 기대는 하고 있었지만, 명확하게 짜증과 행복을 태그해주었다.

 

4. 결과 & 시사점

작은 모델과 적은 데이터로 감정단어를 찾아내는 것은 아주 잘 소화하는 것을 확인하였다. 

- 충분히 많은 데이터셋

- 태깅이 아주 잘된 데이터셋을 구성

- 성능 좋은 Pretrained모델

이 셋팅된다면, 감정분류체계에 따른 다양한 감정단어를 분류하는 분류기 개발의 가능성을 확인하였다.

 

본격적인 R&D가 시작되면, 시행착오를 기록에 남겨 보겠다.

 

결국은 좋은 데이터셋 만들기~!!!