나만의 챗GPT 만들기-3/5
청구서 PDF파일이라는 비정형 데이터를 읽어 텍스트화
챗GPT API를 이용해 정형 데이터로 만들어보자.
7장
PDF에서 데이터를 추출해 그래프 그리기
https://github.com/ychoi-kr/ChatGPT-API-Python/tree/main/ch7/3-2-1
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 파일로 변환되었다.
# 따로 결과 응답은 없다.
1
# CSV 파일 만드는 app.py을 만들어보자.
3-2-1>
2
# 실행
python app.py
D:\1 work> python app.py
로딩이 완료되었습니다
CSV 파일 쓰기가 완료되었습니다
결과
invoices.csv 파일이 생김.
생성된 CSV파일을 보자.
PDF 데이터가 CSV로 정리되어 있다.
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
# 그래프 그려짐
# 비정형 데이터를 사용법
고객의 피드백과 리뷰 분석
SNS에 게시물 분류
계약서 분석 등
https://brunch.co.kr/@topasvga/3868