무회blog

python: 200609-python_part1_topics_추출 본문

Python

python: 200609-python_part1_topics_추출

최무회 2020. 6. 9. 18:21

tss.csv
0.08MB
문재인대통령취임연설문_ansi.txt
0.01MB
정치사회생활30.csv
0.08MB

 

 

In [1]:
# for_005_topikTs_tomoto
# %pip install tomotopy
# %pip install nltk
#  한국어 전처리 
# %pip install --upgrade kiwipiepy  
# %pip install KoNLP
# import nltk
# nltk.download()
#############################################
import tomotopy as tp 
import pandas as pd
import numpy as np
import nltk.stem, nltk.corpus, nltk.tokenize, re ,os
from kiwipiepy import Kiwi
kiwi = Kiwi()
kiwi.prepare()
#############################################
from gensim import corpora 
from gensim import models
from konlpy.utils import pprint
from konlpy.tag import Hannanum
from konlpy.tag import Kkma
kkma = Kkma()
hannanum = Hannanum()
print("success import")
 
success import
In [2]:
# for Setting Test pattern 
# global 변수 , Setting 용 
tg_num = 0  # 읽어드린 문서에서 타겟팅 내용 
dic01 = {}
dic02 = {}
token0 = []
li_model = [] 

get_cnt    = 7           # 토픽의  갯수 , 빈도수에서 자동화 숫자 
k_cnt      = 5     # 토픽의 개수    , 행 , 1 ~ 32767 사이의 정수
top_n_cnt  = get_cnt     # 토픽의  갯수   , 열
min_cf_cnt = 1    # 단어 최소 출현 빈도  , 0 일시 모든 단어를 동일하게 봄 
alpha_cnt  = 0.1   # 문헌‐토픽 빈도
eta_cnt    = 0.01  # 토픽‐단어 빈도
tran_cnt   = 100   # 자동학습 빈도
rm_top2    = 1

# def pd_readFile():
ReadDataPd = pd.read_csv('D:\\app_src\\anaconda\\04-srcTest\\testfile\\all_test\\tss.csv',engine="python")
ReadDataPd['내용']
al_list = ReadDataPd['내용'].tolist()
all_list = [al_list[tg_num]]
hdl_list = all_list[tg_num].split('.')

def tokenize(sent):
    res, score = kiwi.analyze(sent)[0] # 첫번째 결과를 사용
    return [word
            for word, tag, _, _ in res
            if not tag.startswith('E') 
            and not tag.startswith('J') 
            and not tag.startswith('S')] # 조사, 어미, 특수기호는 제거   

path_df = './rs_tm/'

print(type(ReadDataPd['내용']))
print(type(hdl_list))
print("success Setting")
 
<class 'pandas.core.series.Series'>
<class 'list'>
success Setting
In [3]:
class fr_hannanum_mth:
    # 텍스트 정제 함수 : 분석에 불필요한 문자는 전부 제거합니다. 
    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 

    # 형태소 분석해서 용언(P), 체언(N)만 남김
    def get_infoText(read_text):
        #resList = list()
        resList=[]
        #GetWordSet = set(['N'])
        GetWordSet = set(['N','P'])
        for read_text_line in read_text:
            res=""
            if len(read_text_line) > 0:
                pos = hannanum.pos(read_text_line,ntags=9)
                for keyword, type in pos:
                    # 키워드가 한글자 이상일 경우만
                    if len(keyword) > 1 :
                        # 용언(P), 체언(N)만 남김
                        if (type in GetWordSet):
                            if type == 'P': #용언일 경우 '다'를 붙여줌
                                keyword=keyword+'다'
                            resList.append(keyword)  
        return resList

    
    def fm_start(get_cnt):
        texts = []
        # ReadDataPd['내용']
#         for w in ReadDataPd['내용']:
        for w in all_list:
            raw = w.lower()
            #클린징
            ReadDoc_CleanText= fr_hannanum_mth.text_cleaning(raw)

            #클린징 마친 텍스트를 문장으로 분리
            ReadDoc_SplitText=ReadDoc_CleanText.split('\n')
            #print("ReadDoc_SplitText=",ReadDoc_SplitText)

            #문장으로 분리한 텍스트를 형태소 분석해서 용언(N), 체언(V)만 남김
            ReadDoc_Analyis=fr_hannanum_mth.get_infoText(ReadDoc_SplitText)

            ReadDoc_Analyis=pd.Series([x for x in ReadDoc_Analyis if len(x)>1])
            #문서들을 리스트 형태로  texts에 추가
            texts.append(ReadDoc_Analyis)
            
        for i in range(len(texts)) :
            print('-'*50)
            print(texts[i].value_counts().head(get_cnt))
            print(type(texts[i].value_counts().head(get_cnt)))
            series_value = texts[i].value_counts().head(get_cnt)
            return series_value

ss = fr_hannanum_mth.fm_start(get_cnt)
df= pd.DataFrame(ss)
df.to_excel(path_df+'pd_bd_hannanum.xlsx')
 
--------------------------------------------------
대통령     29
국민      19
만들다     10
대한민국     9
우리       8
새롭다      8
여러분      7
dtype: int64
<class 'pandas.core.series.Series'>
In [4]:
class fr_kkma_mth:
    temp = []
    # 형태소 분석하여 명사만 추출
    for i in range(len(all_list)):
        temp.append(kkma.nouns(all_list[i]))
    # print("\n temp=",temp) 

    def flatten(l): 
        flatList = [] 
        for elem in l: 
            if type(elem) == list: 
                for e in elem: 
                    flatList.append(e) 
            else: 
                flatList.append(elem) 
        return flatList
    
    def fm_start(get_cnt):
        word_list=fr_kkma_mth.flatten(fr_kkma_mth.temp)
        # print("\n word_list=",word_list) 
        # 두글자 이상인 단어만 추출
        word_list=pd.Series([x for x in word_list if len(x)>1])
        word_list.value_counts().head(get_cnt)
        print(word_list.value_counts().head(get_cnt))
        series_value = word_list.value_counts().head(get_cnt)
        return series_value

ss = fr_kkma_mth.fm_start(get_cnt)
df= pd.DataFrame(ss)
df.to_excel(path_df+'pd_bd_kkma.xlsx')
 
우리    2
해소    1
가능    1
통치    1
승화    1
재벌    1
광화    1
dtype: int64
In [5]:
class fr_kiwi01_mth:
    # tokenize 처리 
    dic01 = {}
    token0 = []
    li_model = [] 
    li_model_PMI = []
    li_model_IDF = []
    li_model_ONE = []
    
    stemmer = nltk.stem.porter.PorterStemmer() 
    stopwords = set(nltk.corpus.stopwords.words('korean')) 

    def fm_start(get_cnt):
        model     = tp.LDAModel(k=k_cnt, alpha=alpha_cnt,eta = eta_cnt)
        model_PMI = tp.LDAModel(k=k_cnt, alpha=alpha_cnt,eta = eta_cnt, min_cf=min_cf_cnt,tw=tp.TermWeight.PMI)
        model_IDF = tp.LDAModel(k=k_cnt, alpha=alpha_cnt,eta = eta_cnt, min_cf=min_cf_cnt,tw=tp.TermWeight.IDF)
        model_ONE = tp.LDAModel(k=k_cnt, alpha=alpha_cnt,eta = eta_cnt, min_cf=min_cf_cnt,tw=tp.TermWeight.ONE)  # one 모든 단어를 동등하게 보다     

        for i, line in enumerate(all_list):
            token0 = tokenize(line)
            stopwords = set([wd for wd in token0 if len(wd) <= 1]) #  한글자 단어는 불용어로 지정 
            stopwords = set('기자') #  한글자 단어는 불요어로 지정
            token0 = [wd for wd in token0 if len(wd) > 1]          # 한글자 이상 단어 토큰으로 지정 
            model.add_doc(token0)                                    # tokenize함수를 이용해 전처리한 결과를 add_doc에 넣습니다.
            model_PMI.add_doc(token0)  
            model_IDF.add_doc(token0)  
            model_ONE.add_doc(token0)  
        model.train(tran_cnt)    
        for i in range(model.k):
            ttx1= ', '.join(w for w, p in model.get_topic_words(i,top_n=top_n_cnt))
            ttx2= ', '.join(w for w, p in model_PMI.get_topic_words(i, top_n=top_n_cnt))
            ttx3= ', '.join(w for w, p in model_IDF.get_topic_words(i, top_n=top_n_cnt))
            ttx4= ', '.join(w for w, p in model_ONE.get_topic_words(i, top_n=top_n_cnt))
            
            ttx1 = re.sub('[a-zA-Z@.]','',ttx1)
            ttx2 = re.sub('[a-zA-Z@.]','',ttx2)
            ttx3 = re.sub('[a-zA-Z@.]','',ttx3)
            ttx4 = re.sub('[a-zA-Z@.]','',ttx4)
            
            fr_kiwi01_mth.li_model.append(ttx1)
            fr_kiwi01_mth.li_model_PMI.append(ttx2)
            fr_kiwi01_mth.li_model_IDF.append(ttx3)
            fr_kiwi01_mth.li_model_ONE.append(ttx4)
            
            fr_kiwi01_mth.dic01['lda_model'] = fr_kiwi01_mth.li_model
            fr_kiwi01_mth.dic01['lda_PMI']   = fr_kiwi01_mth.li_model_PMI
            fr_kiwi01_mth.dic01['lda_IDF']   = fr_kiwi01_mth.li_model_IDF
            fr_kiwi01_mth.dic01['lda_ONE']   = fr_kiwi01_mth.li_model_ONE
        pd_yp_ldadt = pd.DataFrame(fr_kiwi01_mth.dic01)
        df= pd.DataFrame(pd_yp_ldadt)
        df.to_excel(path_df+'pd_yp_ldadt.xlsx')
        return pd_yp_ldadt
    
fr_kiwi01_mth.fm_start(get_cnt)
Out[5]:
  lda_model lda_PMI lda_IDF lda_ONE
0 국민, 새롭, 존경, 함께, 지금, 감사, 시민 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 나라, 새롭, 역사, 만들, 대한민국
1 만들, 위대, 약속, 문재인, 한반도, 과정, 광화문 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 국민, 대통령, 나라, 지금, 선거, 기관, 위하
2 대통령, 대한민국, 우리, 선거, 드리, 해결, 지지 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 드리, 어렵, 치르, 정치
3 여러분, 역사, 오늘, 말씀, 문제, 시키, 위하 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 국민, 대한민국, 우리, 권력, 시키, 대통령, 오늘
4 나라, 정치, 대화, 권력, 세상, 머리, 갈등 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 만들, 대한민국, 새롭, 우리, 나라 대통령, 국민, 새롭, 우리, 여러분, 만들, 대한민국
In [6]:
#############################################
class fr_kiwi02_mth:
    # (tw=TermWeight.ONE, min_cf=0, rm_top=0, k=1, smoothing_alpha=0.1, eta=0.01, seed=?)  
    mdl_HDPModel    = tp.HDPModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)  # 계층적 디리클레 프로세스 ( HDPModel )
    mdl_CTModel     = tp.CTModel(tw=tp.TermWeight.ONE, min_cf=min_cf_cnt, rm_top=1)   # 상관 토픽 모델 ( CTModel )
    mdl_PAMODel     = tp.PAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 파칭코 할당 ( PAMODel )
    mdl_HPAModel    = tp.HPAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 계층적 PA ( HPAModel )
    mdl_MGLDAModel  = tp.MGLDAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 멀티 그레인 LDA ( MGLDAModel )
    mdl_LLDAModel   = tp.LLDAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 라벨 LDA ( LLDAModel )
#     mdl_HLDAModel   = tp.HLDAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 계층적 LDA ( HLDAModel )
    # model = tp.PLDAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 부분 라벨 LDA ( PLDAModel ) , 안됨 

    def fm_mdl(model):
        for i, line in enumerate(all_list):
            token0 = tokenize(line)
            stopwords = set([wd for wd in token0 if len(wd) <= 1]) #  한글자 단어는 불요어로 지정 
            stopwords = set('기자') #  한글자 단어는 불요어로 지정
            token0 = [wd for wd in token0 if len(wd) > 1]          # 한글자 이상 단어 토큰으로 지정 
            model.add_doc(token0)                                    # tokenize함수를 이용해 전처리한 결과를 add_doc에 넣습니다.
        model.train(tran_cnt) 
        for i in range(model.k):
            ttx1= ', '.join(w for w, p in model.get_topic_words(i,top_n=top_n_cnt))
            ttx1 = re.sub('[a-zA-Z@.]','',ttx1)
            li_model.append(ttx1)
        return li_model
    
    def fm_start():
        li_mdl_HDPModel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_HDPModel)
        li_mdl_CTModel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_CTModel)
        li_mdl_PAMODel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_PAMODel)
        li_mdl_HPAModel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_HPAModel)
        li_mdl_MGLDAModel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_MGLDAModel)
        li_mdl_LLDAModel = fr_kiwi02_mth.fm_mdl(fr_kiwi02_mth.mdl_LLDAModel)
        dic01['mdl_HDPModel'] = li_mdl_HDPModel
        dic01['mdl_CTModel'] = li_mdl_CTModel
        dic01['mdl_PAMODel'] = li_mdl_PAMODel
        dic01['mdl_HPAModel'] = li_mdl_HPAModel
        dic01['mdl_MGLDAModel'] = li_mdl_MGLDAModel
        dic01['mdl_LLDAModel'] = li_mdl_LLDAModel
        pd_zh_ldadt = pd.DataFrame(dic01).head(5)
        pd_zh_ldadt.to_excel(path_df+'pd_zh_ldadt.xlsx')
        return pd_zh_ldadt
In [7]:
# tokenize 처리 
class fr_kiwi03_mth:
    model = tp.HLDAModel(tw=tp.TermWeight.ONE, min_cf=3, rm_top=1)   # 계층적 LDA ( HLDAModel )
    def model_exe(model):
        for i, line in enumerate(hdl_list):
            token0 = tokenize(line)
            stopwords = set([wd for wd in token0 if len(wd) <= 1]) #  한글자 단어는 불요어로 지정 
            stopwords = set('기자') #  한글자 단어는 불요어로 지정
            token0 = [wd for wd in token0 if len(wd) > 1]          # 한글자 이상 단어 토큰으로 지정 
            model.add_doc(token0)                                    # tokenize함수를 이용해 전처리한 결과를 add_doc에 넣습니다.
        model.train(tran_cnt) 
        print(model.k)
        for i in range(model.k):
            ttx1= ', '.join(w for w, p in model.get_topic_words(i,top_n=top_n_cnt))
            ttx1 = re.sub('[a-zA-Z@.]','',ttx1)
            li_model.append(ttx1)
            dic02['mdl_HLDAModel'] = li_model
            pd_hld_ldadt = pd.DataFrame(dic02).head(5)
            pd_hld_ldadt.to_excel(path_df+'pd_hld_ldadt.xlsx')
            return pd_hld_ldadt
    def fm_start():
        fr_kiwi03_mth.model_exe(fr_kiwi03_mth.model)
        
In [8]:
# import os

# aa = os.listdir()
# type(aa)
# aa
# for x in os.listdir('./'):
#         if x.endswith('ipynb'):
#                 print(x)
# os.mkdir('./testfile/all_test/testFolder/')
# os.rmdir('./testfile/all_test/폴더를_생성하지')
# os.remove('./testfile/all_test/문재인대통령취임연설문_ansi - 복사본.txt')


fr_hannanum_mth.fm_start(get_cnt)
fr_kkma_mth.fm_start(get_cnt)
fr_kiwi01_mth.fm_start(get_cnt)
fr_kiwi02_mth.fm_start()
fr_kiwi03_mth.fm_start()
 
--------------------------------------------------
대통령     29
국민      19
만들다     10
대한민국     9
우리       8
새롭다      8
여러분      7
dtype: int64
<class 'pandas.core.series.Series'>
우리    2
해소    1
가능    1
통치    1
승화    1
재벌    1
광화    1
dtype: int64
16
Comments