Project

[Project]한국 뉴스 토픽 모델링 (feat. KoBERTopic)

moonzoo 2023. 2. 14. 14:10

INTRO

https://mz-moonzoo.tistory.com/23

 

[Project]해외 뉴스 토픽 모델링 (feat. BERTopic)

INTRO 트렌드를 따라가기 위해 많은 사람들이 뉴스를 봅니다. 하지만 하루만해도 수백 수천개의 뉴스가 올라오고 그 중 어떤 뉴스가 중요한 뉴스인지 파악하기는 쉽지 않습니다. 한국 뉴스를 통

mz-moonzoo.tistory.com

트렌드를 따라가기 위해 많은 사람들이 뉴스를 봅니다.

하지만 하루만해도 수백 수천개의 뉴스가 올라오고 그 중 어떤 뉴스가 중요한 뉴스인지 파악하기는 쉽지 않습니다.

수백 수천개의 뉴스 기사내에서 비슷한 주제별로 묶어서 핫한 주간, 월간 뉴스를 쉽게 파악해보고자 합니다.

 

사실 전체적인 흐름은 이전 글 해외 뉴스 토픽 모델링과 비슷합니다.

하지만 언어가 달라진 만큼 수정해야할 부분이 많이 있어서 글을 작성해보고자 합니다.

 

BERTopic

  • Topic Modeling 기법 중 하나입니다.
  • BERT 기반 Embedding + Class-based TF-IDF를 사용한 것이 아이디어의 핵심입니다.

구조

BERTopic의 구조는 크게 세 단계로 볼 수 있습니다.

1. BERT를 이용해서 각 Document에 대해서 Embedding을 합니다.

2. UMAP을 이용해서 각 Document Vector의 차원을 축소합니다.

3. HDBSCAN을 이용해서 클러스터링을 합니다.

이 때 Clustering을 통해서 각 Document Vector에 대해서 유사한 Document끼리 묶어주는 과정을 진행합니다.

 

그 다음에 C-TF-IDF를 통해서 각 묶어진 그룹(Topic 또는 Class)에 대해 해당 Topic을 잘 표현하는 단어를 찾습니다.

마지막으로 Maximize Candidate Relevance Algorithm을 이용해서 적절히 Topic을 대표하는 Keyword들이 최대한 다양하게 선별되도록 조정합니다. Document, Word Embedding Vector에 대해서 Similarity를 계산해서 Keyword List를 Return 합니다.

 

데이터 수집

데이터 수집 사이트 : 빅카인즈

 

사실 데이터를 직접 수집하는 것도 해외 뉴스처럼 크롤링 코드를 구현하면 쉽게 가능한데 한국 뉴스의 경우 공유된 크롤링 코드도 많을뿐더러 빅카인즈 처럼 손쉽게 뉴스 데이터를 가져올 수 있는 사이트가 있기 때문에 빠른 실습을 위해 빅카인즈에서 뉴스 데이터를 가져왔습니다.

가져온 뉴스 데이터의 분류는 경제입니다. 경제 뉴스로 분류된 17331건을 다운로드해 실습에 활용했습니다.

데이터 전처리

1. 한국 뉴스 원본 데이터

빅카인즈에서 가져온 2023.02.07~2023.02.14 뉴스기사 데이터 입니다.

해외 뉴스기사 데이터와 마찬가지로 몇 가지 전처리를 진행해보도록 하겠습니다.

 

2. 한국 뉴스 데이터 전처리

drop_duplicates함수를 사용해 본문을 기준으로 중복된 행을 제거 해줬습니다.

수집한 데이터에 결측치가 존재하지 않으므로 결측치 제거는 진행하지 않았습니다.

 

다음으로 뉴스 기사와 제목의 텍스트 전처리를 진행해보도록 하겠습니다.

뉴스 기사와 제목에는 특수문자와 공백이 2칸 이상 등 전처리가 필요한 부분들이 있습니다. 이를 제거하는 것이 좋으므로

re 라이브러리와 정규 표현식을 사용해 제거해주도록 하겠습니다.

[^A-Za-z0-9가-힣] -> 한글, 영어, 숫자만을 포함한다는 의미입니다.

' + ' -> 공백이 2개 이상인 모든 것들을 의미합니다.

이제 저 두 조건을 만족하지 않는 것들을 re.sub 함수를 통해 각 행의 뉴스마다 apply 함수를 이용해 제거해줍니다.

해외 뉴스와 마찬가지로 날짜 컬럼은 datetime로 변환해주시고 사용하는 것이 여러모로 편리하기 때문에

데이터 타입을 datetime으로 변환해줍니다.

그러면 이렇게 본문이 중복된 행 약 500건이 제거가 되고 제목과 본문에 불필요한 이모티콘과 공백들이 제거 됐습니다.

이 뉴스 데이터의 경우 빅카인즈에서 데이터를 가져올 때 이미 날짜를 1주일치만 가져왔기 때문에 따로 날짜 필터링은 진행하지 않고 실습에 사용하도록 하겠습니다.

 

그리고 마지막으로 본문에 빈 문자열이거나 숫자로만 이루어진 줄은 제거해주고 텍스트를 리스트에 append 해줬습니다.

 

3. Custom 불용어 사전

단어 빈도수가 높은데 중요하지 않은 단어와 일반적으로 자주 사용되는 단어를 합쳐서 불용어 사전을 만들었습니다.

한나눔 토크나이저 사용해서 토큰화 한 뒤 단어 빈도수가 상위 200 안에 드는 단어들을 기준으로 불용어 선택

  • 자주 사용되는 불용어 링크 : https://www.ranks.nl/stopwords/korean
  • 추가로 몇가지 불용어 리스트를 직접 다운받아오고 너무 많이 나오는 단어를 제거해줬습니다.

stopwords (1).txt
0.01MB

형태소 분석 모델 세팅 (Spacy)

다양한 형태소 분석 모델들이 존재하는데 저는 Spacy를 사용했습니다

1. 형태소 분석 모델 다운로드

처음 spacy를 설치했다면 spacy의 형태소 분석 모델을 다운로드 하도록 합니다.

여기서 모델의 크기마다 sm, md, lg가 있습니다. en버전과 다르게 trf 모델은 없습니다.

저는 여기서 모델의 크기는 크지만 가장 잘 나온다고 생각한 ko_core_news_lg를 사용했습니다.

하지만 속도가 비교적 느리고 sm, md 모두 성능은 비슷하므로 여건에 맞게 사용하시면 될 것 같습니다.

2. 형태소 분석 모델 세팅

앞서 spacy 모델의 다운로드를 진행했다면 spacy.load를 통해 다운로드한 모델을 불러오도록 합니다.

해외 뉴스와 마찬가지로 customizing tokenizer를 사용했습니다.

영어와 다르게 한국어의 경우 좀 더 많이 복잡합니다... lemma(표제어)만 해도 차이가 큽니다. 

한국어 표제어를 추출하면 ~~~+다, ~~~+ㄴ 이런식으로 나오게 되는데 이러한 것들을 전처리 해줄 필요가 있습니다.

그렇게 token의 표제어와 tag를 따로 추출해서 명사인 것들만 뽑아주도록 합니다.

ncn,ncpa,ncps 등등 tag가 엄청 복잡하니 무엇을 의미하는지 하나하나 직접 찾아보시는 것도.. 나쁘지 않을 것 같습니다.

 

그리고 TfidfVectorizer로 직접 custom한 불용어 사전을 사용해 BOW를 생성해주도록 합니다. 

ngram_range(1,2)로 할 경우 비슷한 의미의 단어가 줄지어 나와서 (1,1)로 설정해줬습니다.

 

직접 해보시면서 자신의 task에 가장 잘 맞는 파라미터를 찾으시는 것을 추천 드립니다.

 

BERTopic 모델 실행

이런식으로 간단하게 모델을 사용할수도 있습니다.

이미 default값으로 파라미터 세팅이 잘 돼있기 때문에 그대로 사용하셔도 괜찮은 성능을 보입니다.

1. customizing BERTopic

맨 처음 BERTopic구조의 embedding model부터 umap model, hdbscan model 모두 직접 파라미터를 세팅할 수 있습니다.

가끔 문서의 수가 너무 적을 경우 직접 파라미터를 조정할 필요가 있어서 저는 상황에 맞게 따로 파라미터를 조정하면서 사용하고 있습니다. min_cluster_size의 default값은 5이지만 문서의 크기가 커서 10으로 조절해줬습니다.

umap_model의 metric 역시도 default값은 euclidean이지만 cosine이 저는 더 성능이 좋아서 사용하고 있습니다.

각자 테스트를 해보시고 마음에드는 결과가 나오는 값을 설정해주시면 될 것 같습니다.

 

embeddinng_model의 경우 다양한 SBERT모델이 있는데 우선 한국어 SBERT모델이 여의치않아서 영어 데이터로 학습된 SBERT인 "paraphrase-MiniLM-L6-v2"와 유사하지만 50개 이상의 언어로 학습된 다국어 SBERT "paraphrase-multilingual-MiniLM-L12-v2"를 사용했습니다.

https://maartengr.github.io/BERTopic/getting_started/embeddings/embeddings.html

 

여기서 외국 모델과 다른 점은 vectorizer_model을 여기서 넣어준 부분입니다.

외국 모델은 사후 전처리를 위해 모델의 output list를 뽑아낸 후 전처리를 진행해줬지만 한국 모델의 경우 

vectorizer모델을 BERTopic에 넣어서 한번에 처리를 진행했습니다.

별 차이는 없는데 사후 전처리가 좋을 수 있다는 글을보고 외국 모델은 그렇게 진행해본 것 입니다.

입맛에 맞게 해보시면 될 것 같습니다.

2. BERTopic fit_transform

이제 세팅한 BERTopic에 fit_transform을 이용해 뉴스의 기사나 제목을 넣어줍니다. (여기선 기사 본문을 넣어줬습니다.)

BERTopic 결과

문서 수가 너무 많아 시간이 오래걸려서 2월12일부터 2월14일까지 약 4900건의 뉴스 데이터로 토픽 모델링을 진행한 결과 입니다. 해외 모델과 유사하게 대충 무슨 내용인지 파악하실 수 있으시겠죠?

최근 chatgpt때문에 핫해진 3. 인공지능, 9.튀르키예 지진 이슈, 13. 하이브 sm 인수 등 큰 사건의 토픽들이 잡히는 것을 확인 할 수 있습니다.

 

13. 하이브 sm 인수 토픽의 상세 키워드 입니다.

해외 토픽 모델과 마찬가지로 모든 기능을 이용할 수 있으니 이전 글을 참고해서 시각화까지 진행해보시면 될 것같습니다.

 

마치며

KOBERTopic이라고 부르기도 하는데 확실히 한국어로 하려고하니 에러도 많이 보고 tokenizer을 custom하는게 좀 힘들었던 것 같습니다. 그리고 이걸 활용해서 여러가지 서비스를 할 수 있고  사실 더 많은 기능과 새로 추가된 기능들이 있는데 그거까지 다루면 스크롤이 너무 길어지고 제가 힘들거 같아서 여기까지 작성하도록 하겠습니다. 

저번 공모전에서 본 KR-WordRank를 활용한 팔로업 뉴스 추천을 본적이 있는데 그 부분을 다음 글에서 다뤄보도록 하겠습니다.

 

자세한 전체 코드는 깃허브 링크에서 참고하시면 됩니다.

https://github.com/moonjoo98/News_trend/tree/master/Topic%20modeling

 

GitHub - moonjoo98/News_trend: 국내 해외뉴스 토픽 모델링 및 감성분석(Tner + Finbert)

국내 해외뉴스 토픽 모델링 및 감성분석(Tner + Finbert). Contribute to moonjoo98/News_trend development by creating an account on GitHub.

github.com