✨ 개요
이 문서는 제품 설명 텍스트만을 기반으로 가격을 예측하는 프로젝트의 일환으로, 최신 Frontier 모델들의 성능을 평가하는 과정을 정리한 것입니다.
먼저, 기존에 전처리된 테스트 데이터를 활용해 사람이 직접 예측한 결과를 기준 삼아 비교하고,
그 다음으로 다양한 Frontier 모델 (예: gpt-4o-mini, gpt-4o-2024-08-06, Claude 3.5 Sonnet)을 이용해
모델별 가격 예측 성능을 테스트합니다.
특히, Frontier 모델들은 별도의 추가 학습 없이 바로 테스트 데이터에 적용하며,
정확성, 응답 포맷 처리(get_price), 비용 이슈(호출 비용 1~2센트 발생) 등에 주의하여 진행합니다.
이 문서는 다음을 목표로 합니다:
- Frontier 모델이 제품 가격 예측 문제에서 얼마나 잘 작동하는지 평가
- 사람이 예측한 결과와 Frontier 모델 결과 비교
- gpt와 Claude 계열 모델의 실제 응답 특성 및 테스트 결과 분석
- 추후 모델 개발 및 최적화 방향에 대한 인사이트 확보
📌 주요 테스트 대상
- Human Prediction (사람 직접 입력)
- GPT-4o-mini
- GPT-4o (2024-08-06 Frontier 버전)
- Claude 3.5 Sonnet (2024년 6월 버전)
1. 실험 준비 (Setup)
라이브러리 임포트
# 📦 필수 라이브러리 임포트
import os # 🧭 파일 경로 작업 및 환경 변수 관리 (예: API 키 불러오기)
import re # 🔍 정규 표현식 처리 (문자열 검색, 치환 등에 사용)
import math # ➗ 수학 관련 함수 제공 (루트, 로그, 삼각함수 등)
import json # 📄 JSON 형식의 데이터 읽기/쓰기
import random # 🎲 무작위 수 생성, 리스트 섞기 등 랜덤 작업
from dotenv import load_dotenv # 🔐 .env 파일로부터 환경 변수 로드
# 🤖 AI 모델 및 서비스 관련 라이브러리
from huggingface_hub import login # 🧠 HuggingFace Hub 로그인 (모델 다운로드/업로드에 필요)
import matplotlib.pyplot as plt # 📊 데이터 시각화를 위한 그래프 라이브러리
import numpy as np # 🔢 수치 계산 및 배열 연산을 위한 라이브러리
import pickle # 💾 파이썬 객체를 파일로 저장하거나 불러오기 위한 직렬화 라이브러리
from collections import Counter # 📈 리스트나 데이터 내 항목들의 빈도수 계산
# 🧠 LLM API 클라이언트
from openai import OpenAI # 🛠️ OpenAI API 사용을 위한 클라이언트 라이브러리 (예: GPT 모델 호출)
from anthropic import Anthropic # 🛠️ Anthropic API 사용을 위한 클라이언트 라이브러리 (예: Claude 모델 호출)
환경 변수 설정 및 API 키 불러오기
# 🌎 환경 변수 설정
load_dotenv(override=True)
# 🔐 .env 파일에 저장된 환경 변수들을 현재 실행 환경에 불러옵니다
# - override=True 옵션을 주면, 이미 존재하는 환경 변수도 덮어쓸 수 있습니다
# 📌 필요한 API 키를 환경 변수로 설정 (없을 경우 기본값 사용)
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')
# - OPENAI_API_KEY를 환경 변수에서 불러와 설정합니다
# - 만약 .env 파일에 값이 없으면 'your-key-if-not-using-env'라는 기본 문자열을 사용합니다
os.environ['ANTHROPIC_API_KEY'] = os.getenv('ANTHROPIC_API_KEY', 'your-key-if-not-using-env')
# - ANTHROPIC_API_KEY도 동일한 방식으로 설정합니다 (Claude 모델 사용 시 필요)
os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', 'your-key-if-not-using-env')
# - HuggingFace Hub에 접근할 때 필요한 HF_TOKEN도 환경 변수로 설정합니다
HuggingFace Hub 로그인
# 🔐 HuggingFace Hub 로그인
hf_token = os.environ['HF_TOKEN']
# - 환경 변수에서 HuggingFace 액세스 토큰(HF_TOKEN)을 불러옵니다
# - 이 토큰은 모델 다운로드/업로드 등 HuggingFace 서비스 이용 시 필요합니다
login(hf_token, add_to_git_credential=True)
# - HuggingFace Hub에 로그인합니다
# - add_to_git_credential=True 옵션을 주면 Git 인증 정보에도 저장되어,
# 추후 Git 기반 명령어(HuggingFace 관련 pull/push 등) 사용 시 자동 로그인됩니다
🧪 테스트 기능 분리 및 호출
# 🧪 테스트 기능 분리 및 호출
# - 테스트 관련 코드를 별도의 패키지(testing)로 분리했습니다
# - 이제 Tester 클래스의 test() 메서드를 호출해서,
# 원하는 함수(function_name)와 테스트 데이터셋(test_dataset)을 넣어 테스트할 수 있습니다
from items import Item # 📦 Item 클래스 가져오기 (개별 제품 정보를 다루는 클래스)
from testing import Tester # 🧪 Tester 클래스 가져오기 (모델/함수 성능 테스트를 담당)
🤖 LLM(대형 언어 모델) 클라이언트 인스턴스 생성
# 🤖 LLM(대형 언어 모델) 클라이언트 인스턴스 생성
openai = OpenAI()
# - OpenAI API를 사용하기 위한 클라이언트 객체 생성
# - 예: GPT-4o, GPT-4, GPT-3.5 등의 모델 호출에 사용
claude = Anthropic()
# - Anthropic API를 사용하기 위한 클라이언트 객체 생성
# - 예: Claude 3 모델군(Claude 3 Opus, Sonnet, Haiku 등) 호출에 사용
📈 주피터 노트북(Jupyter Notebook)에서 그래프를 바로 출력하도록 설정
# 📈 주피터 노트북(Jupyter Notebook)에서 그래프를 바로 출력하도록 설정
%matplotlib inline
# - matplotlib으로 그린 그래프를 별도 창이 아닌,
# 노트북 셀 내부에 바로 표시해줍니다
# - 노트북 환경에서 시각화할 때 기본적으로 사용하는 매직 명령어입니다
📦 데이터셋 불러오기 (train/test pickle)
# 📦 이전에 저장해둔 데이터 불러오기 (피클 파일 사용)
# - 시간이 오래 걸리는 데이터 전처리 과정을 다시 수행하지 않기 위해
# 미리 저장해둔 'train.pkl'과 'test.pkl' 파일을 불러옵니다
with open('train.pkl', 'rb') as file:
train = pickle.load(file)
# 🛠️ 'train.pkl' 파일을 읽어서 train 데이터셋으로 복원
with open('test.pkl', 'rb') as file:
test = pickle.load(file)
# 🛠️ 'test.pkl' 파일을 읽어서 test 데이터셋으로 복원
2. 사람 예측 결과 준비 (Preparing Human Predictions)
📝 테스트 세트 일부를 CSV로 저장
# 📄 CSV 파일로 테스트 데이터 일부 저장
import csv
with open('human_input.csv', 'w', encoding="utf-8") as csvfile:
writer = csv.writer(csvfile)
for t in test[:250]:
writer.writerow([t.test_prompt(), 0])
# - 각 테스트 샘플의 프롬프트를 가져와 CSV에 기록
# - 두 번째 열(0)은 기본 정답 값(placeholder)로 입력
test
데이터셋에서 앞 250개 항목을 골라 CSV 파일로 저장합니다.
각 줄에는 프롬프트 텍스트 (t.test_prompt()
)와 임시 레이블(0) 이 함께 기록됩니다.
이 CSV 파일은 나중에 사람이 직접 읽거나, 다른 평가용 입력으로 사용할 수 있습니다.
📥 사람 예측 결과(human_output.csv) 읽어오기
# 📄 CSV 파일에서 사람 예측 결과 불러오기
human_predictions = []
with open('human_output.csv', 'r', encoding="utf-8") as csvfile:
reader = csv.reader(csvfile)
for row in reader:
human_predictions.append(float(row[1]))
# - CSV 파일의 각 행(row)에서 두 번째 열(row[1]) 값을 가져옴
# - 값을 float(실수형)으로 변환해서 human_predictions 리스트에 추가
human_output.csv
파일을 열어, 두 번째 열(사람이 입력한 예측값) 을 읽고,
human_predictions
리스트에 실수형(float) 으로 저장합니다.
이렇게 하면 사람이 작성한 결과를 코드 안에서 사용할 수 있게 됩니다.
🧠 사람 가격 예측 함수(human_pricer) 정의
# 🧮 특정 아이템에 대한 사람 예측 가격 반환 함수
def human_pricer(item):
idx = test.index(item)
# - 주어진 item이 test 리스트에서 몇 번째(index)인지 찾는다
return human_predictions[idx]
# - 해당 인덱스에 대응하는 사람 예측 결과를 반환한다
주어진 item
이 테스트 데이터(test) 안에서 몇 번째인지 찾은 다음,
같은 순서에 있는 human_predictions
값을 찾아서 반환하는 함수입니다.
즉, 사람이 예상한 가격을 코드에서 쉽게 불러올 수 있게 해줍니다.
🧪 사람 예측 결과 테스트(Tester.test(human_pricer, test))
# 🧪 Human Pricer 함수 테스트
Tester.test(human_pricer, test)
# - human_pricer 함수를 test 데이터셋에 대해 평가합니다
# - Tester 클래스가 내부적으로 정확도, 오류율 등을 계산해줍니다
human_pricer
함수를 테스트 데이터에 적용해서, 사람이 예측한 가격이 얼마나 잘 맞는지 자동으로 평가합니다.
결과는 아마 RMSE, MAE 같은 수치로 나올 가능성이 높아요.
3. Frontier 모델용 프롬프트 준비 (Preparing Prompts for Frontier Models)
🛠️ Frontier 모델을 위한 프롬프트 포맷(messages_for)
# 🧹 Frontier 모델에 맞는 깔끔한 프롬프트 만들기
# - 우리가 직접 모델을 학습시킬 때는 문제를 단순하게 만들 필요가 있지만,
# - Frontier 모델(OpenAI, Anthropic 등)은 고성능이기 때문에
# 별도의 문제 단순화 없이 바로 복잡한 입력을 받을 수 있습니다.
def messages_for(item):
system_message = "You estimate prices of items. Reply only with the price, no explanation"
# - 시스템 프롬프트: 역할 지시 (설명 없이 가격만 답변하도록 제한)
user_prompt = item.test_prompt().replace(" to the nearest dollar", "").replace("\n\nPrice is $", "")
# - 사용자 입력 생성: 기존 프롬프트에서 "to the nearest dollar" 문구와
# "Price is $" 부분을 제거해서 더 자연스럽고 간결하게 만듭니다
return [
{"role": "system", "content": system_message},
{"role": "user", "content": user_prompt},
{"role": "assistant", "content": "Price is $"}
# - assistant 역할이 답변을 "Price is $" 형태로 시작하도록 유도
]
Frontier 모델용 프롬프트를 준비하는 함수입니다.
가격만 깔끔하게 답변하도록 시스템 메시지를 설정하고, 사용자 입력(user_prompt)에서는 불필요한 문구를 제거해서 모델이 더 정확하게 예측하도록 돕습니다.
이렇게 만들어진 프롬프트 리스트는 Frontier API 호출 시 바로 사용할 수 있어요!
🧪 프롬프트 테스트 예시
# 🧪 test 데이터 중 첫 번째 아이템으로 프롬프트 생성 테스트
messages_for(test[0])
# - test 리스트에서 첫 번째 아이템(test[0])을 가져와
# messages_for() 함수를 통해 Frontier 모델용 프롬프트 형식을 생성합니다
# - 출력 결과를 통해 프롬프트 구성이 잘 되었는지 확인할 수 있습니다
테스트 데이터 중 하나를 사용해 messages_for 함수가 올바르게 프롬프트를 만드는지 직접 확인하는 과정입니다.
이 결과는 Frontier 모델(OpenAI GPT, Anthropic Claude 등) 호출할 때 바로 사용할 수 있습니다.
4. 가격 추출 유틸리티 함수 (Utility Function for Price Extraction)
🛠️ 문자열에서 가격 추출 함수(get_price)
# 🔎 문자열 안에서 가격(숫자)만 추출하는 함수
def get_price(s):
s = s.replace('$', '').replace(',', '')
# - 문자열 안의 달러 기호($)와 쉼표(,)를 제거합니다
match = re.search(r"[-+]?\d*\.\d+|\d+", s)
# - 정규 표현식을 사용해 숫자(정수 또는 소수)를 찾습니다
return float(match.group()) if match else 0
# - 숫자를 찾았다면 float형으로 변환해 반환하고,
# - 찾지 못했다면 기본값 0을 반환합니다
문자열 안에 있는 달러 기호($), 쉼표(,) 를 없애고, 순수한 숫자(가격) 만 추출해서 float
형식으로 돌려주는 함수입니다.
만약 숫자가 하나도 없으면 기본으로 0을 반환합니다.
🧪 가격 추출 테스트 예시
# 🔍 get_price 함수 테스트
get_price("The price is roughly $99.99 because blah blah")
# - 문자열 안에 있는 "$99.99"를 인식하고
# - 달러 기호를 제거한 후 숫자 99.99를 float 타입으로 반환합니다
# - 예상 결과: 99.99
주어진 문장에서 가격($99.99) 을 정확히 추출해서 99.99
라는 실수(float) 값으로 변환해 반환합니다.
get_price()
함수가 실제 데이터에서도 제대로 동작하는지 간단히 검증하는 과정입니다.
5. Frontier 모델별 테스트 (Testing Frontier Models)
5-1-1. 🤖 gpt-4o-mini 예측 함수(gpt_4o_mini)
# 🤖 gpt-4o-mini 모델로 가격 예측하는 함수
def gpt_4o_mini(item):
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=messages_for(item),
seed=42,
max_tokens=5
)
# - gpt-4o-mini 모델을 호출해 응답을 받습니다
# - messages_for(item)을 통해 생성한 프롬프트를 입력으로 제공합니다
# - seed=42로 설정해 결과를 재현 가능하게 만듭니다
# - max_tokens=5로 응답 길이를 짧게 제한 (숫자 하나만 받으면 되기 때문)
reply = response.choices[0].message.content
# - 모델 응답에서 실제 텍스트(가격 예측 결과)만 추출합니다
return get_price(reply)
# - 추출한 텍스트에서 숫자(가격)만 골라내어 반환합니다
주어진 item
에 대해 gpt-4o-mini 모델을 호출하여, 가격만 깔끔하게 추출해서 반환하는 함수입니다.
seed
와 max_tokens
를 설정해서 결과를 일정하게 유지하고, get_price() 함수를 이용해 숫자만 정확히 뽑아냅니다.
5-1-2. 🔍 test 데이터 첫 번째 항목의 실제 가격 확인
# 🔎 test 데이터 첫 번째 항목의 실제 가격 확인
test[0].price
# - test 리스트에서 첫 번째 아이템(test[0])의 실제 가격을 가져옵니다
# - 모델이 예측한 가격과 비교할 기준값(정답값, ground truth)입니다
test[0]
은 테스트 데이터셋의 첫 번째 제품을 의미합니다.
.price
를 통해 그 제품의 실제 가격(정답)을 가져옵니다.
이 값은 모델이 예측한 가격과 정확도를 비교할 때 기준으로 사용됩니다.
5-1-3. 🧪 gpt-4o-mini 테스트 결과(Tester.test(gpt_4o_mini, test))
# 🧪 gpt-4o-mini 모델을 test 데이터셋에 대해 평가
Tester.test(gpt_4o_mini, test)
# - gpt_4o_mini 함수를 test 데이터셋 전체에 적용해 성능을 평가합니다
# - Tester 클래스가 자동으로 오차율, 정확도 등의 평가 지표를 계산합니다
# - 사람이 직접 예측한 결과와 Frontier 모델(gpt-4o-mini) 결과를 비교하는 데 활용할 수 있습니다
gpt-4o-mini 모델이 테스트 데이터에서 가격을 얼마나 잘 예측하는지 평가합니다.
Tester.test()
가 자동으로 성능 지표를 계산해서, "모델이 실제 가격에 얼마나 근접했는지" 알려줍니다.
5-2-1. 🚀 gpt-4o-2024-08-06 예측 함수(gpt_4o_frontier)
# 🚀 gpt-4o Frontier 버전으로 가격 예측하는 함수
def gpt_4o_frontier(item):
response = openai.chat.completions.create(
model="gpt-4o-2024-08-06",
messages=messages_for(item),
seed=42,
max_tokens=5
)
# - 최신 gpt-4o-2024-08-06 Frontier 모델을 호출합니다
# - messages_for(item) 함수로 생성한 프롬프트를 입력으로 전달합니다
# - seed=42로 결과를 재현 가능하게 유지합니다
# - max_tokens=5로 응답 길이를 짧게 제한합니다 (숫자만 받을 목적)
reply = response.choices[0].message.content
# - 모델 응답에서 실제 텍스트(가격 예측 결과)만 추출합니다
return get_price(reply)
# - 추출한 텍스트에서 숫자(가격)만 뽑아내어 반환합니다
주어진 item
에 대해 최신 gpt-4o-2024-08-06 모델을 호출해서 가격만 깔끔하게 추출하여 반환하는 함수입니다.
Frontier 모델 버전이기 때문에 더 높은 정확도나 특성을 기대할 수 있습니다.
5-2-2 🧪 gpt-4o-Frontier 테스트 결과(Tester.test(gpt_4o_frontier, test))
# 🧪 최신 gpt-4o-2024-08-06 모델로 테스트 데이터 평가
# - 주의: 이 모델을 호출하는 데 약 1~2센트의 비용이 발생했습니다
# (지역에 따라 요금이 다를 수 있습니다)
# - 비용이 걱정된다면 직접 실행하지 않고 제공된 결과만 참고할 수도 있습니다
Tester.test(gpt_4o_frontier, test)
# - gpt_4o_frontier 함수를 test 데이터셋 전체에 적용해 성능을 평가합니다
# - Tester가 자동으로 RMSE, MAE 등 평가 지표를 계산해줍니다
gpt-4o Frontier 모델을 사용해 테스트 데이터에 대해 가격 예측 성능을 평가합니다.
최신 모델을 사용하기 때문에 더 나은 결과를 기대할 수 있지만, API 호출 비용이 소량 발생할 수 있다는 점에 주의해야 합니다.
5-3-1. 🎵 Claude 3.5 Sonnet 예측 함수(claude_3_point_5_sonnet)
# 🎵 Claude 3.5 Sonnet 모델을 사용해 가격 예측하는 함수
def claude_3_point_5_sonnet(item):
messages = messages_for(item)
system_message = messages[0]['content']
# - system 역할 메시지를 따로 추출합니다 (Claude API는 system 파라미터로 따로 보내야 함)
messages = messages[1:]
# - 나머지 메시지(user, assistant 부분만 남깁니다)
response = claude.messages.create(
model="claude-3-5-sonnet-20240620",
max_tokens=5,
system=system_message,
messages=messages
)
# - Claude 3.5 Sonnet (2024년 6월 버전) 모델을 호출합니다
# - system 메시지와 user 메시지를 각각 전달합니다
# - 최대 토큰 수를 5로 제한해 응답을 짧게 만듭니다 (숫자만 받을 목적)
reply = response.content[0].text
# - Claude 응답 중 첫 번째 메시지의 텍스트를 가져옵니다
return get_price(reply)
# - 텍스트에서 숫자(가격)만 추출해 반환합니다
주어진 item
에 대해 Claude 3.5 Sonnet 모델을 호출해서 가격 예측 결과를 받아오고, 숫자만 깔끔하게 뽑아 반환하는 함수입니다.
Claude API에서는 system 메시지와 user 메시지를 따로 지정해야 하므로 약간 처리 방식이 다릅니다.
5-3-2. 🧪 Claude 3.5 Sonnet 테스트 결과(Tester.test(claude_3_point_5_sonnet, test))
# 🧪 Claude 3.5 Sonnet 모델로 테스트 데이터 평가
# - 주의: 이 모델을 호출하는 데 약 1~2센트의 비용이 들었습니다
# (지역에 따라 요금이 다를 수 있습니다)
Tester.test(claude_3_point_5_sonnet, test)
# - claude_3_point_5_sonnet 함수를 test 데이터셋 전체에 적용해 성능을 평가합니다
# - Tester 클래스가 자동으로 RMSE, MAE 등의 평가 지표를 계산해줍니다
Claude 3.5 Sonnet 모델을 사용해 테스트 데이터에 대한 가격 예측 성능을 평가합니다.
Frontier 모델 중 하나로, 가격만 예측하는 간단한 작업에서도 꽤 좋은 성능을 기대할 수 있습니다.
호출 시 소량의 API 사용 비용이 발생할 수 있습니다.
'🧠 LLM 엔지니어링' 카테고리의 다른 글
Fine-tuned GPT-4o-mini를 이용한 제품 가격 예측 모델 구축 가이드 02 (0) | 2025.05.05 |
---|---|
Fine-tuned GPT-4o-mini를 이용한 제품 가격 예측 모델 구축 가이드 01 (0) | 2025.05.04 |
자연어 처리 기반 가격 예측 모델 개발💸 (BOW vs Word2Vec vs RF) 02 (0) | 2025.05.02 |
자연어 처리 기반 가격 예측 모델 개발💸 (BOW vs Word2Vec vs RF) 01 (1) | 2025.05.01 |
📘 제품 가격 예측 AI 만들기: Amazon 리뷰 데이터로 LLM 학습하기 01 (0) | 2025.04.30 |