INTRO
https://mz-moonzoo.tistory.com/3
한국 광고 분류 모델의 경우 학습에 활용할 적당한 데이터셋이 없어서 직접 데이터 라벨링을 진행해야 하기 때문에 시간이
오래 걸리는 관계로 한국 광고 분류 모델 개발에 앞서 한국 경제 뉴스 기사 감정 분류 모델 개발을 우선 진행하기로 했다.
이것 외에도 한국 뉴스 NER 모델 개발도 진행 중이다.
최종 학습 모델과 학습 데이터셋을 사정상 따로 공개할 수 없어서 베타 버전으로 간단하게만 글을 작성하고자 한다.
최종 목적
1. 한국 뉴스 기사 중 광고성 기사가 많으므로 개발한 한국 광고 분류 모델로 기사 필터링을 진행한다.
-> Topic modeling에 들어갈 기사가 광고가 많으면 응집도가 떨어지고 혼란도가 높아지기 때문.
2. 필터링된 전체 뉴스 기사를 문장 단위로 자르고 Topic modeling + NER + Sentiment Analysis을 진행한다.
-> BERT 모델이 지원하는 최대 문장 길이가 512까지이고 문장 길이가 긴 학습 데이터가 많지 않기 때문.
단, Topic modeling에 들어갈 텍스트는 전체 뉴스 기사를 input으로 넣어서 사용.
FLOW
뉴스 광고 분류 모델(전처리) -> Topic modeling -> NER -> SA -> Output 후 처리
Topic modeling
https://mz-moonzoo.tistory.com/24
Sentiment Analysis
https://mz-moonzoo.tistory.com/17
2023년 2월15일 시점으로 Topic modeling과 Sentiment Analysis까지는 코드와 리뷰작성을 끝냈습니다.
한국 광고 분류 모델은 데이터셋을 직접 만드는게 너무 큰 시간이 소요돼서 가장 마지막으로 미루고 있습니다...ㅎㅎ
이번 글에서는 NER 모델 코드 리뷰를 진행하도록 하겠습니다.
NER
개체명 인식(Named Entity Recognition)이란 말 그대로 이름을 가진 개체(named entity)를 인식하겠다는 것을 의미합니다. 좀 더 쉽게 설명하면, 어떤 이름을 의미하는 단어를 보고는 그 단어가 어떤 유형인지를 인식하는 것을 말합니다.
예를 들어 유정이는 2018년에 골드만삭스에 입사했다. 라는 문장이 있을 때, 사람(person), 조직(organization), 시간(time)에 대해 개체명 인식을 수행하는 모델이라면 다음과 같은 결과를 보여줍니다.
한국 경제 뉴스 NER 모델
이번 프로젝트에서의 목표는 한국 뉴스에서 여러 entity 중 기업들(조직,ORG)만 뽑아내는 것 입니다.
예를들어,
'중국의 리오프닝 본격화와 국내 실내 마스크 해제 조치 기대감에 LG생활건강, 아모레퍼시픽 등은 5%대 뛰었다.' 라는
뉴스 기사가 있을 때 , LG생활건강 - ORG / 아모레퍼시픽 - ORG 이런식으로 기사 내에서 기업명만 뽑아내는 것 입니다.
이를 활용하면 수 많은 뉴스 중에서 기업과 관련된 문장만 뽑아낼 수 있습니다.
이 문장을 SA모델을 통해 감성 스코어를 계산한다면 일간, 주간, 월간 주식 종목의 감성 점수를 측정할 수 있습니다.
생성된 감성 점수를 다양한 서비스에 활용할 수 있을 것입니다.
EX1) 뉴스와 관련된 주식 종목 정보를 제공한다.
- 이 뉴스는 MS와 GOOG와 연관된 뉴스입니다.
EX2) Topic modeling 토픽에 포함된 종목들의 리스트와 감성 점수를 보여줄 수 있습니다.
- 이 주의 뉴스 트렌드 3번은 ChatGPT이고 관련된 종목은 MS, GOOG가 있으며, MS는 긍정 GOOG는 부정입니다.
EX3) 실시간으로 수집된 뉴스 기사로 주식 종목의 감성 점수를 업데이트 하며 시계열 정보로 제공한다.
- 어제에 비해 MS의 감성 스코어는 0.5만큼 상승했으며 현재 감성 스코어는 2.3으로 긍정적입니다.
이 외에도 다양한 서비스와 접목해 활용할 수 있을 것입니다.
1. CPU 및 GPU 환경 설정
개발 환경 : Backend AI(서버) / GPU, Python 3.8, CUDA 11.1
모델 학습 속도 향상을 위해 GPU 설정을 진행합니다.
2. 데이터셋 준비
한국의 NER 데이터는 그 수가 매우 부족한 상황입니다.
현재 공개된 한국어 NER 데이터 셋은 총 세 가지이며, 모두 상업적 이용은 제한되어있습니다.
(1) 국립국어원 NER 데이터 셋
:총 3,555개 문장
:BIO 태깅 시스템 사용
:5종류의 Annotated Entities – { 장소(LC), 날짜(DT), 기관(OG), 시간(TI), 인물(PS) }
(2) 한국해양대학교 자연어처리 연구실 NER 데이터 셋
:총 23,964개 문장
:BIO 태깅 시스템 사용
:10 종류의 Annotated Entities – { 인물(PER), 기관(ORG), 지명(LOC), 기타(POH), 날짜(DAT), 시간(TIM), 기간(DUR), 통화(MNY), 비율(PNT), 기타 수량표현(NOH) }
(3) NAVER NLP Challenge 2018
:총 82, 393개문장
:BIO 태깅 시스템 사용
: 14 종류의 AnnotatedEntities – { 인물(PER), 학문분야(FLD), 인공물(AFW), 기관및 단체(ORG), 지역명(LOC), 문명 및문화(CVL), 날짜(DAT), 시간(TIM), 숫자(NUM), 사건사고 및 행사(EVT), 동물(ANM), 식물(PLT), 금속/암석/화학물질(MAT), 의학용어/IT관련 용어(TRM) }
실습에서는 한국해양대학교 데이터셋과 네이버 데이터셋 두 가지만 사용하도록 하겠습니다.
데이터셋 다운 및 불러오기
1. 한국해양대학교 자연어처리 연구실 NER 데이터 셋
데이터셋 샘플
지금까지 csv파일처럼 한눈에 보기 쉽게 정리된 데이터를 주로 다뤘는데 생긴거만 봐도 뭔가 복잡하네요..ㅋㅋㅋ
2. NAVER NLP Challenge 2018 NER 데이터셋
데이터셋 샘플
네이버 데이터셋은 라이브러리로 손쉽게 불러올 수 있습니다.
네이버 데이터셋도 대충 봤는데도 벌써 눈이 아프네여...ㅎㅎ
3. 상장법인목록 리스트
학습에 사용할 한국 종목명들이 필요해서 급한대로 기업공시 채널에서 전체 상장법인 목록을 다운로드 받았습니다.
그리고 여러 컬럼들 중 기업명만 있으면 되기 때문에 기업명만 따로 org_df변수로 빼줬습니다.
3. 데이터셋 전처리
데이터셋 모두 그대로 학습할 수도 있지만 저의 목적은 한국 기업명만 ORG로 뽑아내는 것이 목적입니다.
1. ORG를 제외한 다른 모든 tag는 'O'로 변환해주도록 합니다.
- 뉴스에서 뽑아내야 할 entity 정보가 ORG이기 때문입니다.
2. 앞서 불러온 상장법인목록 리스트의 회사명을 랜덤으로 데이터 셋의 ORG와 교체해주도록 합니다.
- 학습 데이터셋에 회사명이 포함된 데이터가 별로 없어서 기업명을 잘 뽑아내지 못할 것 같습니다.
- 그래서 상장법인목록 리스트의 회사명을 랜덤으로 데이터셋에 ORG 텍스트와 변경해줬습니다.
3. 단어 단위로 부착된 태그를 음절 단위로 태그를 다시 부착해주도록 하겠습니다.
* 왜 멀쩡한 단어를 음절 단위로 쪼개는지?
- BertTokenizer를 사용할 것인데 여기에는 8000개 밖에 안되는 한국어가 들어있지만 많은 수가 음절입니다.
- 한국어들이 거의 음절로 존재하기 때문에 음절 단위 tokenizer를 적용하면 vocab id를 어느정도 얻을 수 있습니다.
- 그렇기 때문에 음절로 쪼개면 UNK가 별로 없이 나오기 때문에 음절 단위로 학습을 진행했습니다.
4. ORG 단어의 첫 음절에는 B-ORG 태그를 다음 음절부터는 I-ORG 태그를 부착하도록 합니다.
1. 한국해양대학교 자연어처리 연구실 NER 데이터 셋
전처리 샘플
이런식으로 전처리가 잘 진행된 것을 볼 수 있습니다.
자세히 보시면 SUN&L, 한컴위드라는 기업명이 들어가고 음절 단위로 잘 잘린 것을 볼 수 있습니다.
글이 원문은 야스쿠니 신사{ORG} 참배인데 이게 SUM&L로 변환된 것이고. 한컴위드는 일본{ORG}이 변환된 것입니다.
2. NAVER NLP Challenge 2018 NER 데이터셋 전처리
전처리 샘플
이런식으로 전처리가 잘 진행된 것을 볼 수 있습니다.
자세히 보시면 아이스크림에듀라는 기업명이 들어가고 음절 단위로 잘 잘린 것을 볼 수 있습니다.
글의 원문은 비토리오 양일만에 영사관 감호 용퇴. 라는 글인데 영사관이 ORG로 태깅 돼있어서 영사관 대신 아이스크림 에듀가 들어간 것입니다.
3. 한국 해양대학교 데이터셋 + 네이버 데이터셋 합치기
데이터셋 합치기는 간단하게 extend를 사용해 하나의 데이터셋으로 만들어줬습니다.
그리고 학습을 위한 unique_tags, tag2id, id2tag를 정의해주도록 합니다.
여기서 전처리를 진행했을 때 수 많은 entity 태그 중 ORG만 뽑다보니 너무 많은 O가 생성돼 일부 데이터에서 ORG가 들어가있지 않은 문장은 제거하고 학습을 진행하는 방법도 있습니다만 여기서는 제거하지 않고 그냥 진행했습니다.
4. EDA
EDA를 가볍게 진행하고 학습데이터와 평가데이터를 나눠주도록 합니다.
5. Tokenizer
여러 언어모델을 사용해봤지만 KcELECTRA외에 다른 언어모델들은 들쑥날쑥한 성능을 보여줬습니다.
근데 또 신기하게 inference를 해보면 생각보다 잘 나오는거 같기도하고... 이상합니다.
일단 가장 안정적인 성능이 나오는 KcELECTRA를 사용하도록 하겠습니다.
허깅페이스의 transformer를 통해 beomi님이 올려주신 KcELECTRA-base-v2022 토크나이저를 불러옵니다.
음절 tokenzier
저희는 앞서 학습 데이터를 음절 단위로 변경해줬습니다. 하지만 기존 토크나이저는 wordpiece tokenizer로 tokenizing 결과를 반환하기 때문에 음절 tokenizer로 바꿔주도록 하겠습니다.
그리고 첫 음절을 제외한 음절에는 모두 prefix를 붙이도록 합니다. 그 이유는 학습 데이터와 포맷을 맞추기 위해서입니다.
음절 tokenzier 결과
음절 단위로 잘 tokenzier하는지 5자리까지만 확인하도록 하겠습니다. 잘 처리된 것으로 보입니다.
이제 전체 텍스트와 태그 데이터를 tokenizing을 진행합니다.
최종 적으로 train test(87410, 21853)으로 잘 나뉘어졌습니다.
TokenDataset 변환
torch.데이터셋으로 변환하는 이유는 너무 많이 보셨을거 같으니 넘어가도록 하겠습니다.
6. 모델 학습
'허깅 페이스'라는 회사가 만든 'transformers' 패키지가 있고, 일반적인 파이토치 구현체의 layer.py, model.py이 transformer.models에, train.py 가 transformer.Trainer에 대응됩니다.
transformer.Trainer
딥러닝 학습 및 평가에 필요한 optimizer, weight, learning rate schedul, ckpt, tensorbord, evaluation 등을 수행합니다.
Trainer.train 함수를 호출하면 이 모든 과정이 사용자가 원하는 arguments에 맞게 실행됩니다.
pytorch lightning과 비슷하게 공통적으로 사용되는 학습 스크립트를 모듈화 하여 편하게 사용할 수 있다는 점이 장점
허깅페이스의 Trainer를 사용해 모델 학습을 진행해보도록 하겠습니다.
우선 원하는 arguments를 TrainingArguments함수를 사용해 세팅해주도록 하겠습니다.
각 파라미터에 대한 설명은 주석에 달아뒀으니 참고하시면 될 것 같습니다. 원하시는대로 파라미터를 조금씩 변경하셔서 사용하시면 됩니다.
transformer 모델 불러오고 Trainer에 넣어주기
이제 transformer의 tokenzier에 사용한 beomi/KcELECTRA-base-v2022 모델을 불러오고 gpu에 넣어줍니다.
그리고 Trainer 함수에 위에서 세팅한 TrainingArguments와 model 데이터셋을 넣어주시고 callbacks에는 loss가 감소핮 ㅣ않으면 학습을 종료하는 Earlystopping를 넣어주도록 하겠습니다.
그럼 이제 학습 준비가 완료 됐습니다.
Train
Training Loss와 Validation Loss가 쭉쭉 떨어지는 것을 보실 수 있습니다.
trainer.evaluate 결과 eval_loss가 매우 낮은것을 확인 했습니다.
validation Dataset 성능 확인
데이터셋을 추가하는게 성능이 좀 더 떨어지네요ㅠ. 원래 성능이 너무 높았나봅니다.
그럼 이제 열심히 학습시킨 모델을 저장해 필요할때마다 불러와서 사용하도록 합시다.
save_model을 사용하면 폴더가 생성이 됩니다. 그 안에 모델과 training args, config가 있습니다.
7. 저장한 모델 불러오고 Inference
1. 저장한 모델 불러오기
저장한 모델을 불러오는 것은 매우 쉽습니다. 저장만 해두셨으면 위의 코드만으로 학습된 모델을 불러올 수 있습니다.
2. ner_inference
우선 inference를 진행하기 전에 저희의 모델은 기존 토크나이저와 다른 음절 tokenizer이기 때문에 앞에서 사용한
ner_tokenizer을 그대로 가져와 사용하도록 합니다.
위의 코드는 inference 코드입니다. text를 넣어주면 text의 entity를 예측합니다.
1.Infefence example
위의 text는 뉴스 기사의 일부입니다. 다음 텍스트를 학습시킨 ner모델로 inference해보겠습니다.
텍스트 내에서 기업명만 잘 잡아내는 것을 보실 수 있습니다.
2.Infefence example
역시 LG생활건강과 아모레퍼시픽을 잘 잡아내는 것을 확인했습니다.
3.Infefence example
여러 개의 기업명이 속한 기사임에도 딱 기업명만 잘 잡아내는 것을 보실 수 있습니다.
마치며...
생각보다 성능이 잘나오는 것을 보고 놀랐습니다. 대부분의 ORG는 잘 잡아내는 것으로 보입니다.
다른 언어모델을 사용해보거나 데이터셋의 구성을 좀 다르게하고 파라미터를 변경해주면 더 좋은 성능이 나올수도 있다는 생각이 듭니다.
다음 글에서는 한국 뉴스 기사를 학습시킨 Sentiment Analysis, NER 두 모델을 사용해 Inference해보도록 하겠습니다.
전체 코드는 다음 깃허브 링크를 참고하시면 됩니다.
https://github.com/moonjoo98/News_trend/tree/master/KR_NEWS
'Project' 카테고리의 다른 글
[Project]문장 유형 분류 AI 경진대회 (1) | 2023.03.07 |
---|---|
[Project]한국 뉴스 감성분류, NER모델 Inference (0) | 2023.02.15 |
[Project]한국 뉴스 토픽 모델링 (feat. KoBERTopic) (0) | 2023.02.14 |
[Project]해외 뉴스 토픽 모델링 (feat. BERTopic) (5) | 2023.02.13 |
[Project]한국 경제 뉴스 기사 감정 분류 모델 개발 (feat.pytorch) (3) | 2023.01.20 |