SQL(SQL 지표)
SQL(SQL 지표)
Ragas의 SQL 지표는 데이터베이스 대상 SQL 생성 쿼리를 평가하는 데 쓰여요. 쿼리를 실제로 실행해 결과를 비교하는 실행 기반 지표와, 실행 없이 쿼리 자체를 비교하는 비실행 기반 지표로 나뉘죠. 상황에 맞춰 골라 쓸 수 있어요.
출처: 문서
본문
실행 기반 지표(Execution based metrics)
이 지표들에서는 생성된 SQL을 데이터베이스에서 실행한 뒤 response를 기대 결과와 비교해요.
DataCompy 점수(DataCompy Score)
DataCompyScore 지표는 두 pandas DataFrame을 비교하는 Python 라이브러리인 DataCompy를 사용해요. 두 DataFrame을 비교하는 간단한 인터페이스를 제공하고 차이점에 대한 상세 보고서를 제공해요. 이 지표에서 response는 데이터베이스에서 실행되고, 그 결과 데이터가 기대 데이터(reference)와 비교돼요. 비교를 가능하게 하려면 response와 reference 모두 예시에서 보듯이 Comma-Separated Values(CSV) 형태여야 해요.
DataFrame은 행(row) 단위 또는 열(column) 단위로 비교할 수 있어요. 이는 mode 파라미터로 구성할 수 있어요.
mode가 row이면 비교가 행 단위로 이뤄져요. mode가 column이면 비교가 열 단위로 이뤄져요.
[ \text{Precision } = {|\text{Number of matching rows in response and reference}| \over |\text{Total number of rows in response}|} ]
[ \text{Recall } = {|\text{Number of matching rows in response and reference}| \over |\text{Total number of rows in reference}|} ]
기본적으로 mode는 row로 설정되고, 지표는 정밀도와 재현율의 조화 평균인 F1 점수예요.
from ragas.metrics.collections import DataCompyScore
data1 = """acct_id,dollar_amt,name,float_fld,date_fld
10000001234,123.45,George Maharis,14530.1555,2017-01-01
10000001235,0.45,Michael Bluth,1,2017-01-01
10000001236,1345,George Bluth,,2017-01-01
10000001237,123456,Bob Loblaw,345.12,2017-01-01
10000001238,1.05,Lucille Bluth,,2017-01-01
10000001238,1.05,Loose Seal Bluth,,2017-01-01
"""
data2 = """acct_id,dollar_amt,name,float_fld
10000001234,123.4,George Michael Bluth,14530.155
10000001235,0.45,Michael Bluth,
10000001236,1345,George Bluth,1
10000001237,123456,Robert Loblaw,345.12
10000001238,1.05,Loose Seal Bluth,111
"""
metric = DataCompyScore()
result = await metric.ascore(response=data1, reference=data2)
print(f"F1 Score: {result.value}")
print(f"Details: {result.reason}")
열 단위 비교로 바꾸려면 mode 파라미터를 column으로 설정해요.
metric = DataCompyScore(mode="columns", metric="recall")
result = await metric.ascore(response=data1, reference=data2)
DataCompyScore (레거시)
Deprecated
ragas.metrics의DataCompyScore는 사용이 중단됐으며 향후 버전에서 제거될 예정이에요. 위에서 보여준ragas.metrics.collections의DataCompyScore를 사용해주세요.
레거시 DataCompyScore는 SingleTurnSample 스키마를 사용해요:
from ragas.metrics import DataCompyScore
from ragas.dataset_schema import SingleTurnSample
data1 = """acct_id,dollar_amt,name,float_fld,date_fld
10000001234,123.45,George Maharis,14530.1555,2017-01-01
10000001235,0.45,Michael Bluth,1,2017-01-01
10000001236,1345,George Bluth,,2017-01-01
10000001237,123456,Bob Loblaw,345.12,2017-01-01
10000001238,1.05,Lucille Bluth,,2017-01-01
10000001238,1.05,Loose Seal Bluth,,2017-01-01
"""
data2 = """acct_id,dollar_amt,name,float_fld
10000001234,123.4,George Michael Bluth,14530.155
10000001235,0.45,Michael Bluth,
10000001236,1345,George Bluth,1
10000001237,123456,Robert Loblaw,345.12
10000001238,1.05,Loose Seal Bluth,111
"""
sample = SingleTurnSample(response=data1, reference=data2)
scorer = DataCompyScore()
await scorer.single_turn_ascore(sample)
열 단위 비교로 바꾸려면 mode 파라미터를 column으로 설정해요.
scorer = DataCompyScore(mode="column", metric="recall")
비실행 기반 지표(Non Execution based metrics)
SQL 쿼리를 데이터베이스에서 실행하는 것은 시간이 오래 걸리고 때로는 실행이 불가능할 수도 있어요. 이런 경우 비실행 기반 지표로 SQL 쿼리를 평가할 수 있어요. 이 지표들은 데이터베이스에서 실행하지 않고 SQL 쿼리를 직접 비교해요.
SQL 의미적 동등성(SQL Semantic Equivalence)
SQLSemanticEquivalence는 생성된 SQL 쿼리가 reference 쿼리와 의미적으로 동등한지 평가하는 지표예요. 이 지표는 LLM을 사용해 제공된 데이터베이스 스키마 컨텍스트에서 두 쿼리를 분석하고, 같은 결과를 생성할지 결정해요.
이진 지표예요:
- 1.0: SQL 쿼리가 의미적으로 동등함
- 0.0: SQL 쿼리가 동등하지 않음
이 지표는 정확한 동등성 판단을 위해 데이터베이스 스키마 컨텍스트를 고려하며, 의미에 영향을 주지 않는 구문적 차이(예: active = 1 vs active = true)도 반영해요.
from openai import AsyncOpenAI
from ragas.llms.base import llm_factory
from ragas.metrics.collections import SQLSemanticEquivalence
# Initialize the LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create the metric
metric = SQLSemanticEquivalence(llm=llm)
# Evaluate SQL equivalence
result = await metric.ascore(
response="""
SELECT p.product_name, SUM(oi.quantity) AS total_quantity
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_name;
""",
reference="""
SELECT products.product_name, SUM(order_items.quantity) AS total_quantity
FROM order_items
INNER JOIN products ON order_items.product_id = products.product_id
GROUP BY products.product_name;
""",
reference_contexts=[
"""
Table order_items:
- order_item_id: INT
- order_id: INT
- product_id: INT
- quantity: INT
""",
"""
Table products:
- product_id: INT
- product_name: VARCHAR
- price: DECIMAL
"""
]
)
print(f"Equivalent: {result.value == 1.0}")
print(f"Explanation: {result.reason}")
결과에는 두 쿼리에 대한 설명과 동등성 판단의 근거가 포함돼요.
LLMSQLEquivalence (레거시)
Deprecated
LLMSQLEquivalence는 사용이 중단됐으며 향후 버전에서 제거될 예정이에요. 위에서 보여준ragas.metrics.collections의SQLSemanticEquivalence를 사용해주세요.
LLMSQLEquivalence는 SQL 의미적 동등성 평가를 위한 레거시 지표예요. SingleTurnSample 스키마를 사용하며 LLM을 별도로 설정해야 해요.
from ragas.metrics import LLMSQLEquivalence
from ragas.dataset_schema import SingleTurnSample
sample = SingleTurnSample(
response="""
SELECT p.product_name, SUM(oi.quantity) AS total_quantity
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_name;
""",
reference="""
SELECT p.product_name, COUNT(oi.quantity) AS total_quantity
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_name;
""",
reference_contexts=[
"""
Table order_items:
- order_item_id: INT
- order_id: INT
- product_id: INT
- quantity: INT
""",
"""
Table products:
- product_id: INT
- product_name: VARCHAR
- price: DECIMAL
"""
]
)
scorer = LLMSQLEquivalence()
scorer.llm = openai_model
await scorer.single_turn_ascore(sample)