머신 러닝 모델에 [문장과 해당 문장의 label]을 학습시켜야 했고, 이때 필요한 dataset은 최소 1000여개가 필요했다. RNN 모델은 이미 세팅을 완료하였고, 충분한 학습용 dataset만 구축되면 학습을 진행하고 문장으로 입력된 input에 대해 중증도 레벨을 판단하는 인공지능 모델로 이어질 수 있다.
천여개의 Dataset 일일이 만들어줄 수 없어, 자동화할 수 있는 방안을 모색해보았다.
먼저, 중증도 레벨과 증상에 대한 키워드들이 담긴 PDF 파일을 크롤링하여 증상 보고 문장에 들어갈 수 있는 키워드들을 저장해주었다.
import pdfplumber
import re
adult_symptoms_info = []
child_symptoms_info = []
# 15세 이상 page 5~74
# 15세 미만 page 75~158
with pdfplumber.open('./emergency_level.pdf') as pdf:
for i in range(5, 158):
page = pdf.pages[i]
page_text = page.extract_text()
# 전체 text를 \n 기준으로 나누기
page_text_arr = page_text.split("\n")
for j in range(1, len(page_text_arr)):
# 숫자로 끝나는 문장만 추출
symptoms_text = re.findall(r".*[0-9]$", page_text_arr[j])
if(symptoms_text):
print(symptoms_text)
# 알파벳 (코드)를 기준으로 쪼개기
target_symptoms = re.split("[A-Z]+", symptoms_text[0])
target_symptoms_wo_spaces = [part.strip() for part in target_symptoms]
# 15세 이상 환자에 대한 증상 키워드
if(5 <= i <= 74):
adult_symptoms_info.append([target_symptoms_wo_spaces[0], target_symptoms_wo_spaces[1]])
# 15세 미만 환자에 대한 증상 키워드
elif(75 <= i <= 158):
if(len(target_symptoms_wo_spaces) > 1):
child_symptoms_info.append([target_symptoms_wo_spaces[0], target_symptoms_wo_spaces[1]])
# 중복되는 증상 제거
unique_adult_data = set(tuple(x) for x in adult_symptoms_info)
unique_adult_list = [list(x) for x in unique_adult_data]
unique_child_data = set(tuple(x) for x in child_symptoms_info)
unique_child_list = [list(x) for x in unique_child_data]
키워드를 다 가져왔다고 하더라도 이를 기반으로 천여개의 문장 dataset을 만들어주기는 어려워서 ChatGPT api를 활용하여 우리의 키워드들이 담긴 list를 돌면서 GPT에 각 증상 레벨별 타당한 문장을 생성해줄 수 있도록 코드를 짜보았다.
import os
import openai
from dotenv import load_dotenv
load_dotenv()
openai.organization = os.environ.get("ORGANIZATION_KEY")
openai.api_key = os.environ.get("OPENAPI_KEY")
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "system",
"content":
"""
너는 구급차에 타고 있는 응급구조사 역할을 맡을거고 현재 환자는 구급차에 타고 있는 상태야.
1단계가 가장 위급하고, 5단계가 가장 경미한 증상에 대한 상황이야.
다른 설명없이 딱 문장만 제시해줘.
말하는 것처럼 작성하는게 아닌 보고서처럼 작성해줘.
문장 하나당 큰따옴표로 구분해주고 줄바꿈만 해주면 돼.
환자 증상 상태에 대한 문장을 최소 25자로 자세하게 써줘.
"""
},
{
"role": "user",
"content":
f"""
{adult_symptoms[i][0]}, {adult_symptoms[i][1]}의 증상을 호소하는 환자에 대해 ktas 중증도 분류에 따라 분류 등급 1, 2, 3, 4, 5단계에 해당하는 상황 예시를 각 단계별로 3개씩 뽑아줘.
"""
}
]
)
result = completion.choices[0].message.content
with open("sentences-adult.txt", "a", encoding="utf-8") as file:
file.write(results + "\n")
gpt-3.5 모델 사용시 1분에 3번의 요청만 가능하다는 제약이 있어, 1분에 3번만 요청을 하도록 scheduling을 해주었다.
import time, schedule
def schedule_api_calls():
i = 0
def job():
nonlocal i
print(f"{i}", ": ", adult_symptoms[i])
if i < len(adult_symptoms):
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[]
i += 1
else:
schedule.cancel_job(job)
schedule.every(20).seconds.do(job)
schedule_api_calls()
while True:
schedule.run_pending()
time.sleep(1)