상세 컨텐츠

본문 제목

UTagger + KorpuSQL을 이용해서 코퍼스 구축하기

적분史

by ∫2tdt=t²+c 2016. 1. 28. 17:19

본문

KorpuSQL 다운로드는 아래 페이지에서 가능합니다.

2016/01/27 - [프로그래밍] - 코퍼스 분석용 SQL도구 KorpuSQL 개발!


KorpuSQL을 개발한게 간편한 코퍼스 구축을 위해서였죠. 구슬이 서 말이라도 꿰어야 보배인것처럼 코퍼스 처리 프로그램이 서 말이라도 직접 구축해보지 않으면 의미가 없어요. 그래서 한 번 코퍼스 구축을 해보기로 했습니다. 텍스트를 구하기가 가장 쉬운 방법이 뭐가 있을까 고민하다가, 한국어 위키백과의 문서들을 가져와서 코퍼스로 구축해보기로 했습니다. 일단 위키백과가 백과사전을 지향하는 위키 사이트이다보니, 다른 인터넷 페이지들과는 달리 어느 정도 검증된 표현을 사용하고, 구어나 인터넷에서 유행하는 이상한 말들보다는 표준어 문어체로 작성되어 있어서 이 친구를 고른 것이지요. 




자, 일단 목표를 설정했으니 방법을 강구해봅시다.




일단 한국어 위키백과의 모든 문서를 긁어와야하는데, 모든 문서 목록은 여기에서 볼 수 있습니다. 일단 Python을 이용해서 이 문서 목록을 가져오는일을 해보죠. 해당 페이지의 HTML소스코드를 살펴봅시다.




<span class="mw-htmlform-submit-buttons"> <input class="mw-htmlform-submit" type="submit" value="보기" /> </span> </fieldset> </form><div class="mw-allpages-nav">
<a href="/w/index.php?title=%ED%8A%B9%EC%88%98:%EB%AA%A8%EB%93%A0%EB%AC%B8%EC%84%9C&amp;from=.jar" title="특수:모든문서">
다음 문서 (.jar)</a></div><div class="mw-allpages-body"><ul class="mw-allpages-chunk">
<li class="allpagesredirect"><a href="/wiki/!" class="mw-redirect" title="!">!</a></li>
<li><a href="/wiki/!!" title="!!">!!</a></li> <li><a href="/wiki/!!!" title="!!!">!!!</a></li> <li class="allpagesredirect"><a href="/wiki/!%3F" class="mw-redirect" title="!?">!?</a></li> <li class="allpagesredirect"><a href="/wiki/!Democracia_Real_YA!" class="mw-redirect" title="!Democracia Real YA!">!Democracia Real YA!</a></li> <li><a href="/wiki/!_(%EB%8F%99%EC%9D%8C%EC%9D%B4%EC%9D%98)" title="! (동음이의)">! (동음이의)</a></li> <li><a href="/wiki/!_-attention-" title="! -attention-">! -attention-</a></li> <li class="allpagesredirect"><a href="/wiki/!%EC%BF%B5%EC%96%B4" class="mw-redirect" title="!쿵어">!쿵어</a></li>


앞뒤 자르고 중요한 부분만 가져왔습니다. 일단 문서 목록은 <ul class="mw-allpage-chunk"> 에서 시작됩니다. 끝나는 부분은 </ul>이겠죠. 정규식을 이용해서 이 사이에 있는 녀석들을 가져오면 목록은 구할 수 있겠죠. 그리고 보시면 class="mw-redirect" 로 리다이렉트 문서는 별도로 표시가 되어있습니다. 리다이렉트 문서 목록까지 다 가져오면 겹치는 문서가 생길테므로 이 녀석들은 제외하고 가져옵시다.

그리고 다음 페이지로 넘어가는 링크는 녹색으로 칠해진 부분에 있습니다. 친절하게도 다음 문서라고 써져있기까지 하네요. HTML소스에서 이 부분이 있으면 다음 페이지로 넘어가서 계속 파싱하고, 없으면 끝내는 것으로 코드를 작성하면 되겠습니다.


자 그럼 이제 코딩 시작해볼까요. 시간이 오래걸릴거 같아서 아저씨는 미리 만들어왔어요. 파이썬3용 코드입니다.



문서가 30만개가 넘다보니 목록만 가져오는데도 좀 시간이 걸립니다. 게임이나 하면서 잠시 기다려주세요.


목록을 모두 가져왔다면 본격적으로 페이지를 가져와봅시다. 한국어 위키백과 문서들의 HTML소스코드를 잘 들여다보면 일반적인 위키백과 페이지 문서의 본문은 <div id="mw-content-text" lang="ko" dir="ltr" class="mw-content-ltr"> 태그에서 시작해서 <div class="printfooter"> 태그 앞에서 끝난다는 것을 알수있습니다. 여기를 끄집어내온다음 각종 태그들은 지워버리면 문서 내 텍스트만 뽑아올 수 있겠죠! HTML 문서에서는 공백문자가 두 개 이상 등장해도 공백 한 칸으로만 해석합니다. (원래 약속이 그래요.) 그리고 몇몇 태그는 block속성을 지니고 있어서 그 태그가 끝나면 자동으로 줄(문단)이 바뀌죠. 그리고 위키백과의 특성상 문단마다 [편집]이라는 링크가 있는데 이 녀석들도 모두 지워버리지요. (그렇지 않으면 [편집]이 코퍼스내 빈도순위 1위 단어가 될겁니다.) 이 점을 고려해서 적절하게 텍스트를 뽑아봅시다. 역시나 아저씨는 미리 만들어왔어요.



이 함수를 실행하면 다음과 같은 결과를 얻을 수 있습니다. 예제로 사용한 페이지는 고대 한국어 페이지입니다.


음 잘 작동합니다. 이제 이 함수를 아까 만들어 저장했던 list.txt 목록 파일에 들어있는 모든 페이지에 대해서 수행해야 합니다. 이렇게 스크립트를 짜봅시다.


짠! 장담컨대 이 코드는 매우 잘 돌아가지만 하루종일 돌려도 프로그램이 안끝날 수 있습니다. 컴퓨터 속도가 느려서 그런게 아니라 웹페이지를 가져오는데 시간이 걸리기 때문입니다. 웹페이지를 가져올때까지 기다린다음 처리해서 저장하고, 또 다음 웹페이지를 가져올때까지 기다리고... 비효율적이죠. 쓰레드와 큐를 이용해서 여러 웹페이지를 가져오게 한다음 받은 웹페이지부터 처리하도록 수정해봅시다.



스레드 16개를 돌리며 웹페이지를 가져오게 수정했습니다. 이정도면 컴퓨터 놀리지 않고 웹 페이지를 가져올 수 있을겁니다. (스레드 숫자를 더 올려도 괜찮을거같은데, 위키백과 쪽에서 DDoS공격 같은걸로 오인해서 차단시켜버릴까봐 이 정도에서 만족하기로 했습니다.)


이렇게 밤새 돌리면 30만 페이지를 모두 가져올 수 있습니다. 다 가져왔다면? 바로 UTagger를 실행합시다.




UTagger 설정은 위와 같이 해줍니다. 파일 형태: [원시말뭉치], 출력 형식: [한줄에 한어절]




그리고 폴더 분석을 눌러서 우리가 긁어온 위키백과 문서들이 있는 doc 폴더를 골라줍니다.

문서가 많죠? 시간이 꽤 걸립니다. 이번엔 컴퓨터 켜놓고 식사하고 오시면 될듯합니다.


다 됐나요? 그러면 이제 KorpuSQL을 실행합시다. 이 프로그램은 태깅 코퍼스를 DB화하여 통계를 비롯한 각종 처리를 용이하게 도와줍니다.


[파일] - [데이터베이스 연결]



내장 DB로 [새로 만들기/열기...] 를 누릅니다.

외부 데이터베이스를 사용할 수도 있지만, 그럴려면 별도로 MySQL이나 MariaDB 등을 설치해야합니다. 컴퓨터 메모리만 풍족하다면 내장 DB를 메모리에 적재하고 사용하는게 가장 빠릅니다. (물론 외부 DB를 메모리 테이블로 만들어서 쓰는게 그것보다 빠르긴하지만 번거로우므로)



디비 생성이 완료되었다면 이제 태깅 코퍼스를 입력할 차례입니다.

[데이터베이스]-[태그 코퍼스 일괄 입력]을 누르세요



[패턴 추가]로 가져올 파일 목록을 추가할 수 있습니다. [파일 추가]로 여러 파일을 동시에 추가할 수도 있지만, 아시다시피 파일갯수가 30만개가 넘기 때문에 번거롭습니다. 인코딩은 EUC-KR로 선택해주세요.



태그 파일이 생성된 폴더의 경로를 적어주면 됩니다. [확인]을 누르면 디비 입력이 시작됩니다. 컴퓨터 사양에 따라 소요 시간이 달라지겠지만, 이번에는 차 한잔 하고 오시면 될거같습니다.


디비 입력이 끝나면, 이제 코퍼스 분석을 즐기면 됩니다. 코퍼스 전체 용량이 크다보니 쿼리 수행시간이 좀 걸리네요 더 단축시킬 방법 없는지 고민해봐야겠습니다.

관련글 더보기

댓글 영역