Deep Learning/NLP
11. Luhn Summerizer
해파리냉채무침
2023. 3. 30. 17:33
문서 요약이란 중요한 문장을 자동으로 추출하는 과정
중요한 문장을 추출한다 -> 문장의 중요성을 어떻게 판단?
추상적 요약
문서를 의미적으로 이해 , 의미 추출 하여 요약 생성
추출 요약
문장별 중요도 계산 , 순위 높은 문장 선택 , 기술의 난이도가 있음.
Luhn Summerize 이용한 문서 요약
단어의 중요도는 사용빈도로 측정, 작가는 중요한 단어를 반복한다.
중요 단어를 구분할 수 있는 구역을 C와 D로 표시 빈도수가 높다고 무조건 중요한 단어는
아님을 의미. 작성자가 많이 사용한 단어가 많은 문장이 중요한 문장이다
문장의 중요도
sentence 각 대쉬는 토큰을 의미함.
중요 단어가 시작하는 처음과 끝사이 단어들 중 중요단어의 상대 비율
문장 중요도 = (윈도내 포함된 중요단어 갯수)^2/ 윈도내 포함된 단어갯수
중요단어 결정 시 문서 내 단어빈도 비율 구간을 0.001초과 0.5미만으로 설정함.
이번 코드 따라하는데 뭔가 첫 데이터 부터 잘못된것 같다??
깃허브 복붙햇는데 데이터가 이상하게 나옴,,, 그냥 이상하게 나온 데이터로 했다
doc = '과기정통부, 22일 유영민 장관 등 참석해 기념행사 2021년까지 1516억원 투입, 5100여종 데이터 구축 민간 클라우드 통한 외부연계체계도.."개방성 강화" [이데일리 이재운 기자]'
이걸로 도큐먼트 데이서 설정했스므니다
import nltk
nltk.download('punkt')
#토큰화
from nltk.tokenize import sent_tokenize
from konlpy.tag import Okt
import MeCab
def get_sentences(txt) :
return sent_tokenize(txt)
def get_words(txt) : #단어목록리턴
mecab = MeCab
return [t[0] for t in Okt().pos(txt) if (t[1] == 'Noun') & (len(t[0])>1)] #품사태깅+ 명사계열 한글자 인것만 적용 #품사뽑기
d = get_sentences(doc)
get_words(d[0])
['정통부',
'유영민',
'장관',
'참석',
'기념',
'행사',
'투입',
'여종',
'데이터',
'구축',
'민간',
'클라우드',
'통한',
'외부',
'체계',
'개방',
'강화',
'이데일리',
'재운',
'기자']
토큰화는 예쁘게 됨
#중요 단어 결정
def get_keywords(doc,min_ratio=0.001,max_ratio=0.5):
from nltk import FreqDist
min_ratio = 0.001
max_ratio = 0.5
tokens = get_words(doc)
freq = FreqDist(tokens)
keywords = set()
for w, f in freq.items() : #단어빈도 계산
if (freq[w]/freq.N() > min_ratio) & (freq[w]/freq.N() < max_ratio) :
keywords.add(w)
return keywords
print(get_keywords(doc))
{'구축', '행사', '재운', '데이터', '외부', '기자', '장관', '참석', '체계', '민간', '투입', '유영민', '정통부', '이데일리', '강화', '통한', '개방', '기념', '클라우드', '여종'}
sentences = get_sentences(doc)
keywords = get_keywords(doc)
#words = get_words(sentences)
def get_sentence_weight(sentence, keywords) :
words = get_words(sentences[0])
window_start = 0
for i in range(len(words)) :
if words[i] in keywords :
window_start = i
break
for i in range(len(words) - 1, 0, -1) :
if words[i] in keywords :
window_end = i
break
#print(window_start) #19
#print(window_end) #1
if window_start > window_end :
return 0
window_size = window_end - window_start + 1
#print(window_size)
keywords_cnt = 0
for w in words :
if w in keywords :
keywords_cnt += 1
return (keywords_cnt*keywords_cnt) / window_size
get_sentence_weight(sentences[0], keywords) #20
print(words)
print(keywords)
['정통부', '유영민', '장관', '참석', '기념', '행사', '투입', '여종', '데이터', '구축', '민간', '클라우드', '통한', '외부', '체계', '개방', '강화', '이데일리', '재운', '기자']
{'구축', '행사', '재운', '데이터', '외부', '기자', '장관', '참석', '체계', '민간', '투입', '유영민', '정통부', '이데일리', '강화', '통한', '개방', '기념', '클라우드', '여종'}
#문서 요약
sentences = get_sentences(doc)
keywords = get_keywords(doc, 0.01)
sentence_weights = []
for s in sentences :
sentence_weights.append( (get_sentence_weight(s, keywords), s) ) #가중치와 실제sentences 까지
sentence_weights.sort(reverse = True)
sentence_weights #스코어 20
[(20.0,
'과기정통부, 22일 유영민 장관 등 참석해 기념행사 2021년까지 1516억원 투입, 5100여종 데이터 구축 민간 클라우드 통한 외부연계체계도.."개방성 강화" [이데일리 이재운 기자]')]
def summarize(doc,n=3):
sentences = get_sentences(doc)
keywords = get_keywords(doc)
sentence_weights = []
for s in sentences:
sentence_weights.append((get_sentence_weight(s,keywords),s))
sentence_weights.sort(reverse=True)
return sentence_weights[:n]
summarize(doc,3)
[(20.0,
'과기정통부, 22일 유영민 장관 등 참석해 기념행사 2021년까지 1516억원 투입, 5100여종 데이터 구축 민간 클라우드 통한 외부연계체계도.."개방성 강화" [이데일리 이재운 기자]')]
코드는 참고용으로 적었지만 결과가 이상하게 나와서 도큐먼트 데이터를 여러개 가져와야 할것같움
출처: https://github.com/insightcampus/sesac-nlp/tree/main/ipynb