DA(Data Architecture) 도구/단어 추출 도구

단어 추출 도구(5): 단어 추출 도구 소스코드 설명(2)

ProDA 2021. 11. 13.

이 글은 새로운 블로그로 옮겼습니다. 5초후 자동으로 이동합니다.

▶ 새로운 블로그 주소: https://prodskill.com/

▶ 새로운 글 주소: https://prodskill.com/word-extractor-source-code-2/

이전 글에 이어 Python으로 구현한 단어 추출 도구의 소스코드에 대해 살펴본다.

 

이전 글에서 이어지는 내용이다.

단어 추출 도구(4): 단어 추출 도구 소스코드 설명(1)

 

단어 추출 도구(4): 단어 추출 도구 소스코드 설명(1)

Python으로 구현한 단어 추출 도구의 소스코드에 대해 살펴본다. 이전 글에서 이어지는 내용이다. 단어 추출 도구(3): 단어 추출 도구 실행, 결과 확인 방법 단어 추출 도구(3): 단어 추출 도구 실행,

prodtool.tistory.com


목차

     

     

    4. 단어 추출 도구 소스코드

    4.3. get_file_text 함수

    def get_file_text(file_name) -> DataFrame:
        """
        MS Word, PowerPoint, Text, DB Comment(Excel) file에서 text를 추출하는 함수
        :param file_name: 파일명
        :return: file에서 추출한 text(DataFrame type)
        """
        df_text = DataFrame()
        if file_name.endswith(('.doc', '.docx')):
            df_text = get_doc_text(file_name)
        elif file_name.endswith(('.ppt', '.pptx')):
            df_text = get_ppt_text(file_name)
        elif file_name.endswith('.txt'):
            df_text = get_txt_text(file_name)
        elif file_name.endswith(('.xls', '.xlsx', '.xlsb')):
            df_text = get_db_comment_text(file_name)
        return df_text

     

    • 357~365행: 파일 확장자에 따라 적합한 함수를 실행하고 그 결과를 df_text에 담아 반환한다.

     

    파일 확장자에 따라 실행하는 각 함수에 대한 설명은 다음과 같다.

     

    4.3.1. get_doc_text 함수

    def get_doc_text(file_name) -> DataFrame:
        """
        doc 파일에서 text를 추출하여 DataFrame type으로 return
        :param file_name: 입력 파일명 (str type)
        :return: 입력 파일에서 추출한 text
        """
        # :return: 입력 파일에서 추출한 text에 형태소 분석기로 명사 추출한 DataFrame
        start_time = time.time()
        print('\r\nget_doc_text: %s' % file_name)
        word_app = win32com.client.Dispatch("Word.Application")
        word_file = word_app.Documents.Open(file_name, True)
        # result = []
        df_text = pd.DataFrame()
        page = 0
        for paragraph in word_file.Paragraphs:
            text = paragraph.Range.Text
            page = paragraph.Range.Information(3)  # 3: wdActiveEndPageNumber(Text의 페이지번호 확인)
            if text.strip() != '':
                sr_text = Series([file_name, 'doc', page, text, f'{file_name}:{page}:{text}'],
                                 index=['FileName', 'FileType', 'Page', 'Text', 'Source'])
                df_text = df_text.append(sr_text, ignore_index=True)
    
        word_file.Close()
        print('text count: %s' % str(df_text.shape[0]))
        print('page count: %d' % page)
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('[pid:%d] get_doc_text elapsed time: %s' % (os.getpid(), elapsed_time))
        # return get_word_list(df_text)
        return df_text

     

    • 193행: win32com package로 MS Word 프로그램의 instance를 생성한다. MS Word가 실행되지 않은 상태라면 이 코드로 실행된다.
    • 194행: 위에서 생성한 MS Word 프로그램 instance에서 .doc 또는 .docx 파일을 연다.
    • 198행: 파일 내용의 단락(Paragraph)을 순회한다.
    • 199행: 단락의 내용중 텍스트를 추출한다.
    • 200행: 현재 단락의 페이지 번호를 추출한다. Range.Information(3)에서 "3"은 wdActiveEndPageNumber 상수값에 해당한다. 자세한 내용은 WdInformation enumeration (Word) | Microsoft Docs를 참조한다.
    • 202~204행: 추출한 텍스트를 Series 개체로 만들고, df_text DataFrame의 행에 추가한다.
    • 214행: 파일에서 추출한 텍스트가 담겨있는 df_text를 반환한다.

     

    4.3.2. get_ppt_text 함수

    def get_ppt_text(file_name) -> DataFrame:
        """
        ppt 파일에서 text를 추출하여 DataFrame type으로 return
        :param file_name: 입력 파일명 (str type)
        :return: 입력 파일에서 추출한 text
        """
        # :return: 입력 파일에서 추출한 text에 형태소 분석기로 명사 추출한 DataFrame
        start_time = time.time()
        print('\r\nget_ppt_text: %s' % file_name)
        ppt_app = win32com.client.Dispatch('PowerPoint.Application')
        ppt_file = ppt_app.Presentations.Open(file_name, True)
        # result = []
        df_text = pd.DataFrame()
        page_count = 0
        for slide in ppt_file.Slides:
            slide_number = slide.SlideNumber
            page_count += 1
            for shape in slide.Shapes:
                shape_text = []
                text = ''
                if shape.HasTable:
                    col_cnt = shape.Table.Columns.Count
                    row_cnt = shape.Table.Rows.Count
                    for row_idx in range(1, row_cnt + 1):
                        for col_idx in range(1, col_cnt + 1):
                            text = shape.Table.Cell(row_idx, col_idx).Shape.TextFrame.TextRange.Text
                            if text != '':
                                text = text.replace('\r', ' ')
                                shape_text.append(text)
                elif shape.HasTextFrame:
                    for paragraph in shape.TextFrame.TextRange.Paragraphs():
                        text = paragraph.Text
                        if text != '':
                            shape_text.append(text)
                for text in shape_text:
                    if text.strip() != '':
                        sr_text = Series([file_name, 'ppt', slide_number, text, f'{file_name}:{slide_number}:{text}'],
                                         index=['FileName', 'FileType', 'Page', 'Text', 'Source'])
                        df_text = df_text.append(sr_text, ignore_index=True)
        # print(result)
        ppt_file.Close()
        # print(df_result)
        print('text count: %s' % str(df_text.shape[0]))
        print('page count: %d' % page_count)
        # print(df_text.head(10))
        # print(df_result.Paragraph)
        # return df_result
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('[pid:%d] get_ppt_text elapsed time: %s' % (os.getpid(), elapsed_time))
        # return get_word_list(df_text)
        return df_text

     

    • 138행: win32com package로 MS Powerpoint 프로그램의 instance를 생성한다. MS Powerpoint가 실행되지 않은 상태라면 이 코드로 실행된다.
    • 139행: 위에서 생성한 MS Powerpoint 프로그램 instance에서 .ppt 또는 .pptx 파일을 연다.
    • 143행: 파일의 슬라이드(Slide)를 순회한다.
    • 146행: 각 슬라이드의 도형(Shape)을 순회한다.
    • 149~157행: 도형이 표(Table)인 경우 표의 각 cell에서 텍스트를 추출한다.
    • 158~162행: 도형이 표(Table)가 아니고 Text를 가지고 있는 경우 텍스트를 추출한다.
    • 163~167행: 추출한 텍스트를 Series 개체로 만들고, df_text DataFrame의 행에 추가한다.
    • 181행: 파일에서 추출한 텍스트가 담겨있는 df_text를 반환한다.

     

    4.3.3. get_txt_text 함수

    def get_txt_text(file_name) -> DataFrame:
        """
        txt 파일에서 text를 추출하여 DataFrame type으로 return
        :param file_name: 입력 파일명 (str type)
        :return: 입력 파일에서 추출한 text
        """
        # :return: 입력 파일에서 추출한 text에 형태소 분석기로 명사 추출한 DataFrame
        start_time = time.time()
        print('\r\nget_txt_text: ' + file_name)
        df_text = pd.DataFrame()
        line_number = 0
        with open(file_name, 'rt', encoding='UTF8') as file:
            for text in file:
                line_number += 1
                if text.strip() != '':
                    sr_text = Series([file_name, 'txt', line_number, text, f'{file_name}:{line_number}:{text}'],
                                     index=['FileName', 'FileType', 'Page', 'Text', 'Source'])
                    df_text = df_text.append(sr_text, ignore_index=True)
        print('text count: %d' % df_text.shape[0])
        print('line count: %d' % line_number)
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('[pid:%d] get_txt_text elapsed time: %s' % (os.getpid(), elapsed_time))
        # return get_word_list(df_text)
        return df_text

     

    • 228행: file을 UTF8 인코딩의 읽기 전용 텍스트 모드로 연다. (mode='rt')
    • 229행: file의 행(line)을 순회한다.
    • 231~234행: 행 텍스트를 Series 개체로 만들고, df_text DataFrame의 행에 추가한다.
    • 242행: 파일에서 추출한 텍스트가 담겨있는 df_text를 반환한다.

     

    4.3.4. get_db_comment_text 함수

    def get_db_comment_text(file_name) -> DataFrame:
        """
        db_comment 파일에서 text를 추출하여 DataFrame type으로 return
        :param file_name:  입력 파일명 (str type)
        :return: 입력 파일에서 추출한 text
        """
        # :return: 입력 파일에서 추출한 text에 형태소 분석기로 명사 추출한 DataFrame
        start_time = time.time()
        print('\r\nget_db_comment_text: %s' % file_name)
        excel_app = win32com.client.Dispatch('Excel.Application')
        full_path_file_name = os.path.abspath(file_name)
        excel_file = excel_app.Workbooks.Open(full_path_file_name, True)
    
        # region Table comment
        table_comment_sheet = excel_file.Worksheets(1)
        last_row = table_comment_sheet.Range("A1").End(-4121).Row  # -4121: xlDown
        table_comment_range = 'A2:D%s' % (str(last_row))
        print('table_comment_range : %s (%d rows)' % (table_comment_range, last_row - 1))
        table_comments = table_comment_sheet.Range(table_comment_range).Value2
        df_table = pd.DataFrame(list(table_comments),
                                columns=['DB', 'Schema', 'Table', 'Text'])
        df_table['FileName'] = full_path_file_name
        df_table['FileType'] = 'table'
        df_table['Page'] = 0
        df_table = df_table[df_table.Text.notnull()]  # Text 값이 없는 행 제거
        df_table['Source'] = df_table['DB'] + '.' + df_table['Schema'] + '.' + df_table['Table'] \
                             + '(' + df_table['Text'].astype(str) + ')'
        # print(df_table)
        # endregion
    
        # region Column comment
        column_comment_sheet = excel_file.Worksheets(2)
        last_row = column_comment_sheet.Range("A1").End(-4121).Row  # -4121: xlDown
        column_comment_range = 'A2:E%s' % (str(last_row))
        print('column_comment_range : %s (%d rows)' % (column_comment_range, last_row - 1))
        column_comments = column_comment_sheet.Range(column_comment_range).Value2
        df_column = pd.DataFrame(list(column_comments),
                                 columns=['DB', 'Schema', 'Table', 'Column', 'Text'])
        df_column['FileName'] = full_path_file_name
        df_column['FileType'] = 'column'
        df_column['Page'] = 0
        df_column = df_column[df_column.Text.notnull()]  # Text 값이 없는 행 제거
        df_column['Source'] = df_column['DB'] + '.' + df_column['Schema'] + '.' + df_column['Table'] \
                              + '.' + df_column['Column'] + '(' + df_column['Text'].astype(str) + ')'
        # print(df_column)
        # endregion
    
        excel_file.Close()
        df_text = df_column.append(df_table, ignore_index=True)
        # print(df_text)
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('[pid:%d] get_db_comment_text elapsed time: %s' % (os.getpid(), elapsed_time))
        print('text count: %s' % str(df_text.shape[0]))
        # return get_word_list(df_text)
        return df_text

     

    • 300행: win32com package로 MS Excel 프로그램의 instance를 생성한다. MS Excel이 실행되지 않은 상태라면 이 코드로 실행된다.
    • 302행: 위에서 생성한 MS Excel 프로그램 instance에서 .xls 또는 .xlsx 파일을 연다.
    • 305~317행: 테이블 comment가 저장되어 있는 엑셀 파일의 첫 번째 시트에서 Text를 추출한다.
    • 306행: 테이블 comment 시트의 가장 마지막 행 번호를 구한다. Range("A1").End(-4211).Row 에서 "-4211"은 "xlDown" 상수이다. 자세한 내용은 XlDirection enumeration (Excel) | Microsoft Docs 문서를 참조한다.
    • 309행: 테이블 comment 시트의 내용을 table_comments 변수로 읽는다. 이 방법은 Loop를 사용하지 않고 Range의 내용을 한 번에 memory로 읽는 방법이다. VBA 코딩 패턴: Range Loop-읽기(Read) 내용을 참조한다. 이 글은 엑셀 VBA로 설명되어 있으나 Python에서도 OLE Automation을 사용하면 거의 동일하게 적용할 수 있다.
    • 310~317행: table_comments를 DataFrame df_table로 변환하고 'FileName', 'FileType', 'Page', 'Source' 열(column)의 데이터를 추가한다.
    • 322~334행: 컬럼 comment가 저장되어 있는 엑셀 파일의 두 번째 시트에서 Text를 추출한다.
    • 323행: 컬럼 comment 시트의 가장 마지막 행 번호를 구한다. 306행과 동일한 방법을 사용한다.
    • 326행: 컬럼 comment 시트의 내용을 column_comments 변수로 읽는다. 309행과 동일한 방법을 사용한다.
    • 327~334행: column_comments를 DataFrame df_column으로 변환하고 'FileName', 'FileType', 'Page', 'Source' 열(column)의 데이터를 추가한다.
    • 339행: df_column과 df_table을 합쳐서 df_text를 만든다.
    • 347행: DB 테이블, 컬럼 comment가 저장된 엑셀 파일에서 추출한 텍스트가 담겨있는 df_text를 반환한다.

     

    4.3.5. get_hwp_text 함수

    def get_hwp_text(file_name) -> DataFrame:
        pass

    현재 구현되어 있지 않다. 향후 필요시 구현 예정이다.

     

    4.3.6. get_pdf_text 함수

    def get_pdf_text(file_name) -> DataFrame:
        pass

    현재 구현되어 있지 않다. 향후 필요시 구현 예정이다.

     

    4.4. get_word_list 함수

    단어 추출 도구에서 가장 핵심인 함수이다.

    def get_word_list(df_text) -> DataFrame:
        """
        text 추출결과 DataFrame에서 명사를 추출하여 최종 output을 DataFrame type으로 return
        :param df_text: 파일에서 추출한 text(DataFrame type)
        :return: 명사, 복합어(1개 이상의 명사, 접두사+명사+접미사) 추출결과(Dataframe type)
        """
        start_time = time.time()
        df_result = DataFrame()
    
        tagger = Mecab()
        # tagger = Komoran()
        row_idx = 0
        for index, row in df_text.iterrows():
            row_idx += 1
            if row_idx % 100 == 0:  # 100건마다 현재 진행상태 출력
                print('[pid:%d] current: %d, total: %d, progress: %3.2f%%' %
                      (os.getpid(), row_idx, df_text.shape[0], round(row_idx / df_text.shape[0] * 100, 2)))
            file_name = row['FileName']
            file_type = row['FileType']
            page = row['Page']
            text = str(row['Text'])
            source = (row['Source'])
            is_db = True if row['FileType'] in ('table', 'column') else False
            is_db_table = True if row['FileType'] == 'table' else False
            is_db_column = True if row['FileType'] == 'column' else False
            if is_db:
                db = row['DB']
                schema = row['Schema']
                table = row['Table']
                if is_db_column:
                    column = row['Column']
    
            if text is None or text.strip() == '':
                continue
            try:
                # nouns = mecab.nouns(text)
                # [O]ToDo: 연속된 체언접두사(XPN), 명사파생접미사(XSN) 까지 포함하여 추출
                # [O]ToDo: 명사(NNG, NNP)가 연속될 때 각각 명사와 연결된 복합명사 함께 추출
                text_pos = tagger.pos(text)
                words = [pos for pos, tag in text_pos if tag in ['NNG', 'NNP', 'SL']]  # NNG: 일반명사, NNP: 고유명사
                pos_list = [x for (x, y) in text_pos]
                tag_list = [y for (x, y) in text_pos]
                pos_str = '/'.join(pos_list) + '/'
                tag_str = '/'.join(tag_list) + '/'
                iterator = re.finditer('(NNP/|NNG/)+(XSN/)*|(XPN/)+(NNP/|NNG/)+(XSN/)*|(SL/)+', tag_str)
                for mo in iterator:
                    x, y = mo.span()
                    if x == 0:
                        start_idx = 0
                    else:
                        start_idx = tag_str[:x].count('/')
                    end_idx = tag_str[:y].count('/')
                    sub_pos = ''
                    # if end_idx - start_idx > 1 and not (start_idx == 0 and end_idx == len(tag_list)):
                    if end_idx - start_idx > 1:
                        for i in range(start_idx, end_idx):
                            sub_pos += pos_list[i]
                        # print('%s[sub_pos]' % sub_pos)
                        words.append('%s[복합어]' % sub_pos)  # 추가 형태소 등록
    
                if len(words) >= 1:
                    # print(nouns, text)
                    for word in words:
                        # print(noun, '\t', text)
                        if not is_db:
                            # sr_text = Series([file_name, file_type, page, text, word],
                            #                  index=['FileName', 'FileType', 'Page', 'Text', 'Word'])
                            df_word = DataFrame(
                                {'FileName': [file_name], 'FileType': [file_type], 'Page': [page], 'Text': [text],
                                 'Word': [word], 'Source': [source]})
                        elif is_db_table:
                            # sr_text = Series([file_name, file_type, page, text, word, db, schema, table],
                            #                  index=['FileName', 'FileType', 'Page', 'Text', 'Word', 'DB', 'Schema', 'Table'])
                            df_word = DataFrame(
                                {'FileName': [file_name], 'FileType': [file_type], 'Page': [page], 'Text': [text],
                                 'Word': [word], 'DB': [db], 'Schema': [schema], 'Table': [table], 'Source': [source]})
                        elif is_db_column:
                            # sr_text = Series([file_name, file_type, page, text, word, db, schema, table, column],
                            #                  index=['FileName', 'FileType', 'Page', 'Text', 'Word', 'DB', 'Schema', 'Table', 'Column'])
                            df_word = DataFrame(
                                {'FileName': [file_name], 'FileType': [file_type], 'Page': [page], 'Text': [text],
                                 'Word': [word], 'DB': [db], 'Schema': [schema], 'Table': [table], 'Column': [column],
                                 'Source': [source]})
                        # df_result = df_result.append(sr_text, ignore_index=True)  # Todo: append를 concat으로 바꾸기
                        df_result = pd.concat([df_result, df_word], ignore_index=True)
            except Exception as ex:
                print('[pid:%d] Exception has raised for text: %s' % (os.getpid(), text))
                print(ex)
    
        print(
            '[pid:%d] input text count:%d, extracted word count: %d' % (os.getpid(), df_text.shape[0], df_result.shape[0]))
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('[pid:%d] get_word_list finished. total: %d, elapsed time: %s' %
              (os.getpid(), df_text.shape[0], elapsed_time))
        return df_result

     

    • 35행: 자연어 형태소 분석기 Mecab 객체를 생성한다. Mecab이 아닌 다른 tagger를 사용하려면 여기에서 package명을 변경한다.
    • 38행: DataFrame df_text의 행을 순회한다.
    • 64행: pos 함수로 형태소 분석기의 품사 tagging을 실행한다. 품사 tagging과 관련한 내용은 별도로 정리하겠다.
      • 품사 tagging 함수 pos는 입력 문자열을 품사 단위로 분해하고 각 단위가 어떤 품사인지 표시(tagging)한 문자열을 반환한다.
      • 예를 들어, text가 '사용자는 기능적 요구사항과 비기능적 요구사항을 정의한다.'인 경우, pos 함수의 실행결과는 '[('사용', 'NNG'), ('자', 'XSN'), ('는', 'JX'), ('기능', 'NNG'), ('적', 'XSN'), ('요구', 'NNG'), ('사항', 'NNG'), ('과', 'JC'), ('비', 'XPN'), ('기능', 'NNG'), ('적', 'XSN'), ('요구', 'NNG'), ('사항', 'NNG'), ('을', 'JKO'), ('정의', 'NNG'), ('한다', 'XSV+EF'), ('.', 'SF')]'이다.
      • 위 예시에 tagging 된 품사 중 'NNG'는 일반 명사, 'XSN'는 명사 파생 접미사, 'JX'는 보조사, 'JC'는 접속 조사, 'XPN'은 체언 접두사, 'JKO'는 목적격 조사, 'XSV+EF'는 동사 파생 접미사+종결 어미, 'SF'는 마침표/물음표/느낌표를 의미한다.
    • 65행: 품사 tagging 결과에서 표준 단어 후보로 가장 적합한 품사인 일반 명사(NNG), 고유 명사(NNP), 외국어(SL)를 골라낸다. 외국어(SL)는 알파벳으로 구성된 약어를 표준 단어 후보로 추출하기 위해 지정하였다.
    • 70행: 정규표현식(regula expression)을 이용하여 '(NNP/|NNG/)+(XSN/)*|(XPN/)+(NNP/|NNG/)+(XSN/)*|(SL/)+' 패턴을 찾는다.
      • 이 패턴은 다음 세 가지 중 하나를 찾아낸다.
        • (NNP/|NNG/)+(XSN/)*: (고유 명사 또는 일반명사) 1개 이상 + 명사 파생 접미사 0개 이상
        • (XPN/)+(NNP/|NNG/)+(XSN/)*: 체언 접두사 1개 이상 + (고유 명사 또는 일반명사) 1개 이상 + 명사 파생 접미사 0개 이상
        • (SL/)+: 외국어 1개 이상
    • 71~84행: 위 정규표현식 패턴으로 찾아지는 단어들을 연결하고 suffix '[복합어]'를 붙여서 추출 단어 목록에 추가한다. 나중에 표준 단어 사전 정제 작업을 할 때, 복합어로 추출된 단어를 식별하기 위해 일부러 suffix를 붙여둔다.
    • 86~110행: 추출된 단어를 출처와 파일 형식 등의 부가 속성을 더하여 DataFrame에 담는다.
    • 122행: 추출된 단어 목록이 담겨있는 df_result를 반환한다. 

     

    참고로, 다른 품사 패턴을 추가로 추출하려면 65행과 70행을 수정하면 된다.

     

    4.5. make_word_cloud 함수

    def make_word_cloud(df_group, now_dt, out_path):
        """
        명사의 빈도를 구한 DataFrame으로 word cloud 그리기
        :param df_group: 명사 빈도 DataFrame
        :param now_dt: 현재 날짜 시각
        :param out_path: 출력경로
        :return: None
        """
        start_time = time.time()
        print('\r\nstart make_word_cloud...')
        from wordcloud import WordCloud
        import matplotlib.pyplot as plt
        # malgun.ttf # NanumSquare.ttf # NanumSquareR.ttf NanumMyeongjo.ttf # NanumBarunpenR.ttf # NanumBarunGothic.ttf
        wc = WordCloud(font_path='.\\font\\NanumBarunGothic.ttf',
                       background_color='white',
                       max_words=500,
                       width=1800,
                       height=1000
                       )
    
        # print(df_group.head(10))
        words = df_group.to_dict()['Freq']
        # print(words)
        # words = df_group.T.to_dict('list')
        wc.generate_from_frequencies(words)
        wc.to_file('%s\\wordcloud_%s.png' % (out_path, now_dt))
        # plt.axis('off')
        end_time = time.time()
        # elapsed_time = end_time - start_time
        elapsed_time = str(datetime.timedelta(seconds=end_time - start_time))
        print('make_word_cloud elapsed time: %s' % elapsed_time)

     

    이 함수에서는 WordCloud package를 사용한다.

    WordCloud 예시
    WordCloud 예시

     

    • 258~263행: WordCloud 개체를 생성한다.
      • font 폴더 하위에 있는 NanumBarunGothic.ttf(나눔바른고딕) 글꼴 파일을 사용하였다. 다른 글꼴로 변경하려면 font 폴더에 글꼴 파일을 복사하고 그 파일명을 지정하면 된다.
      • background_color, max_words, width, height는 원하는 값으로 변경해서 사용하면 된다.
    • 266행: DataFrame df_group에서 Key는 Index(단어), Value는 'Freq'(빈도)로 구성된 dictionary words를 생성한다.
    • 269행: 빈도가 포함된 words로부터 WordCloud 이미지를 생성한다.
    • 270행: 생성된 WordCloud 이미지를 저장한다.

     


    여기까지 소스코드에 대한 설명은 마쳤다. 다음에는 소스코드에 대한 부가설명과 품사 tagging 관련 내용을 살펴보겠다.

    댓글

    💲 추천 글