논문을 많이 읽다보니 전공 분야에 관해 영어로 된 글은 별 어려움이 없이 읽을 수 있다. 그러다가 간혹 영화나 드라마에서 "this ~ is based on a true story" 라는 문구를 보면, 원래 이야기가 무엇이었나 궁금해서 참을 수가 없게 된다. 하지만 관련 원서를 구해 읽으면, 거의 첫 페이지 부터 내가 잘 모르는 표현이 어마어마하게 많이 나와서, 참을 수 없던 마음이 다시 사라진다. 그래서 소설에서 등장하는 단어 중에 내가 모르는 단어는 미리 외워두면 좋지 않을까 하는 마음에 오랜만에 워드 카운트를 만들어서 외울 단어를 찾아보려고 한다.

 

이 글에서는 파이썬을 이용하여 epub 형태로 된 문서에서 단어를 추출하고, 각 단어마다 출현하는 빈도 수를 세는 방법, 그리고 영어 사전을 이용하여 단어 뜻을 찾는 방법을 구현해볼 것이다.

 

실습은 Project Gutenberg 에서 무료 공개하는 책 중에서 Alice's Adventures in Wonderland (https://www.gutenberg.org/ebooks/11)를 가지고 한다. 링크를 따라가면 EPUB (no images)를 받아서 코드를 따라 구현해볼 수 있다.

 

파일과 디렉토리 구조는 아래와 같이 만들었다. 다운로드 받은 epub 파일은 data 디렉토리 안에 alice.epub 이라는 이름으로 저장하였다.

 

 

 

 

 

파이썬에서 epub 파일을 읽어오려면 ebooklib(https://github.com/aerkalov/ebooklib)을 설치해야하고, Beautiful Soup 4(https://pypi.org/project/beautifulsoup4/)를 사용한다. ebooklib 을 설치하려면 링크에서 git clone 으로 깃헙 저장소 파일을 다운로드 받고, python setup.py install 명령어로 설치한다. Beautiful Soup 은 pip install beautifulsoup4 명령어로 설치하면 된다.

 

읽어온 문자열에는 그리 큰 의미가 없는 단어들도 있기 마련이다(예를 들어 i, my, me, a, the). 이를 stopword (https://bit.ly/3uBin3H)라고 한다. 그리고 동사도 원형으로 변형해주고, 숫자 같은 것들은 모두 제거해주기 위해서 Natural Language Toolkit (https://www.nltk.org/)과 정규 표현식을 이용한다.

 

또한 영어 사전에서 단어 뜻을 알아오려면 PyDictionary (https://pypi.org/project/PyDictionary/)를 이용하면 된다.

 

그 외에 numpy, matplotlib 을 추가로 설치하고 패키지를 불러온다.

 

 

 

 

글을 읽어올 때, 대소문자를 모두 소문자로 통일하고, 마침표나 쉼표 같은 걸 (구두점, punctuation 이라고 함) 모두 제거하기 위한 하이퍼파라미터를 지정해준다. 혹시 대문자와 구두점을 유지하고 싶은 경우 이 값을 각각 False 로 바꿔주면 된다.

 

 

 

 

 

epub 을 읽어오면 bytes 자료형으로 챕터 내용을 각각 읽어올 수 있다. print 함수로 출력해보면, html 형식으로 되어있는 데, 이걸 BeautifulSoup 을 이용해 우리가 읽기 편한 형태로 변환해줄 것이다. 이걸 수행할 함수를 하나 짜준다.

 

 

 

 

이제 epub 파일을 읽어온다. 읽어올 때는 epub 의 read_epub 메쏘드 안에 읽어올 파일의 경로를 넣어주면 된다. 그렇게 해서 생성한  ebooklib.epub.EpubBook 클래스를 아래 2번 라인과 같은 코드로 챕터별로 내용을 읽어와 리스트에 저장한다. 저장한 데이터는 위에서 만들어 둔 함수를 이용해 문자열 형태로 변환하고, 소문자로 변환할지 말지에 따라 최종 문장 리스트(sentences)에 저장한다.

 

 

 

 

위에서 다룬 것 처럼 영어 단어에는 별 의미가 없는 단어들도 많다(stop words). 이걸 제거해주고, 또한 경우에 따라 문장의 구두점(punctuation)을 모두 제거해주고, 마지막으로 숫자를 모두 제거한다. 그리고 복수 단어는 단수로 변환하고, 동사는 원형으로 가져오고자 했다(이러한 행위를 lemmatization 이라고 함).

 

 

 

그러면 이제 책에서 등장하는 단어의 빈도를 확인 해볼 준비가 어느 정도 되었다. 이제 numpy 를 이용하여, 단어의 등장 빈도수를 세어본다. 그리고, 단어마다 등장하는 횟수를 딕셔너리에 넣어준다. 즉, 키:값=단어:빈도수. 역으로 빈도수 별로 단어도 딕셔너리에 넣어준다. 즉, 빈도수:단어리스트.

 

 

 

단어 출현 빈도를 히스토그램으로 그려보고 싶다면, 아래와 같은 코드를 이용한다. 반복해서 출현하는 단어가 훨씬 적기 때문에 아래 그림과 같은 형태로 나타난다. 적게 출현한 단어 개수가 너무 많기 때문에 세로 축의 크기를 최대 100으로 제한했다.

 

 

 

 

출현 빈도 별로 단어를 확인해보면, 출현 빈도가 높은 단어는 우리가 뜻을 알고 있는 경우가 많다. 그래서 이 예제에서는 출현 빈도가 1인 단어만 확인해보았다. 영어사전은 PyDictionary 를 이용한다. 영어 사전에 뜻이 있다면, 이를 품사와 품사별 뜻을 딕셔너리 형태로 반환해준다. 화면 출력은 보기 좋게 하기 위해 굳이 pprint 로 했다. PyDictionary 는 Princeton 대학 서버에 있는 온라인 사전 wordnet에서 검색해오기 때문에 인터넷이 연결 되어 있어야하고, 그래서 단어 검색해오는 시간이 좀 걸린다. 많은 단어를 검색하려면 시간을 넉넉히 두고 해야 한다. 참고로 아래 세 단어 검색에는 약 4-5초 정도 걸린다. 

 

 

 

주피터랩에서 출력결과는 아래와 같다. 단어는 무작위로 고르도록 했으므로 다른 단어가 나타날 수 있다.

 

 

뜻을 아는지 모르는지는 단어 공부를 하고 싶은 사람이 보고 직접 확인해야한다.

 

학습 해두면 좋은 단어를 자동으로 추출하고 싶다면, 다른 책으로부터 inverse document frequency (https://en.wikipedia.org/wiki/Tf%E2%80%93idf) 까지 확인해서 출현 빈도와 외워두면 좋을 단어 관계를 정하는 게 좋을 것이다. 또한 영한사전 검색 결과를 얻고 싶다면 영한사전 API 를 사용해야한다. 이 글에서,  이 두 가지에 관한 내용은 생략한다.

Posted by 공돌이pooh

댓글을 달아 주세요