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