상세 컨텐츠

본문 제목

코퍼스 분석용 SQL도구 KorpuSQL 개발!

프로그래밍

by ∫2tdt=t²+c 2016. 1. 27. 03:16

본문

예전에 국어정보학 수업 들었을때 코퍼스로 빈도 분석하는 것을 용이하게 하려고 Counter++를 개발했던 적이 있었습니다. 벌써 2년도 넘게 된일이죠. 이 프로그램을 통해서 연어 빈도를 매우 간편하게 조사할 수 있었습니다. 덕분에 국어정보학 과제를 하는데 큰 도움이 됐었지요. 하지만 이걸 짜던 당시에도 과연 이 프로그램이 연어 빈도 이상의 분석을 하는데 유용하게 쓰일수 있을지에 대해 회의가 많았습니다. 일단 파이썬이나 기타 스크립트 언어가 아닌 네이티브 C로 작성했는데도 생각처럼 빠른 속도가 나오지 않았고(환경에 따라 300만 어절 검색하는데 몇십초에서 몇분이 걸리기도 할 정도였습니다.), 단순히 한 행의 문자열을 정규식 비교를 통해 골라내서 앞뒤 행을 골라내는거라 복잡한 조건을 주고 검색하는것이 불가능했기 때문입니다. 그래도 기존의 텍스트 에디터랑 단순 빈도 계수기 정도보다는 낫지 않냐고 위로하면서 개발을 마무리짓고, 오래지 않아 입대를 해버렸습니다.


군생활 도중에도 문득 코퍼스 생각이 떠올라 코퍼스 분석을 좀더 확장성 있고 빠르게 수행할 방법에 대해서 종종 고민해보았습니다. 이때 생각났던 것은 페이스북이 지원하던 FQL이었습니다. SQL과 비슷한 형식의 문법으로 페이스북 내부의 각종 자료들을 깔끔하게 가져올수 있는 유저 API. 코퍼스를 처리할때도 이런 질의문 같은게 있으면 편리하지 않을까 생각해서 SQL과 비슷하게 코퍼스용 질의문을 구성해보곤 했습니다.

스케치 엔진에서 https://www.sketchengine.co.uk/corpus-querying/ 코퍼스 쿼리문을 지원한다길래 한 번 살펴보기도 했으나 제가 기대했던것만큼 확장성이 있는 것은 아니었습니다.


그래서 몇달전까지만 해도 SQL과 유사한 KQL을 정의하고, 그것을 해석하고 실행하는 가벼운 데이터베이스 시스템을 만들어야겠다는 겁없는 생각을 가지고 있었습니다. 빠르고 확장성 있게 코퍼스 분석을 실시하려면 이를 개발하는 것 말고 다른 방법이 없다고 판단했기 때문이었습니다. 그런데 크롤러와 검색엔진을 작성해보면서 SQL이란 놈이 단순히 INSERT INTO하고 SELECT해서 자료를 읽고 쓰는것뿐만 아니라, 쿼리 안에 쿼리를 넣고, 테이블끼리 조인하고 유니온하면서 복잡다단한 연산을 수행할수 있는 막강한 기능을 가졌고, 이미 수많은 개발자들에 의해 검증되고 안정적이며 속도도 최적화된 데이터베이스를 가졌다는 것을 깨달았습니다. 사실, 이미 검색엔진들에서 쓰이고 있는 기술이 코퍼스 분석하는데 쓰이는 것과 거의 같은 기술이라는 것도 덤으로 자연스레 알게되었습니다. 

그렇다면 굳이 있는 바퀴를 또 만들 필요는 없겠다. 이미 만들어진 바퀴를 코퍼스 분석용 툴에 달아주는게 훨씬 낫겠다.

해서 방향을 급선회해서, CSV로 이루어진 코퍼스 데이터들을 고급진 데이터베이스로 바꿔주고, 이 데이터베이스에 적절히 쿼리를 날려서 빈도 분석 등의 작업을 수행할 수 있게 해주는 프로그램을 짜기로 했습니다. 많고 많은 데이터베이스 시스템이 있지만, 지금 제 서버에는 MariaDB가 깔려있고, 내장 DB로 사용할 수 있는 디비에는 SQLite이 있었습니다. 그래서 둘을 모두 지원하는 프로그램을 작성하기로 했죠. 외부 디비를 연결해서 쓸수 있게하면 제가 프로그램 단에서 발버둥치지 않아도 성능 좋은 디비를 연결하면 자연스럽게 분석툴 전체의 성능이 올라가니깐요.


프로젝트 이름은 KorpuSQLCorpus + SQL의 합친 표현인데, 앞의 C를 K로 바꾸었습니다. 일단은 한국어(Korean)용으로 개발했으니까요.


사실 코어부분 개발은 하루만에 끝났습니다. 코어부분이라고 해봤자 기존의 텍스트로 된 코퍼스 데이터 파일들을 파싱해서 SQL을 이용해서 데이터베이스에 넣어주는거랑, 데이터베이스에 들어간 코퍼스 데이터들을 SQL을 이용해서 적절하게 가져오는게 전부였으니까요. SQLite와 MySQL을 추상화해서 관리하는 클래스를 작성함으로써 사용자 입맛에 따라 양쪽 디비를 모두 활용할 수 있게 했습니다. (역시 표준화의 힘. DB간 SQL문법이 약간씩 달라서 손봐야했지만 그래도 이정도면 양반입니다.)

태깅 코퍼스 파일은 한 줄에 한 어절 양식으로 작성된 것만 가져올 수 있습니다. 다른 양식의 태깅 코퍼스 입력도 필요하다면 업데이트를 통해 추가하도록 하지요.


문제는 UI, UI는 만악의 근원이었습니다. 처음에는 MFC 같은 무거운건 피하고자 그냥 Win32로 깔짝깔짝 개발하다가, 너무 귀찮아서 때려치우고 MFC로 UI를 다시 짰는데, 짜다보니 이건 너무 쓸데 없이 복잡해지는거 같아서 아예 싹다 날려버렸습니다. 그래서 중단하고 웹에서 KorpuSQL을 돌릴 수 있는 XE용 위젯을 개발했습니다. 그리고 이 MFC에서 제공하는 HTM 다이얼로그 기능을 활용해서 HTML/CSS/JS코드를 재활용했습니다. (UI 코딩은 HTML/CSS만큼 편한게 없는거 같아요.) 이 작업에 3일이 걸렸네요. 아무튼 길고 긴 시간을 보내고 KorpuSQL을 드디어 공개하게 되었습니다.




내장 DB로 연결할 경우 SQLite를 통해서 데이터베이스를 운용하게 됩니다. 메모리 용량이 가능한 경우 디비를 메모리에 올려놓고 쓸수 있는데, 이 경우 속도가 어마무시하게 빨라집니다. 또한 외부 MySQL 서버에 연결해서 사용할 수도 있습니다.



코퍼스 연구를 하는 사람중 많은 수가 SQL을 잘 모르기 때문에 SQL을 자동으로 작성할 수 있는 템플릿을 넣었습니다. 일단 제가 생각해봤을때 코퍼스를 가지고 유용하게 쓸만한 경우 몇가지를 뽑아서 템플릿화했는데, 실제로 코퍼스 관련쪽에 계신 분들이 어떤 기능을 필요로할지는 잘 모르겠네요. 요구사항이 있으면 바로 추가해서 템플릿 업데이트가 가능합니다.


현재 입력된 템플릿 목록 (굵게 표시된 부분은 1.1버전에서 추가된 것입니다.)


단어/형태소 통계

단어/형태소의 문헌 빈도

특정 형태소를 포함하는 단어 통계

특정 형태소 주위에 나타나는 형태소 통계

특정 단어 주위에 나타나는 단어 통계

특정 형태소 주위에 나타나는 단어 통계

특정 형태소가 포함된 단어 내의 형태소 통계

특정 단어/형태소가 포함된 예문 추출

여러 단어/형태소가 포함된 예문 추출

모든 문서 내 단어 당 평균 형태소 갯수

문서 종류별 문장 내 평균 단어 갯수

특정 단어가 어떤 단어와 가장 많이 같은 문장 내에서 등장하는지

특정 형태소가 어떤 형태소와 가장 많이 같은 문장 내에서 등장하는지


SQL과 HTML/CSS로 개발되었기때문에 웹으로 올리는 것도 어렵지 않았습니다. 코어부분만 약간 손봐서 PHP로 고치면 되었거든요. 그래서 동일한 기능의 웹 서비스도 제공합니다. http://lab.bab2min.pe.kr/KorpuSQLWeb


(버전1.1) 원시 코퍼스를 입력하면 형태소 분석기와 연동하여 자동으로 코퍼스를 구축해주는 기능이 추가되었습니다.

이제 Komoran과 꼬꼬마 형태소분석기가 연동됩니다. 연동 추가기능을 사용하시려면 Java Runtime 1.6 이상이 설치되어있어야합니다. 자세한 것은 이 글을 참조해주시길 바랍니다.

KSQL-1.1.z01

KSQL-1.1.z02

KSQL-1.1.zip




300만어절 태깅된 데이터베이스 파일도 공유합니다. 다운받아서 압축풀면, KorpuSQL에서 바로 가져와서 사용할 수 있는 버전입니다.

https://drive.google.com/file/d/0B6tFWSUsa0BpNGsxSjdMVzh5MGM/view

관련글 더보기

댓글 영역