TextRank를 이용한 문서요약
이번 포스팅은 구글의 PageRank를 Text에 적용시킨 TextRank 알고리즘에 대한 내용이다. TextRank 알고리즘을 알아본 후 다음 포스팅에서 TextRank를 이용하여 문서를 요약해주는 시스템 구현을 포스팅할 예정이다.
TextRank 란?
TextRank는 Mihalcea(2004)이 제안한 알고리즘으로 텍스트에 관한 graph-based ranking model 로써, Google의 PageRank를 활용한 알고리즘이다. PageRank는Brin and Page(1998)이 제안한 알고리즘으로 하이퍼링크를 가지는 웹 문서에 상대적 중요도에 따라 가중치를 부여하는 방법이다. 서로간의 인용과 참조로 연결된 임의의 묶음에 적용할 수 있다.(wikipedia) PageRank가 높은 웹페이지는 다른 웹 사이트로 부터 링크를 받는다 즉 다른 사이트가 참조를 많이한것으로 해석할 수 있다. 예를 들어, 아래 그림의 Page A
의 PageRank는 B,C,D 각각의 PageRank
(damping factor
로 웹 서핑을 하는 사람이 해당 페이지를 만족하지 못하고 다른 페이지로 가는 링크를 클릭할 확률이다. PageRnak의 자세한 내용은 조성문님의 블로그에서 확인할 수 있다.
[그림 1] PageRank 예시
이러한 PageRank
알고리즘을 활용한 것이 바로 TextRank
이다. TextRank
는 PageRank
의 중요도가 높은 웹 사이트는 다른 많은 사이트로 부터 링크를 받는다는 점에 착안하여 문서 내의 문장(or 단어)를 이용하여 문장의 Ranking을 계산하는 알고리즘이다.
[그림 2] PageRank > TextRank 적용
TextRank 식은 아래와 같다.
TR(Vi) : 문장 또는 단어(V)i 에 대한 TextRank값wij : 문장 또는 단어i 와j 사이의 가중치d:dampingfactor , PageRank에서 웹 서핑을 하는 사람이 해당 페이지를 만족하지 못하고 다른페이지로 이동하는 확률로써, TextRank에서도 그 값을 그대로 사용(0.85로 설정)- TextRank
TR(Vi) 를 계산 한 뒤 높은 순으로 정렬
TextRank 구현 해보기
TextRank를 적용하여 문서를 요약해주는 시스템을 구현 해본다. 전체 프로세스는 아래 그림3 과 같다.
Step 0. 필요한 패키지 설치하기
- Newspaper: 사용자가 입력한
url
에서 text를 크롤링 해주는 패키지이다. 자세한 내용은 Newspaper모듈을 이용하여 뉴스 기사 크롤링하기에서 확인 할 수 있다.
- python 3 :
pip install newspaper3k
- python 2 :
pip install newspaper
- KoNLPy: 한글형태소 분석기로 TextRank를 적용하기 위한 전처리 과정으로 사용된다. Python에 KoNLPy 설치 및 예제 실행에서 확인할 수 있다.
KoNLPy
를 설치하기 위해서는JPype1
을 설치해야한다.
- JPype1 설치:
pip install jpype1
- KoNLPy 설치:
pip install konlpy
- Scikit-learn: Python의 대표적인 머신러닝 패키지 중 하나로
TF-IDF
모델을 생성하는데 사용한다.
- scikit-learn 설치:
pip install scikit-learn
이제 문서 요약 시스템을 구현하기 위해 필요한 패키지 설치가 끝났다. 이제 각 세부 프로세스와 소스코드를 알아보도록 하자.
Step 1. 문서 타입에 따른 문장 단위로 분리하기(텍스트 크롤링 > 문장 단위 분리 > 명사 추출)
- 텍스트 크롤링
현재, 구현하고자 하는문서요약시스템
은 사용자가 입력값을url
혹은text
2가지로 입력할 수 있게 구현할 것이다. 사용자가 url을 입력했을 때,Step 0
에서 설치한 newspaper 패키지를 이용하여 text를 크롤링한다. - 문장 단위 분리
문장 단위로 분리하기 위해 여러가지 방법을 생각하던 중KoNLPy
중꼬꼬마(Kkma) 분석기
함수 중 문장을 추출하는sentences()
라는 함수를 이용하여 문장을 분리한다. - 명사 추출(POS-Tagging)
TF-IDF 모델
을 만들기 위한 전처리 과정으로 문장으로 분리 한 뒤 문장을 형태소 단위로 나눈 후 품사 태깅을 통해 명사들만 추출한다.KoNLPy
중Twitter
를 이용하여 명사를 추출해 준다.
<SentenceTokenizer Class>
[텍스트 크롤링, 문장 단위 분리, 명사 추출] 과정을 SentenceTokenizer
클래스로 만들었다.
- 아래의 코드에서
stopwords
는 불용어로써 문장 내에서 내용을 나타내는데 의미를 가지지 않는 단어들의 집합을 의미한다. stopwords는 사용 목적에 맞게 적절히 추가, 삭제를 해주면 된다. - url2sentences(url) : url 주소를 받아 기사내용(article.text)을 추출하여 Kkma.sentences()를 이용하여 문장단위로 나누어 준 후 senteces를 return 해 준다.
- text2sentences(text) : text(str)를 입력받아 Kkma.sentences()를 이용하여 문장단위로 나누어 준 후 senteces를 return 해 준다.
- get_nouns(sentences) : sentences를 받아 Twitter.nouns()를 이용하여 명사를 추출한 뒤 nouns를 return해 준다.
Step 2. TF-IDF 모델 생성 및 그래프 생성
- TF-IDF
TF-IDF(Term Frequency - Inverse Document Frequency)는 정보 검색(Information Retrieval)과 텍스트 마이닝에서 사용하는 단어의 상대적인 가중치이다. 여러 문서로 이루어진 문서 군이 있을 때 어떤 단어가 특정 문서 내에서 얼마나 중요한 것인지를 나타내는 통계적 수치이다. 자세한 내용은 Wikipedia에서 확인할 수 있다.
- TF(Term Frequency) : 단어 빈도, 특정 단어가 문서 내에 얼만큼의 빈도로 등장하는지를 나타내는 척도
- IDF(Inverse Document Frequency) : 역문헌 빈도수, 문서 빈도의 역수로써 전체 문서 개수를 해당 단어가 포함된 문서의 개수로 나눈 것을 의미한다.
- TF-IDF 식 :
Wi,j=tfi,j×log(N/dfi)
TF-IDF를 계산하기 위해 Python의 머신러닝 패키지인 Scikit-learn을 이용하여 TF-IDF모델링을 수행한다. TF-IDF를 구하고 난 뒤 그래프를 생성하기 위해 Sentence - Term Matrix(원래는 Document-Term Matrix)를 아래의 그림4 처럼 생성한다.
[그림 4] Sentence-Term Matrix 생성
- 그래프 생성
Sentence-Term Matrix
를 이용하여 전치행렬을 구한뒤 서로 곱해준다. 즉, Correlation Matrix 를 생성한다. 이렇게 생성한Correlation Matrix
를 Graph의 Adjancey Matrix로 생각해 줄 수 있다. (Correlation Matrix의 대각행렬 원소 1을 0으로 치환 해줘야함) 따라서, 아래 그림5 처럼Correlation Matrix
를 통해 문장(or 단어) 간의 가중치 그래프(Weighted graph)로 나타낼 수 있다.
[그림 5] Correlation Matrix를 이용한 가중치 그래프 생성
<GrpahMatrix Class>
[TF-IDF 모델, 그래프 생성] 과정을 GraphMatrix
클래스로 구현했다.
- build_sent_graph(sentence) : 명사로 이루어진 문장을 입력받아 sklearn의 TfidfVectorizer.fit_transform을 이용하여 tfidf matrix를 만든 후 Sentence graph를 return 한다.
- build_words_grahp(sentnece) : 명사로 이루어진 문장을 입력받아 sklearn의 CountVectorizer.fit_transform을 이용하여 matrix를 만든 후 word graph와 {idx: word}형태의 dictionary를 return한다.
Step 3. TextRank 알고리즘 적용
이제 드디어, TextRank 알고리즘을 구현하는 단계이다.
앞에서 생성된 문장(or 단어)의 가중치 그래프를 이용하여 TextRank 알고리즘을 적용한다. TextRank 알고리즘을 통해 Ranking값이 높은 순으로 정렬한 뒤 요약할 문장(or 단어)의 개수 만큼 출력 해준다.
<Rank class>
TextRank 알고리즘을 구현한 클래스이다.
- get_ranks(graph): 위의 식을 구현한 부분이며, {idx : rank 값} 형태의 dictionary를 return 한다.
- spookyQubit/TextRank 를 참고함
Step 4. TextRank Class 구현
Step1 ~ Step3
까지의 클래스를 조합하여 TextRank 클래스를 구현했다. 사용자는 이 TextRank class를 이용하여 문서의 요약 또는 키워드들을 확인한다.
- summarize(sent_num=3): Default로 3줄 요약 가능하게 구현했다.
- keywords(word_num=10): Default로 10개의 키워드를 출력하도록 구현했다.
Step 5. 결과 확인
결과 확인을 위해 [다음 뉴스]에서월급쟁이 65%, 신용카드 소득공제 못받는다 기사를 요약해보자.
◇ 연 봉 5000만원 대가 84% 로 카드 공제 가장 많이 받아 신용카드 소득 공제를 받으려면 총소득의 4분의 1 이상을 카드로 써야 한다. 2015년 기준으로 근로 소득세를 내는 사람 중에서 카드 소득 공제를 받는 비율이 가장 많은 소득 구간은 연봉 5000만 ~6000 만원이었다. 연봉 4000만원 대는 81%, 3000만원 대는 73%, 2000만원 대는 55% 만 카드 소득 공제를 받은 것으로 나타났다. keywords : ['소득', '공제', '카드', '사람', '사용', '한도', '만원', '신용카드', '경우', '문턱']
이상으로 TextRank를 직접 구현하여 문서요약시스템
을 만들어 보았다. 전처리 과정에서 불용어 처리나, 품사태깅에 대한 부족한 부분이 있지만 직접 구현해보는것 자체가 큰 의미가 있는거 같다. 현재 gensim을 비롯한 다양한 패키지들이 TextRank알고리즘을 활용하여 문서를 요약해주고 있다. 역시 코딩은 있는거 잘 가져다 쓰는 것이 최고인거 같다.