brunch

You can make anything
by writing

C.S.Lewis

by 박경아 May 24. 2022

누구냐 널(NER)?

자연어처리 파이널 프로젝트

브런치 글 발행 목록들을 보니 지난 2월 구정이 마지막이였다. 이후로 무슨일이 있었을까? 3월부터 거의 매일 패스트캠퍼스의 딥러닝 실시간 강의와 공부, 그리고 4월엔 자연어처리(NLP) 온라인 학습 트랙을 선택해 강의지옥을 헤메고 있었다. NLP 자체도 처음이지만 NLP 실습이 모두 CLI (Command Line Inferface) 환경에서 이뤄지다 보니 새로운 내용 이해하랴 낯선 실습환경까지 단기간에 정신이 없었다... 어찌됬든 무사히 파이널 프로젝트를 끝내고 깃허브까지 파게 되었다.


패스트캠퍼스 AI 데이터 사이언티스트 6개월 과정을 마친 지금 과연 내가 딥러닝과 머신러닝을 제대로 알고 있는 지 의문도 들지만 그래도 이전보다는 좀? 많이? 성장했겠지?? 앞으로 그 동안 배운 것들을 스스로 정리하는 시간도 가지고 브런치에 그 내용을 조금씩 적어나갈 생각이다.


먼가 중간에 훌쩍 띈 느낌이 들지만 수료를 위한 파이널 프로젝트로 어떤 프로젝트를 진행했고, 어떤 것들을 배웠는지 나의 파이널 프로젝트에 대해 적어보려고 한다.



누구냐 널(NER)?


머신러닝과 딥러닝 기초를 배우고 과정 막바지에 자연어처리(NLP), 컴퓨터비전(CV), 추천 시스템(Recom.) 등의 온라인 트랙학습을 선택하게 된다. 나는 마케팅에서 머신러닝이나 딥러닝을 활용한 고객이탈이나 LTV 예측과 같은 정량적 예측 외에 온라인 상에 고객들이 남기는 반응이나 댓글, 혹은 트렌드를 파악하기 위해 딥러닝을 활용한 자연어처리를 배워보는 게 의미있겠다고 생각해 자연어처리 과정을 선택했다.


자연어처리(Natural Language Processing, NLP)란 말 그대로 사람이 사용하는 말을 처리하는 것으로 자연어는 컴퓨터의 언어가 '인공적'인 것과 대조적인 의미이다. NLP는 다시 컴퓨터가 인간의 말을 이해할 수 있도록 가르치는 NLU (Natural Language Understanding)와 컴퓨터가 이해하고 처리한 결과를 다시 인간의 언어로 돌려주는 NLG (Natural Language Generation)로 나눌 수 있다.


이번에 파이널 프로젝트로 진행한 주제인 NER(Named Entity Recognition)은 NLU의 한 분야로 텍스트가 주어지면 그 안에서 미리 정의한 정보들을 찾아주는 태스크이다. 여기서 미리 정의한 정보란 사람이름이나 지명, 회사이름, 도시이름 등 어떤 개체(Entity)도 될 수 있다.  인식할 Entity 유형을 정의하고 이 Entity 정보를 가진 수만, 혹은 수십 만의 데이터를 가지고 딥러닝에게 학습시켜 새로운 문장이 주어졌을 때 우리가 원하는 개체명들을 쉽게 찾도록 하는 것이다.


예를 들어 캐릭터 이름이나 동물을 개체명으로 정의하고 딥러닝에게 학습시켰다면 (단어표현들의 의미와 숨겨진 패턴 등을 공부해) 위와 같이 예측해주길 기대한다.


NER은 주로 대량의 텍스트 데이터에서 힘을 발휘할 수 있는데 인사팀에서 방대한 지원자들의 이력서나 자소서에서 우선적으로 필요한 내용들을 찾아보거나 고객지원팀에서 고객 리뷰를 다 읽어보기 전에 불만이나 신고 관련 글을 우선적으로 체크하고, 키워드 별로 내용을 필터링하는 데 사용할 수 있다. 


마케팅에서는 패션 브랜드의 소셜 마케팅 전략을 분석함에 있어 NER을 활용한 사례를 보았는데 'A라인 스커트', 'V넥' , '가죽' 등과 같은 패션 심벌을 개체명으로 정의하고 인스타그램에서 크롤링해온 포스트 정보에서 개체명 정보가 있으면 정보성 콘텐츠, 없으면 브랜딩 콘텐츠로 분류하는 것이다. 또한, 각 브랜드의 온라인 사이트에서 크롤링해 온 제품정보(product descriptions)에 NER를 활용해 패션 심벌들을 태깅하고 패션 심벌이 해당 제품정보에 있는 지 아닌 지 여부로 벡터를 생성해 브랜드간 유사도를 계산하는 방법 등이다. 



프로젝트 진행과정


파이널 프로젝트는 팀 프로젝트로, 15개 대분류 카테고리로 개체명이 정의된 국립국어원의 모두의 말뭉치에 대해 사전학습 언어모델(PLM)을 활용한 NER 태스크를 진행하는 것이였다. 해당 데이터셋은 각 문장에 대해 개체명 정보를 문장에서 위치를 나타내는 인덱스로 제공할 뿐 각 문장 내 단어들이 어떤 개체명인지 혹은 아닌지는 우리가 직접 주어진 인덱스를 활용해 태깅을 해야 했다.


국립국어원 개체명 분석 말뭉치 2021 데이터 예시


이를 BIO(Beginning-Inside-Outside) 태깅이라고 하는 데, 문장을 토큰화하고 특정 개체명에 해당하는 토큰 가운데 가장 첫번째 토큰은 B-를 붙이고 개체명에 해당하지만 후속 토큰은 I-를, 그리고 개체명 아닌 토큰은 O를 붙여 딥러닝에게 학습시키는 방법이다.


위 예시를 살펴보면 "[횡설수설/권순활]北 '외화벌이' 뜯어먹기"라는 문장에서 권순활이 사람(PS)을 나타내는 NE로 정의되어 있는데 토크나이저로 권순활을 토큰화하면 (토크나이저에 따라 결과가 다르겠지만) "권순", "##활"로 토큰화된다고 하면 "권순"에는 B-PS를, "##활"에는 I-PS를 태깅하는 것이다. 그리고 딥러닝이 이 두 토큰이 합쳐져 PS(사람)을 나타내는 개체명임을 학습하길 기대하는 것이다.


지금 돌아보면 프로젝트에서 가장 중요하고 시행착오도 많았던 부분이 바로 이 태깅이라 생각한다. 팀원 가운데 코딩 알고리즘을 잘 짜는 컴퓨터 공학부(?) 출신 멤버가 있어서 우리는 얼른 BIO 태깅을 위한 로직을 만들고 딥러닝을 학습시키기 위한 파이토치 코드를 공부했다. 하지만 처음에 B나 I를 개체명 앞에 붙이든 뒤에 붙이든 상관없다고 생각해서 뒤에 붙였는데 학습도 잘되고 결과도 측정되지만 토큰별 성능을 확인하는 과정에서 (seqeval) 오픈소스 라이브러리가 제대로 작동하지 않음을 발견했다.  


오픈소스 라이브러리를 사용할 땐 코드를 좀 살펴보고 사용해야 한다고 해야하나? 아니면 일단 결과를 빨리 확인하고 틀린 게 없는 지 확인하는 게 중요하다고 해야하나? 다행히 발표 몇 일 전에 발견해 결국 B-, I-를 다시 앞에 붙여 재학습을 시켜야했다.


한 가지 또 어려웠던 점은 나를 비롯해 팀원들 모두 허깅페이스(HuggingFace)를 처음 써보는 것은 물론이고 NER이라는 것이 생소했다는 점이다. 그래서 우리는 온라인 강의에서 들은 김기현 강사님의 텍스트 분류를 위한 허깅페이스 코드를 베이스로 각자 NER 태스크로 바꿔 나갔다. 나의 경우는 허깅페이스에 나와 있는 NER 샘플 코드를 공부하고 조금씩 구현해 나갔다. 아무것도 모를 땐 튜토리얼이나 샘플을 따라 일단 만들어 보는 게 좋다는 생각이 들었다. 



레슨런 (LessonLearned)


이제 4주간의 프로젝트가 끝이 났다. 지금 생각하면 어떻게 구현했나 아찔하기도 하지만, 그 당시엔 최선을 다해 코드를 구현하려고 노력했던 것 같다. 아쉬웠던 점은 BIO 태깅이나 코드 짜기에 급급해 전처리 부분에 좀 더 신경을 쓰지 못한 것이다. 특수문자를 제거하거나 BPE 적용 후 토크나이저를 적용했다면 결과가 어땠을까라는 생각도 든다.


또한, 토큰화 과정에서 사전에 있지 않아 OOV(Out of Vocabulary) 처리되어 제대로 학습되지 못한 개체명 등이 있는데 주로 원소이름이나 외국 인명, 지명을 나타내는 외래어, 한자어 등에서 발생했다. 이를 해결하기 위해 직접 이들 단어를 사전에 추가해 보거나 해당 단어와 비슷한 도메인의 데이터를 가져와 추가학습은 어떻게 시키는건지 궁금하기도 하다.


다행히 프로젝트 결과는 나쁘지 않았는데 데이터셋은 다르지만 KLUE (Korean Language Undertanding Evaluation)가 자신들의 벤치마크 데이터로 진행하고 공개한 NER 태스크의 Entity F1 최고 점수가 85점이다. 우리가 모델을 훈련시켜 테스트셋에 적용해 얻는 최고 점수는 86점으로 아무래도 KLUE의 벤치마크 데이터셋이 3만 문장인데 비해 우리는 약 35만 문장으로 데이터셋 규모가 큰 것이 성능이 잘 나온 이유가 아닐까 생각한다. 보다 자세한 내용이 궁금하신 분들은 팀 깃허브도 한 번 방문해 보시면 좋을 것 같다.   



엔딩 크레딧


혼자 했다면 이런 좋은 결과를 얻지 못했을 것이다. 머신러닝 딥러닝 강사님이시자 우리에게 GPU를 허락해 주신 김용담 강사님, 온라인 강의만 들었지만 개인적으로 NLP계 백종원(?) 샘이라 생각하는 김기현 강사님, 우리들의 노력을 좋게 평가해주신 심사위원님들, 그리고 같이 좋은 결과를 이뤄낸 소현님, 동재님, 영환님께 감사합니다!


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari