무회blog

200623-yoyag_test_008-002, 요약테스트 본문

Python

200623-yoyag_test_008-002, 요약테스트

최무회 2020. 6. 24. 09:24
200623-yoyag_test_008-002
In [1]:
import pandas as pd 
import time, timeit, os, sys , re 
from gensim.summarization import summarize
from collections import Counter
import collections
from nltk.tokenize import sent_tokenize,word_tokenize

#############################################
from datetime import datetime
import numpy as np 
import nltk.stem, nltk.corpus, nltk.tokenize 
from newspaper import Article
#############################################
import tomotopy as tp 
#############################################
from gensim import corpora 
from gensim import models
from konlpy.utils import pprint
from kiwipiepy import Kiwi
from konlpy.tag import Hannanum
hannanum = Hannanum()
kiwi = Kiwi()
kiwi.prepare()
#############################################
import requests as rq
import selenium as se
from selenium import webdriver
from bs4 import BeautifulSoup
from multiprocessing import Pool
#############################################
from string import punctuation
from heapq import nlargest
In [2]:
def text_cleaning(text): 
        #이모티콘 제거
        EMOJI = re.compile('[\U00010000-\U0010ffff]', flags=re.UNICODE)
        text= EMOJI.sub(r'', text)
        #이메일 주소 제거
        email =re.compile('([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)')
        text = email.sub('', text) 
        #URL 제거
        url =re.compile('(http|ftp|https)://(?:[-\w.]|(?:%[\da-fA-F]{2}))+')
        text = url.sub('', text) 
        #HTML 제거
        html =re.compile('<[^>]*>')
        text = html.sub('', text) 

        #특수문자를 공백으로 대체(문장을 살리기위헤 마침표는 남겨둠)
        #special =re.compile('[^\w\s]')
        #text = special.sub(' ', text) 
        special= ['*', '{', ',', ':', ']', '$', '+', '[', '#', '(', '%', '&', '}', '`', '‘', '’','·',
                    '=', ';', '>','>', '/', '"', '“', '”', '\\', '?', '~', "'", '<', ')', '^', '!', '_',
                    '|', '@','@','©','ⓒ', '℗','®','①', '-','▶','…','☞','▲'] #'.', 빼고
        for chr in special :
            text=text.replace(chr,' ')

        #특수문자 제거 후 생기는 중복된 공백 제거
        while text.find('  ') > 0:
            text = text.replace('  ',' ' ) # 중복된 공백 제거

        #특수문자 제거 후 생기는 중복된 개행 제거
        while text.find('\n\n') > 0:
            text = text.replace('\n\n','\n' ) # 중복된 개행 제거
        
        # .텍스트 ->  ".텍스트" -> ". 텍스트"

        #좌우측 공백 삭제
        text.strip()

        # 좌측 공백 삭제
        # text.lstrip()

        # 우측 공백 삭제
        #text.rstrip()        
        return text  
In [3]:
def textSummerFunc():
    # punctuation는 [, ], ? 등 기호 리스트 이다.
    STOPWORDS =  list(punctuation)

    #문장에 나타나는 단어의 빈도 중 최소, 최대등 의미없는 단어를 제거하기 위한 변수
    MIN_WORD_PROP, MAX_WORD_PROP = 0.1, 0.9

    def compute_word_frequencies(word_sentences):
        words = [word for sentence in word_sentences 
                         for word in sentence 
                             if word not in STOPWORDS]
        counter = Counter(words)
        limit = float(max(counter.values()))
        word_frequencies = {word: freq/limit 
                                    for word,freq in counter.items()}
        # Drop words if too common or too uncommon
        word_frequencies = {word: freq 
                                for word,freq in word_frequencies.items() 
                                    if freq > MIN_WORD_PROP 
                                    and freq < MAX_WORD_PROP}
        return word_frequencies

    def sentence_score(word_sentence, word_frequencies):
        return sum([ word_frequencies.get(word,0) 
                        for word in word_sentence])

    def summarize(text:str, num_sentences=3):
        """
        Summarize the text, by return the most relevant sentences
         :text the text to summarize
         :num_sentences the number of sentences to return
        """
        # Make the text lowercase
        text = text.lower()

        # Break text into sentences 
        sentences = sent_tokenize(text)

        # Break sentences into words
        word_sentences = [word_tokenize(sentence) 
                              for sentence in sentences]

        # Compute the word frequencies
        word_frequencies = compute_word_frequencies(word_sentences)

        # Calculate the scores for each of the sentences
        scores = [sentence_score(word_sentence, word_frequencies)
                         for word_sentence in word_sentences]
        sentence_scores = list(zip(sentences, scores))

        # Rank the sentences
        top_sentence_scores = nlargest(num_sentences, 
                                       sentence_scores,
                                       key=lambda t: t[1])

        # Return the top sentences
        return [t[0] for t in top_sentence_scores]


    #분류 대상 파일을 읽어온다
    ReadDataPd = df2.copy()
    ReadDataPd=ReadDataPd.assign(summarize_word='')
    counter=0
    # for w in ReadDataPd['내용']:
    for w in ReadDataPd['content']:
        #클린징
        ReadDoc_CleanText= text_cleaning(w)
        #print("\nReadDoc_CleanText=",ReadDoc_CleanText[:100])
        # n줄로 요약 생성
        sum_res=summarize(ReadDoc_CleanText, num_sentences=3)

        ReadDataPd.at[counter,'summarize_word']=sum_res
        counter=counter+1
#     path_to = creatFolder_in + td + '_'+ subMenu.strip() + '_' + test_bindo +'_'+ str(most_cnt) + '_textSummerFunc'+'.xlsx'    
#     ReadDataPd.to_excel(path_to)

    return ReadDataPd    

# textSummerFunc()    
In [4]:
def gensim_wordSummarize(tts,tts1):
    aa = []
    bb = []
    cc = []
    li_tts = []
    liwd_cnt = []
    tts_cnt = 0        
    for i in range(len(tts)):
        tts_cnt = i
        len(tts[tts_cnt])
        ttss = ''
        for i in tts[tts_cnt]:
            ttss = ttss + i

        ttss1 = ''
        for i in tts1[tts_cnt]:
            ttss1 = ttss1 + i

        liwd = word_tokenize(ttss)                           #####  gensim 단어 토큰화  
        liwd = [x for x in liwd if len(x) > 2]
        liwd1 = word_tokenize(ttss1)                        #####   naver 단어 토큰화  
        liwd1 = [x for x in liwd1 if len(x) > 2]

        a = Counter(liwd)  # a.most_common  # 빈도수(frequency)가 높은 순으로 상위
        b = Counter(liwd1)
        c = a & b                                                          # 교집합
        c = c.most_common(most_cnt)                                                # 교집합 빈도수 

        if len(liwd) == 0 :
            biyur = 0
        else:
            biyur = round(len(c)/len(liwd),2)*100
            biyur = int(biyur)
        biyur = str(biyur) + '%'                 #  네이버요약 기준 , gensim 단어 매칭 비율 


        ## a | b #  합집합에 대한 내용 
        aa.append(a.most_common(3))   # 상위 몇개 빼기 
        bb.append(b.most_common(3))

        liwd_cnt.append(biyur)

        cc.append(len(c))           # 교집합 빈도수 
        li_tts.append(c)

    # df2['요약_단어빈도교집합']  = li_tts
    df2['요약단어_교집합']   = li_tts
    df2['naver_단어빈도']    = aa
    df2['gensim_단어빈도']   = bb
    df2['단어_빈도수']       = cc
    df2['빈도_비율']         = liwd_cnt

    df3 = df2.copy()
    
    df3['단어매칭율'] = pd.to_numeric(df3['빈도_비율'].str.replace('%',''))
    df3['단어매칭율'] = str(df3['단어매칭율'].mean()) + '%'
#     df3 = df3[['subMenu','title','yoyag','naver_단어빈도','summarize_word','txdf_단어빈도','요약단어_교집합','빈도_비율','단어_빈도수','단어매칭율']]
    df3 = df3[['subMenu','title','yoyag','naver_단어빈도','summary_yoyag','gensim_단어빈도','요약단어_교집합','빈도_비율','단어_빈도수','단어매칭율']]

    for i in range(len(df3['요약단어_교집합'])):
        if len(df3['요약단어_교집합'][i]) == 0 :
               df3['요약단어_교집합'][i] = '무'
        else:
               pass
    # df3 = df3.sort_values(by=['단어_빈도수'], axis = 0, ascending = False)  ## ascending 정렬  교집합 
#     df3 = df3.sort_values(by=['빈도_비율'], axis = 0, ascending = False)  ## ascending 정렬   빈도율

    path_to = creatFolder_in + td + '_'+ subMenu.strip() + '_' + test_bindo +'_'+ str(most_cnt)+'_gensim_wordSummarize' +'.xlsx'    
    df3.to_excel(path_to)
    return df3
In [5]:
def summary_wordSummarize(tts,tts1):
    aa = []
    bb = []
    cc = []
    li_tts = []
    liwd_cnt = []
    tts_cnt = 0        
    for i in range(len(tts)):
        tts_cnt = i
        len(tts[tts_cnt])
        ttss = ''
        for i in tts[tts_cnt]:
            ttss = ttss + i

        ttss1 = ''
        for i in tts1[tts_cnt]:
            ttss1 = ttss1 + i

        liwd = word_tokenize(ttss)                           #####  gensim 단어 토큰화  
        liwd = [x for x in liwd if len(x) > 2]
        liwd1 = word_tokenize(ttss1)                        #####   naver 단어 토큰화  
        liwd1 = [x for x in liwd1 if len(x) > 2]

        a = Counter(liwd)  # a.most_common  # 빈도수(frequency)가 높은 순으로 상위
        b = Counter(liwd1)
        c = a & b                                                          # 교집합
        c = c.most_common(most_cnt)                                                # 교집합 빈도수 

        if len(liwd) == 0 :
            biyur = 0
        else:
            biyur = round(len(c)/len(liwd),2)*100
            biyur = int(biyur)
        biyur = str(biyur) + '%'                 #  네이버요약 기준 , gensim 단어 매칭 비율 


        ## a | b #  합집합에 대한 내용 
        aa.append(a.most_common(3))   # 상위 몇개 빼기 
        bb.append(b.most_common(3))

        liwd_cnt.append(biyur)

        cc.append(len(c))           # 교집합 빈도수 
        li_tts.append(c)

    # df2['요약_단어빈도교집합']  = li_tts
    txdf['요약단어_교집합']   = li_tts
    txdf['naver_단어빈도']    = aa
    txdf['txdf_단어빈도']     = bb
    txdf['단어_빈도수']       = cc
    txdf['빈도_비율']         = liwd_cnt

    df3 = txdf.copy()
    df3['단어매칭율'] = pd.to_numeric(df3['빈도_비율'].str.replace('%',''))
    df3['단어매칭율'] = str(df3['단어매칭율'].mean()) + '%'
    
    df3 = df3[['subMenu','title','yoyag','naver_단어빈도','summarize_word','txdf_단어빈도','요약단어_교집합','빈도_비율','단어_빈도수','단어매칭율']]

    for i in range(len(df3['요약단어_교집합'])):
        if len(df3['요약단어_교집합'][i]) == 0 :
               df3['요약단어_교집합'][i] = '무'
        else:
               pass
    # df3 = df3.sort_values(by=['단어_빈도수'], axis = 0, ascending = False)  ## ascending 정렬  교집합 
#     df3 = df3.sort_values(by=['빈도_비율'], axis = 0, ascending = False)  ## ascending 정렬   빈도율
    path_to = creatFolder_in + td + '_'+ subMenu.strip() + '_' + test_bindo +'_'+ str(most_cnt)+'_summary_wordSummarize' +'.xlsx'    
    df3.to_excel(path_to)
    
    return df3
In [6]:
path = './yoyag_test/'
checkFolder = os.path.isdir(path)

creatFolder_in = path

if checkFolder == True:
    pass
else:
    os.mkdir(creatFolder_in)

    ############ 폴더 생성 및 체크 
tdd = datetime.today().strftime("%m%d")
checkFolder = os.path.isdir('./yoyag_test/'+'20'+tdd + '/')
creatFolder_in = './yoyag_test/'+'20'+tdd + '/'

if checkFolder == True:
    pass
else:
    os.mkdir(creatFolder_in)

bindo_li = {}
td = datetime.today().strftime("%Y%m%d")     # 오늘 일자  
path_dir = './news002/quanbu/'
path_list = os.listdir(path_dir)
path = path_dir +  path_list[0]
In [7]:
subMenu    = ''                              # 타겟 메뉴 
sheet_cnt  = 1                               # 0 - 5 , 정치, 경제, 사회, 생활, 세계, it 
most_cnt   = 20                              #  상위 교집합의 갯수 기준 테스트 

test_bindo = '빈도_비율'                     #  빈도_비율,   # 단어_빈도수   ,(교집합 테스트)
# test_bindo = '단어_빈도수'                 #  빈도_비율,   # 단어_빈도수   ,(교집합 테스트)
# test_ratio = 0.5                             # 30% 의 비율로 요약 요청 
test_wordCnt = 25                            # 단어수 20개로 지정 
df = pd.read_excel(path, sheet_name=sheet_cnt)

df1 = df.copy()
df1['content'] = df1['content'].str.replace('◆|ⓒ','').str.strip()
df2 = df1[['subMenu','title','content','yoyag']]
##################################################################################################
li_summary = []  
chk = 0
pd.set_option('mode.chained_assignment',  None) # <==== 경고를 끈다    
# ################################################### test001 요약단어_교집합 , gensim_단어요약 VS naver_단어요약
cnt_li = df2['content'].tolist()
subMenu  = df2['subMenu'][0]
print(len(cnt_li))
print(cnt_li[73])
for i in cnt_li:
    tts = text_cleaning(i)
    chk = chk + 1
#     print(chk)
    
#     TotalWord = 단어수 세서 넣고
#     TotalLine = 스플릿 해서 넣고
#     문장당 단어수 = (TotalWord/TotalLine) * 3.2
    
    output1 = tts.replace('.','. ')
#     output = summarize(output1,ratio=test_ratio)                           ## test_ratio
#     output = summarize(output,word_count =test_wordCnt)                   ## test_wordCnt
    output = summarize(output1,word_count =test_wordCnt)                   ## test_wordCnt

    output = output.replace('다.','다._').split('_')
    li_summary.append(output)
df2['summary_yoyag'] = pd.Series(li_summary)
tts = df2['summary_yoyag'].tolist()
tts1 = df2['yoyag'].tolist()
####################################################################### test002 요약단어_교집합 , summary_단어요약 VS naver_단어요약
txdf      = textSummerFunc()                       # summarrize 함수를 사용 
tts0      = txdf['summarize_word'].tolist()
tts01     = txdf['yoyag'].tolist()
subMenu   = txdf['subMenu'][0]
#######################################################################
gensim_wordSummarize(tts,tts1)
# summary_wordSummarize(tts0,tts01)  
100
총 113명 지역아동에게 회화 중심 원어민 영어교육 무상 제공미래지향적 사회공헌활동 일환으로 수혜 조합 지속 확대 예정신협사회공헌재단이 2020년 '신협 어부바 원어민 영어교실' 사업을 추진한다고 22일 밝혔다. 신협사회공헌재단신협사회공헌재단이 2020년 '신협 어부바 원어민 영어교실' 사업을 추진한다고 22일 밝혔다.‘신협 어부바 원어민 영어교실’ 사업은 소외계층 아동에게 원어민 영어교육을 무상으로 제공해 의사소통능력 향상과 양질의 교육 기회를 제공하는 사회공헌활동이다.재단은 2020년 전국 6개 신협(▲김천 ▲경일 ▲달구벌 ▲서해중앙 ▲장성 ▲해남우리)과 함께 기초학습 및 생활회화·체험 위주의 교육 프로그램을 60명의 아동에게 제공하고 향후 프로그램을 확대할 방침이다.김윤식 재단 이사장은 “신협사회공헌재단은 모든 아동들이 평등하게 양질의 교육을 받을 수 있도록 지원을 아끼지 않고 있다”며 “신협은 미래 사회의 기둥이 될 아이들이 건강하게 자랄 수 있도록, 협동조합의 힘으로 금융 안전망을 넘어 거대한 사회 안전망이 되겠다”고 밝혔다.데일리안 배근미 기자 (athena3507@dailian.co.kr) (주)데일리안 - 무단전재, 변형, 무단배포 금지
Out[7]:
subMenu title yoyag naver_단어빈도 summarize_word txdf_단어빈도 요약단어_교집합 빈도_비율 단어_빈도수 단어매칭율
0 경제 위례신도시 제일풍경채 견본주택 오픈 제일건설㈜은 '위례신도시 제일풍경채'의 견본주택을 오픈하고 본격적인 분양에 들어간다... [(위례신도시, 4), (우수한, 2), (일부타입, 2)] [우수한 단지배치로 공원 및 남한산성 조망권을 영구적 일부타입 제외 으로 확보해 쾌... [(제일건설㈜은, 1), ('위례신도시, 1), (제일풍경채, 1)] [(위례신도시, 1), (다양한, 1), (제일풍경채, 1), (제일건설㈜은, 1)... 17% 20 22.49%
1 경제 외국인도 우선주 열풍에 ‘GO!’ 최근 국내 증시에서 불고 있는 우선주 열풍에 외국인도 몸을 실었다.보통주 대비 우선... [(우선주, 5), (투자자들의, 3), (보통주의, 2)] [이에 보통주 투자자들의 경우 손실을 대부분 만회했지만 여전히 넘치는 유동성은 증시... [(우선주, 3), (증시에서, 1), (열풍에, 1)] [(우선주, 3), (매력이, 1), (것으로, 1), (외국인들이, 1), (우선... 13% 20 22.49%
2 경제 [fnRASSI]앱클론, 52주 신고가...3.52% ↑ 앱클론은 52주신고가를 기록하고 있어 주목할만하다.이는 60일 일 평균 거래량 78... [(성장성, 2), (앱클론의, 2), (1.34, 2)] [지표 항목 값 종합점수 성장성 매출액증가율 0.78 5.02 자기자본증가율 0.3... [(앱클론은, 1), (52주신고가를, 1), (기록하고, 1)] [(성장성, 1), (점수는, 1), (12.97점으로, 1), (분기에, 1), ... 11% 5 22.49%
3 경제 [fnRASSI]피앤이솔루션, 52주 신고가...5.35% ↑ 피앤이솔루션은 52주신고가를 기록하고 있어 주목할만하다.최근 5일간 동종목의 외국인... [(종합점수, 2), (재무분석, 1), (80점으로, 1)] [퀀트 재무분석 종합점수 80점으로 상승 지표 항목 값 종합점수 성장성 매출액증가율... [(외국인, 2), (피앤이솔루션은, 1), (52주신고가를, 1)] [(5일간, 1), (동종목의, 1), (외국인, 1), (투자자는, 1), (순매... 15% 7 22.49%
4 경제 다날 페이코인(PCI), 가상자산 거래소 업비트에 상장 다날은 블록체인 자회사 다날핀테크가 발행한 페이코인이 지난 18일 가상자산 거래소 ... [(가상자산, 3), (메이저, 2), (페이코인, 2)] [다날핀테크 관계자는 업비트는 월 평균 방문자수 468만명을 기록하는 국내 메이저 ... [(거래소, 2), (거래가, 2), (가상자산의, 2)] [(가상자산의, 2), (거래소, 2), (관계자는, 1), (업비트는, 1), (... 31% 20 22.49%
... ... ... ... ... ... ... ... ... ... ...
95 경제 KB자산운용, ESG 인프라펀드 규모 2조원 돌파 KB자산운용은 ESG 관련 인프라펀드 규모가 2조원을 돌파했다고 22일 밝혔다.신재... [(투자하는, 3), (다양한, 2), (외에도, 2)] [전남 신안군 자은면에 29.4㎿급 풍력발전단지를 짓는 프로젝트에 투자한 kb자은풍... [(태양광, 3), (KB자산운용은, 1), (ESG, 1)] [(운용을, 1), (외에도, 1), (있으며, 1), (넓히고, 1), (규모가,... 8% 7 22.49%
96 경제 종근당, 美 학회서 항암 이중항체 신약 전임상 결과발표 종근당은 항암 이중항체 바이오 신약 'CKD-702'의 전임상 결과를 미국암학회 연... [(ckd, 5), (전임상, 3), (수용체, 3)] [또 면역세포가 암세포에 살상기능을 발휘하도록 돕는 항체 의존성 세포 독성 adcc... [(전임상, 2), (성장인자, 2), (종근당은, 1)] [(전임상, 2), (성장인자, 2), (종근당은, 1), (이중항체, 1), (바... 15% 20 22.49%
97 경제 인국공, 대학생이 가장 일하고 싶은 공기업 '3년 연속' 취업포털 인크루트가 '2020 대학생이 꼽은 가장 일하고 싶은 공기업' TOP10 ... [(공기업, 3), (만족스러운, 2), (급여와, 2)] [인국공이 3년 연속 대학생 선호 공기업 1위로 꼽힌 비결은 무엇일까 해당 기업을 ... [(공기업, 3), (취업포털, 1), (인크루트가, 1)] [(공기업, 3), (대학생, 1), (대학생이, 1), (일하고, 1)] 11% 4 22.49%
98 경제 '일진다이아' 5% 이상 상승, 단기·중기 이평선 정배열로 상승세 단기·중기 이평선 정배열로 상승세 일봉 차트의 모습은 현재 단기·중기 이평선이 정배... [(per는, 2), (화학업종의, 2), (per, 2)] [per는 화학업종의 평균 per 17.9배 대비 15.7배 높은 수준으로 업종 내... [(단기·중기, 2), (종목의, 2), (이평선, 1)] [(종목의, 2), (이평선, 1), (정배열로, 1), (차트의, 1), (모습은... 35% 18 22.49%
99 경제 현대로템, GTX-A노선 전동차 40량 추가 수주 현대로템은 22일 한국철도시설공단에서 발주한 삼성동탄 광역급행철도 차량 40량을 수... [(전동차, 8), (gtx, 5), (a노선, 5)] [일반 지하철보다 속도가 빠른 gtx a노선 전동차의 특성상 ktx srt 등 고속... [(전동차, 6), (현대로템은, 2), (수주한, 2)] [(전동차, 6), (수주한, 2), (수주하며, 1), (현대로템은, 1), (2... 16% 20 22.49%

100 rows × 10 columns

In [8]:
# subMenu    = ''                              # 타겟 메뉴 
# sheet_cnt  = 1                               # 0 - 5 , 정치, 경제, 사회, 생활, 세계, it 
# most_cnt   = 20                              #  상위 교집합의 갯수 기준 테스트 

# test_bindo = '빈도_비율'                     #  빈도_비율,   # 단어_빈도수   ,(교집합 테스트)
# # test_ratio = 0.5                             # 30% 의 비율로 요약 요청 
# test_wordCnt = 25                            # 단어수 20개로 지정 
# df = pd.read_excel(path, sheet_name=sheet_cnt)

# df1 = df.copy()
# df1 = df1.drop_duplicates('content')        #### 중복된 행 제거 
# print(len(df1))
# df1['content'][0]
# # df1['content'] = df1['content'].str.replace('◆|ⓒ','').str.strip()
# # df2 = df1[['subMenu','title','content','yoyag']]
# # df2
In [ ]:
 
Comments