본문 바로가기
아래아한글 자동화/python+hwp 중급

정부부처 보도자료에 필드가 적용되어 요약 언어모델 데이터셋 만들기 쉬워졌다

by 일코 2022. 9. 22.

과기정통부와 행안부 보도자료를 살펴보다가 재미있는 점을 두 가지 발견했습니다.

하나는, 보도자료에 machine-readable한 hwpx 포맷으로 바뀌어가고 있다는 점이며

다른 하나는 올해 초, 1월 말 경부터 한/글 문서에 필드와 누름틀이 매겨지고 있다는 점입니다.

 

이 두 가지는 항상 양질의 데이터에 배고픈 요즘 시대에

아주 큰 강점이 됩니다.

 

예를 들어보겠습니다.

1. 뉴스기사 크롤링할 때

얼마 전부터 KoGPT나 KoBART 등 한국어 대규모 언어모델이 개발되고 있는데, 학습데이터셋 대부분은 웹에 공개된 언론 뉴스기사나 위키자료 등이죠. 크롤링으로 대규모의 자료를 스크랩해오더라도 데이터셋의 전/후처리가 쉽지 않은데, 그 이유는 언론사마다 제각각인 시맨틱 태그, 맥락없이 중간중간 삽입된 사진설명, 광고 등의 정보로 인해 크롤링 자체도 쉽지 않지만 데이터를 정제하거나 품질을 끌어올리기가 여간해서는 쉽지 않습니다.

 

2. HWP 포맷의 보도자료에서 텍스트를 추출할 때

저도 얼마 전에 과기정통부 보도자료를 전부 다운받아 txt로 변환해서 모 회사에 제공해드린 적이 있었습니다. 언어모델 개발에 활용하기 위해서였던 것 같습니다. 저도 크롤링한 김에 보도자료를 뜯어보면서 문서 구조를 파악해봤는데, 아쉬운 점이 몇 가지 있었습니다.

우선 hwp파일 안에서 제목을 추출하기도 쉽지가 않았습니다. 기간에 따라 헤더 서식이 제각각이었기 때문인데요.

예를 들어 2012년 보도자료 중 하나는

2013년 보도자료 중 하나는

2015년 보도자료 중 하나는

이런 식으로 서식이 자꾸 바뀌었기 때문에

학습자료는 고사하고 일괄적으로 제목이나 본문을 추출하기도 벅찼습니다.

게다가, 본문내용과 큰 상관없는 붙임문서 텍스트를 삭제하는 코드도 작성할 수가 없었습니다.

왜냐년 어떤 담당자는 "붙임"으로, 어떤 담당자는 "참고자료"로,

또 어떤 담당자는 "첨부"라는 이름으로 표를 작성해놓은 상태라

붙임문서를 잘라낼 기준을 찾기도 너무 힘들었습니다. (결국 포기..)

 

그런데 올해 초부터 보도자료에 누름틀과 필드가 도입되었습니다. 이게 무슨 뜻이냐면

이제 코드 한 줄이면 제목이나 담당자, 본문 등을 바로 추출할 수 있게 된 겁니다.

한 번 보여드리겠습니다. 아래는 9월22일자 과기정통부 보도자료 중 하나입니다.

겉보기에는 별로 달라진 게 없고, 오히려 좀 수수해진 느낌인데?

얘를 파이썬으로 열여보겠습니다.

아래처럼 보도자료의 각 요소들을 누름틀과 필드로 접근할 수가 있게 되었습니다.

제목을 추출하는 것도 짧은 한 줄의 코드로 다 됩니다.

(모두 확인해본 건 아니지만) 과기정통부 뿐만 아니라 다른 부처 자료도 동일하게 누름틀이 적용되는 추세인 것 같습니다.

게다가 필드 이름도 거의 유사합니다. (완전히 통일되지는 않았고요ㅜ)

행안부 보도자료도 한 번 열어볼까요?

이렇게 문서 특정 구간구간에 라벨링이 되어 있어서, 원하는 정보만 취합하거나 추출하는 작업이 엄청나게 간편해졌습니다. 보도자료가 1만 건이든 10만 건이든 단순하고 일관된 코드로 정보를 얻을 수 있게 된 겁니다. 저만 뿌듯한가요ㅎㅎ

간단한 tsv만들기 예제를 보여드리겠습니다.

누름틀이 삽입된 최근 700여개의 과기정통부 보도자료에서

본문(붙임 제외)과 제목만 판다스 데이터프레임으로 추출해서

언어모델 학습 등에 자주 사용되는 tsv(tab-separated values) 포맷으로 변환하는 과정을 보여드리겠습니다.

 

보도자료는 미리 크롤링해서 아래와 같이 폴더 안에 저장해 두었습니다.

(크롤링 코드는 다음에 포스팅으로 공유하겠습니다.)

700여개의 보도자료

아래와 같이 실행해 판다스 데이터프레임을 생성합니다.

df = pd.DataFrame(columns=["content", "title"])
for idx, file in enumerate(filelist[:3]):
    hwp.Open(os.path.join(os.getcwd(), file), arg="versionwarning:False")
    content = hwp.GetFieldText("본문")
    if content:
        df = df.append({"content": content, "title": hwp.GetFieldText("제목명")}, ignore_index=True)
        print(f"[{idx+1}/{len(filelist)}]{hwp.GetFieldText('제목명')}")
    hwp.Run("FileClose")

15번 라인의 "versionwarning: False" 파라미터는, 상위버전 문서를 열 때 경고팝업이 뜨우지 않게 하는 명령입니다.

직접 한/글 문서를 열었다 닫았다 하는 작업이라 시간이 조금 걸리네요.

자, 추출이 완료되었습니다!

만들어진 데이터프레임을 확인해보겠습니다.

2022년 1월 이후에도 누름틀이 매겨져 있지 않은 보도자료가 150개 이상이긴 하네요..

거두절미하고 tsv로 변환해보겠습니다.

한 줄이면 되네요.

언어모델 관련한 데이터셋은 일반적으로 사용하는 CSV, comma-separated values가 아니라 TSV, tab-separated를 사용하는 이유는 무엇일까요?
아무래도 문자열 자료에는 온점이나 콤마가 많이 사용되다 보니,
문서 내에서 비교적 사용이 흔하지 않은 tab을 구분자로 사용하는 거 아닐까요?^^

성공적으로 저장되었는지 한 번 열어보고 마치겠습니다.

제 바탕화면에 잘 저장되었네요ㅎ

마치며

여기까지, 누름틀을 활용해 보도자료에서 간단하게 정보를 추출하고

tsv로 만들어 저장하는 과정까지 살펴보았습니다.

이번 포스팅은 여기서 마치겠습니다.

행복한 하루 되세요!

 

 

 

댓글