brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Jun 24. 2024

 AI 2탄-3. PDF에서 데이터 추출하여 그래프

나만의 챗GPT 만들기-3/5

<11> 서비스4- PDF에서 데이터 추출하여 그래프 그리기- 변경됨, 오류 수정필요


청구서 PDF파일이라는 비정형 데이터를 읽어 텍스트화

챗GPT API를 이용해 정형 데이터로 만들어보자.



<1> PDF에서 데이터 추출 순서는?

<2> PDF를 불러 구조화된 데이터 JSON으로 변환하자 (실습)

<3> JSON을 CSV로 출력하기 (실습)

<4> 그래프로 그리기 (실습)

<5> 활용 사례




<1> PDF에서 데이터 추출 순서는?


7장

PDF에서 데이터를  추출해 그래프 그리기


https://github.com/ychoi-kr/ChatGPT-API-Python/tree/main/ch7/3-2-1




<2> PDF를 불러 구조화된 데이터 JSON으로 변환하자


1

PDF를 불러와 챗GPT의 API를 사용하여 JSON형식으로 변환하자.

비정형 데이터를 정형 데이터로 변환할 때 JSON형식을 많이 사용한다.



2

1work  디렉터리

data폴더 만들고 PDF파일을 저장한다.

data 폴더  아래 5개의 PDF를 불러온다.




3

# VsCode

file > Open folder  > 1 work



4

# PDF를 불러오기 위해 pypdf 라이브러리를 사용한다.

# 터미널, pypdf설치


pip install pypdf



5

# 5개의 PDF를 불러와서 JSON코드로 만들어 보자.


1) # PDF를 JSON 으로 변환

# load_pdf.py  



import os

import re

import json

from langchain_community.document_loaders import PyPDFLoader

from langchain_openai import ChatOpenAI

from langchain.schema import HumanMessage



def extract_and_parse_json(text):

    """

    텍스트에서 JSON 문자열을 추출하여 사전형으로 변환하는 기능

    """

    try:

        # 'text'에서 JSON 문자열 추출하기

        match = re.search(r"\{.*\}", text, re.DOTALL)

        json_string = match.group() if match else ""

        # JSON 문자열을 파이썬의 딕셔너리형으로 변환

        return json.loads(json_string)

    except (AttributeError, json.JSONDecodeError):

        # 두 작업 중 하나라도 실패하면 빈 딕셔너리를 반환한다.

        return {}



def load_all_pdfs(directory):

    """

    directory 폴더 아래의 PDF 파일을 읽어와 JSON 형식의 데이터 배열을 반환하는 함수

    """

    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.0)    

    # directory 폴더 내의 PDF 파일 목록을 얻음

    pdf_files = [f for f in os.listdir(directory) if f.endswith(".pdf")]    

    # 각 PDF의 JSON을 저장할 배열을 정의

    contents = []    

    for pdf_file in pdf_files:

        loader = PyPDFLoader(os.path.join(directory, pdf_file))

        pages = loader.load_and_split()

        prompt = f""""

        다음 데이터는 청구서 PDF 데이터를 텍스트로 변환한 것입니다.

        청구서 데이터를 다음의 키를 가진 JSON 형식으로 변환하세요.

        키에 해당하는 텍스트를 찾지 못하면 값을 비워둡니다.        

        또한, 다음 내용은 당사 정보이므로 JSON 출력에 포함하지 마십시오.

         - AI 비즈니스 솔루션 주식회사

         - ㉾ 05500 서울특별시 송파구 올림픽로 1234번지 테크빌딩 789층        

        ###        

        키:

        - 발행일

        - 청구 번호

        - 인보이스 번호

        - 회사명

        - 주소

        - 제목

        - 청구 금액

        - 결제 기한

        - 상세 정보

        - 소계

        - 소비세

        - 청구금액(총액)

        - 송금처        

        ###        

        다음은 청구서 데이터를 JSON 형식으로 변환한 예시입니다.        

        ###        

        예:

        [(

            "날짜": "2023년 10월 31일",

            "청구 번호": "2023-1031"

            "인보이스 번호": "T0123456789012",

            "회사명": "테크놀로지 솔루션즈 주식회사"

            "주소": "㉾ 05500 서울특별시 송파구 올림픽로 1234번지 테크빌딩 789층",

            "제목": "웹사이트 리뉴얼 프로젝트",

            "청구 금액": "2,275,000",

            "지급 기한": "2023년 11월 30일"

            "상세": "디렉팅 비용 ₩1,000,000 / 개발 비용 ₩1,500,000",

            "소계": "2,500,000",

            "소비세": "250,000",

            "청구금액(총액)": "2,275,000",

            "입금처": "AA은행 BB지점 보통 1234567"

        )]        

        ###        

        데이터:

        {pages[0].page_content}

        """        

        result = llm.invoke([HumanMessage(content=prompt)])        

        contents.append(extract_and_parse_json(result.content))

    return contents




6

2) # JSON을 CSV 파일로 변환

# app.py


import load_pdf

import csv

import matplotlib.pyplot as plt

import pandas as pd

from matplotlib.ticker import MultipleLocator, FuncFormatter

def write_to_csv(billing_data):

    # CSV 파일명

    csv_file = "invoices.csv"


    # 헤더를 결정 (JSON의 키에서)

    header = billing_data[0].keys()


    # CSV 파일을 쓰기 모드로 열어 데이터를 쓰기

    with open(csv_file, 'w', newline='', encoding='utf-8') as f:

        writer = csv.DictWriter(f, fieldnames=header)

        writer.writeheader()

        writer.writerows(billing_data)


def main():

    # data 폴더의 모든 PDF 파일을 읽어 JSON 형식의 데이터를 받음

    billing_data = load_pdf.load_all_pdfs('data')

    print("로딩이 완료되었습니다")


    # JSON 형식의 데이터를 CSV 파일로 작성

    write_to_csv(billing_data)

    print("CSV 파일 쓰기가 완료되었습니다")


if __name__ == "__main__":

    main()




6

#터미널

pip install langchain-community==0.0.17

pip install langchain==0.1.4 langchain-core==0.1.17

pip install langchain-openai==0.0.5



7

python load_pdf.py


JSON 파일로 변환되었다.

# 따로 결과 응답은 없다. 






<3> JSON을 CSV로 출력하기


1

# CSV 파일 만드는 app.py을 만들어보자.

3-2-1> 



2

# 실행

python app.py


D:\1 work> python app.py

로딩이 완료되었습니다

CSV 파일 쓰기가 완료되었습니다



결과

invoices.csv 파일이 생김.

생성된 CSV파일을 보자.

PDF 데이터가 CSV로 정리되어 있다.






<4> 그래프로 그리기


ch7\3-3-1>


1

# CSV를 그래프로  그려보자.

# 필요한 라이브러리 설치 = matplotlib pandas

pip install matplotlib pandas


D:\1 work> pip install matplotlib pandas



2

# load.py 실행 시켜도 아무 변화 없음.


PS C:\0ai2\0\ch7\3-3-1> python.exe .\app.py     

데이터 로드 완료

CSV 파일 쓰기 완료

Traceback (most recent call last):

  File "C:\0ai2\0\ch7\3-3-1\app.py", line 60, in <module>

    main()

  File "C:\0ai2\0\ch7\3-3-1\app.py", line 56, in main

    draw_graph("invoices.csv")

  File "C:\0ai2\0\ch7\3-3-1\app.py", line 38, in draw_graph

    ax.set_ylim(0, max(df["청구금액(총액)"]) + 100000)

                   ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

TypeError: can only concatenate str (not "int") to str







# 그래프 그려짐





<5> 활용 사례


# 비정형 데이터를 사용법


고객의 피드백과 리뷰 분석

SNS에 게시물 분류

계약서 분석 등




다음 

챗봇 만들기 = PDF 내용을 바탕으로 챗봇이 답변.


https://brunch.co.kr/@topasvga/3868


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari