
Snowflake의 ML/AI Observability를 실무 관점에서 검증하기
요약
실무 운영 중 발생하는 ML 모델의 성능 저하와 생성형 AI 앱의 품질 열화 문제를 해결하기 위한 Observability의 중요성을 다룹니다. Snowflake의 기능을 활용해 데이터 드리프트와 RAG의 Groundedness 저하를 감지하는 실무 사례를 제시합니다.
핵심 포인트
- 에러가 발생하지 않아도 모델 성능은 조용히 열화될 수 있음
- ML 모델은 데이터 드리프트와 학습 전제 변화를 모니터링해야 함
- 생성형 AI는 할루시네이션과 검색 품질 저하를 감지하는 것이 핵심
- Snowflake는 AI와 ML 각각에 특화된 Observability 기능을 제공함
서론: 왜 실무 운영에 Observability가 필요한가
머신러닝 (ML) 모델이나 생성형 AI 앱을 "만들고 끝"낼 수 있는 현장은 거의 없습니다. 실무에 배포하여 고객이 사용하는 순간부터, 머신러닝 모델이나 AI는 조용히 열화(Degradation)가 시작됩니다.
예를 들어, 프로젝트 관리 도구 AI에서 다음과 같은 상황을 상상해 보세요.
케이스 1 이용 지속 예측 모델: 어떤 SaaS의 커스터머 석세스(Customer Success) 팀은 해지할 것 같은 고객을 감지하는 "이용 지속 예측 모델"을 실무 운영하고 있다. 학습 시의 정밀도는 양호했고, 시스템 에러도 전혀 발생하지 않았다. 그런데 어느 달, 요금제 개정을 기점으로 모델이 "지속"이라고 예측했던 PRO 플랜 고객들이 연달아 해지하기 시작했다. 원인을 추적해 보니, 개정으로 인해 사용자의 주간 활성 일수 등 이용 패턴이 변하면서 학습 시의 전제가 무너져 있었다. 모델은 아무것도 고장 나지 않았지만, 주변 상황이 변하면서 예측이 빗나가기 시작했고, 해지가 표면화될 때까지 아무도 알아채지 못했다.
케이스 2 헬프 센터의 AI 어시스턴트: 어떤 SaaS는 헬프 센터에 제품 문서를 검색하여 답변하는 AI 어시스턴트를 탑재하고 있다. 고객으로부터 "답변이 딱딱하다"라는 피드백을 받고, 담당자는 좋은 의도로 생성형 LLM을 상위 모델로 교체했다. 답변은 확실히 유창해졌다. 하지만 며칠 후, 유인 지원(Human Support)으로의 문의가 오히려 증가해 버렸다. 조사해 보니, 새 모델은 헬프 문서에 적혀 있지 않은 "그럴듯한 사양이나 요금"을 자신만만하게 보충하여 답변하고 있었다. 출시 전에 몇 문제만 테스트했을 때는 완벽해 보였는데...
두 경우 모두 "작동하고 있다(=예외는 발생하지 않았다)에도 불구하고 성과는 악화되고 있는" 조용한 품질 열화입니다. 유닛 테스트(Unit Test)나 생존 확인(Liveness Monitoring)으로는 쉽게 감지할 수 없습니다. 정리하자면, 열화는 다음과 같은 형태로 다가옵니다.
ML 모델: 입력 분포의 드리프트(Drift), 학습 시 전제의 노후화, 데이터 파이프라인의 손상으로 인해 의도치 않게 정밀도가 떨어진다. -
생성형 AI 앱 (RAG / AI 에이전트): 검색이 어긋나거나, LLM이 할루시네이션(Hallucination)을 일으키거나, 프롬프트 변경으로 품질이 퇴보한다. 게다가 출력이 비결정적(Non-deterministic)이고 교묘하기 때문에 "고장 났다"는 것을 알아차리기 어렵다.
필요한 것은 "에러 없이 작동하는가"가 아니라 "기대하는 품질을 유지하고 있는가"를 지속적으로 측정하는 메커니즘이며, 즉 Observability입니다.
본 기사에서는 가상의 SaaS인 SnowflakeDesk (프로젝트 관리 도구) 운영을 기반으로, AI 에이전트와 머신러닝에 Observability를 활용합니다. 이 SnowflakeDesk의 케이스 1에 해당하는 "요금 개정 후의 드리프트와 정밀도 저하"를 model monitor가 감지하는 모습(정밀도 0.77→0.62)과, 케이스 2에 해당하는 "상위 모델에서 groundedness가 낮아지는" 현상(v3에서 0.77까지 저하)을 모두 실제 데이터로 관측합니다.
Snowflake는 이 두 종류의 워크로드에 대해 각각 전용의 가관측성 (Observability) 기능을 제공하고 있습니다.
| AI Observability | ML Observability |
|---|---|
| 대상 | 생성형 AI 앱 / 에이전트 (RAG, 요약 등) |
| ... |
본 기사에서는 이 두 가지를 하나의 SaaS 운영 스토리를 통해 해설합니다.
가상의 SaaS인 "SnowflakeDesk" (프로젝트 관리 도구)는 두 가지 AI/ML 워크로드를 실무 운영하고 있습니다.
제품 문서에 답변하는 RAG 어시스턴트 (헬프 센터) → AI Observability로 평가·비교
이용 지속 예측 모델 (해지=1인 이진 분류) → ML Observability로 드리프트·성능 모니터링
각각 "어떻게 만들고, 어떻게 관측하며, 관측 결과로부터 무엇을 읽어낼 수 있는지"를 실제 데이터로 살펴보겠습니다.
전체상과 목표
만드는 것과 관측하는 것을 한 장으로 정리하면 다음과 같습니다.
검증 환경은 다음과 같습니다.
- Snowflake 계정: 도쿄 리전 (
AWS_AP_NORTHEAST_1) - Python 라이브러리: snowflake-ml-python 1.46, snowflake-snowpark-python 1.53, trulens-core
- 판정용 LLM (LLM-as-a-judge):
claude-sonnet-4-6
(도쿄 리전에서 동작 확인 완료. 기본값은 llama3.1-70b)
- 임베딩 모델 (Embedding Model):
snowflake-arctic-embed-l-v2.0
환경 준비: DB · 스키마 · 권한
SnowflakeDesk 환경을 구축합니다.
먼저 데이터베이스와 스키마를 준비합니다. 핵심 포인트는 External Agent (AI Obs 앱 실체)는 model 객체와 네임스페이스를 공유한다는 점이므로, RAG용과 ML용으로 스키마를 나누어 두는 것입니다.
CREATE DATABASE IF NOT EXISTS ML_AI_OBS_BLOG;
CREATE SCHEMA IF NOT EXISTS ML_AI_OBS_BLOG.RAG; -- AI Observability / External Agent
CREATE SCHEMA IF NOT EXISTS ML_AI_OBS_BLOG.ML; -- ML Observability / model & monitor
AI Observability를 전용 역할 (Role)로 사용할 때의 최소 권한은 다음과 같습니다 (운영 환경에서는 이 방식을 권장합니다. 이번에는 검증을 위해 ACCOUNTADMIN으로 실행합니다).
CREATE ROLE IF NOT EXISTS observability_user_role;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE observability_user_role;
GRANT CREATE EXTERNAL AGENT ON SCHEMA ML_AI_OBS_BLOG.RAG TO ROLE observability_user_role;
...
CORTEX_USER
: Cortex 함수 (LLM-as-a-judge가 사용하는 AI_COMPLETE)를 호출하기 위해 필수
CREATE EXTERNAL AGENT
: 평가 대상 앱을 Snowflake에 등록하기 위해 필요
CREATE TASK / EXECUTE TASK
: Run (평가 작업)은 내부적으로 태스크 (Task)를 사용하기 때문에 필요
생성할 테이블 그룹의 ER 다이어그램 (클릭하여 확장)
이번 검증에서 생성할 테이블 그룹을 ER 다이어그램으로 나타내면 다음과 같습니다. RAG 스키마가 AI Observability용, ML 스키마가 ML Observability용입니다.
RAG 스키마 (AI Observability용)
RAG측:DOCS를AI_EMBED로 벡터화한 것이DOC_CHUNKS입니다.EVAL_QUESTIONS는 평가 데이터셋 (AI Obs의 Run이 참조)입니다.
ML 스키마 (ML Observability용)
ML측:CHURN_TRAIN으로 학습한 모델 (Model Registry의CHURN_MODEL)이CHURN_SCORING(추론 로그)을 생성하며, 이를CHURN_BASELINE(기준 스냅샷)과의 드리프트 (Drift) 비교에 사용합니다. 모니터링의 타입 제약상,EVENT_TS는TIMESTAMP_NTZ, 예측/실측 열은NUMBER, 세그먼트 열PLAN_TYPE은STRING이라는 점에 주의하십시오 (자세한 내용은 파트 2 참조).
파트 1:
컨셉 정리
Snowflake의 AI Observability는 오픈 소스 (OSS)인 TruLens를 기반으로, 생성형 AI 앱을 Snowflake 상에서 평가 및 트레이스 (Trace)하는 메커니즘입니다.
등장하는 개념은 다음 5가지만 파악하면 충분합니다.
- Application / External Agent: 평가 대상 앱. TruLens SDK에서 등록하면 Snowflake에 External Agent 객체가 생성됩니다 (메타데이터만 생성되며, 앱 본체나 트레이스는 이벤트 테이블에 저장됩니다).
- Version: retriever · 프롬프트 · LLM 등의 구성 차이. 버전 비교의 단위입니다.
- Dataset: 입력값 (및 선택 사항인 정답 = ground truth)의 세트입니다.
- Run: 특정 버전 × 데이터셋의 평가 작업 (Job).
invocation(앱 실행 + 트레이스 생성)과computation
(메트릭 계산 (Metrics calculation))의 2단계. -
Metrics / Traces: LLM-as-a-judge에 의한 스코어(0–1)와 각 단계의 입출력·레이턴시(Latency)·토큰.
검증: SnowflakeDesk 헬프데스크 RAG를 3가지 구성으로 비교하기
SnowflakeDesk 헬프데스크는 RAG로 구현됩니다. 과제로서 "실제 운영 환경에서 어떤 RAG 구성을 채택해야 하는가"를 관측하여 결정해야 하는 상황을 가정합니다.
SnowflakeDesk의 제품 문서 25개(합성 데이터)를 임베딩(Embedding)하고, 다음 3가지 버전을 동일한 12개 질문(정답 포함)으로 평가했습니다.
| 버전 | 검색 건수 | 생성 LLM | 목적 |
|---|---|---|---|
v1_baseline | top-1 | llama3.1-8b | 비용을 최소화한 심플 버전 |
v2_retrieval | top-4 | llama3.1-8b | retriever(검색기)만 개선 |
v3_quality | top-4 | claude-sonnet-4-6 | retriever + 생성 LLM을 개선 |
v1→v2에서는 "검색 건수의 효과", v2→v3에서는 "LLM의 효과"를 분리하여 관측할 수 있도록 구성했습니다.
문서 임베딩과 RAG
RAG에서는 문서를 AI로 임베딩 표현(벡터)으로 변환하여, 문서를 유사도 검색(Similarity search)할 수 있도록 합니다.
문서의 제목과 본문을 AI_EMBED로 1024차원의 벡터로 변환합니다.
CREATE OR REPLACE TABLE ML_AI_OBS_BLOG.RAG.DOC_CHUNKS AS
SELECT DOC_ID, CATEGORY, TITLE, CONTENT,
AI_EMBED('snowflake-arctic-embed-l-v2.0', TITLE || ' ' || CONTENT) AS EMBEDDING
...
RAG의 retriever(질문에 대한 관련 문서 검색)는 벡터 유사도 검색입니다. 검색 건수(limit_to_retrieve)를 바꾸는 것만으로 v1(top-1)과 v2/v3(top-4)를 전환할 수 있습니다. 구체적으로는, 사용자의 질문을 AI_EMBED를 통해 동일한 임베딩 모델로 벡터화하고, VECTOR_COSINE_SIMILARITY로 각 문서와의 유사도를 계산하여 상위 limit_to_retrieve 건을 문맥(Context)으로 LLM에 전달합니다. 이 건수는 검색의 "정밀도(소수 정예)"와 "망라성(많이 수집)"을 좌우하는 파라미터이며, 후술할 평가 메트릭의 트레이드오프(Trade-off)를 발생시키는 역할을 합니다.
이 RAG의 흐름을 도식화하면 다음과 같습니다. 상단은 사전 준비(오프라인 인덱싱), 하단은 질문이 들어왔을 때의 처리(온라인)입니다.
- ① 인덱싱(Indexing):
DOCS를AI_EMBED로 벡터화하여DOC_CHUNKS에 저장합니다. 여기까지는 한 번만 수행하면 됩니다. - - ② 질의응답(Question Answering): 질문을 동일한 모델로 벡터화 → 코사인 유사도로 정렬 → 상위
limit_to_retrieve건을 문맥으로 하여 생성 LLM에 전달하는 흐름입니다.limit_to_retrieve(검색 건수)와 생성 LLM이라는 두 지점만 교체한 것이 v1/v2/v3입니다.
TruLens로 앱 측정하기
먼저, 평가 대상이 되는 RAG 앱을 Python으로 구현합니다. 지금까지 설명한 "벡터 검색 → 생성"의 흐름을 SnowflakeDeskRAG라는 하나의 클래스로 묶은 것입니다. 다음 3가지 메서드로 구성됩니다.
retrieve_context(query): 질문과 관련된 문서를 벡터 검색함 (검색 단계) -generate_completion(query, context): 취득한 문맥을 사용하여 생성 LLM으로 답변함 (생성 단계) -query(query): 위 두 가지를 순차적으로 호출하는 엔트리 포인트(Entry point, 앱의 입구)
이 클래스를 AI Observability로 관측할 수 있게 만드는 것이 TruLens를 이용한 측정(Instrumentation)입니다. 관측하고자 하는 Python 함수에 @instrument를...
데코레이터로 장식하고, span type (RETRIEVAL / GENERATION / RECORD_ROOT)과 span attribute (어떤 인자가 입력·출력·검색 쿼리·검색 결과인지)를 선언합니다. 이 데코레이터가 붙은 함수는 메트릭스 (context relevance 등)가 자동으로 측정됩니다.
from snowflake.cortex import complete
from trulens.core.otel.instrument import instrument
from trulens.otel.semconv.trace import SpanAttributes
...
TruLens에 앱을 등록하고 Run을 실행하기
관측 대상인 앱 객체를 TruLens의 TruApp 클래스에 버전별로 등록하고, RunConfig에서 데이터셋 (Snowflake 테이블)과 컬럼 매핑을 지정하여 실행합니다.
from trulens.apps.app import TruApp
from trulens.connectors.snowflake import SnowflakeConnector
from trulens.core.run import RunConfig
...
평가 결과: 관측이 밝혀낸 "비자명한 트레이드오프 (non-obvious trade-off)"
다음은 3개 버전의 평균 점수 (정규화됨 0–1, claude-sonnet-4-6을 judge로 사용)입니다.
| 메트릭스 | v1_baseline (top1/llama) | v2_retrieval (top4/llama) | v3_quality (top4/claude) |
|---|---|---|---|
| context_relevance | 0.889 | 0.292 | 0.292 |
| groundedness | 1.000 | 1.000 | 0.774 |
| answer_relevance | 0.667 | 0.806 | 0.861 |
| ... | |||
![]() |
이 데이터는 직관에 반하는 중요한 사실을 시각화하고 있다고 할 수 있습니다.
-
context_relevance는 v1 (top-1)이 가장 높습니다 (0.89). 이는 "검색 정밀도 (precision)"를 측정하는 지표로, 검색에서 1건만 반환하면 그것은 대개 가장 관련도가 높은 문서이므로 relevance가 높아집니다. 검색 건수를 4건으로 늘리면 (v2, v3), 관련도가 낮은 문서가 포함되기 때문에 평균이 낮아져 0.29까지 떨어집니다. -
-
하지만 correctness / coherence는 v1이 가장 낮습니다 (0.56 / 0.64). SnowflakeDesk의 질문에는 "Pro 요금과 API 레이트 제한은?"과 같이 여러 문서에 걸친 질문이 포함되어 있으며, top-1에서는 정보가 부족하여 답변을 다 할 수 없고, 소형 모델 (llama3.1-8b)에서는 문장의 일관성도 떨어지기 때문입니다. -
-
검색 획득 수를 top-4로 늘리면 (v2) correctness가 0.75로 상승하며, 여기에 더 강력한 LLM (v3, claude-sonnet-4-6)을 사용하면 correctness 0.97 / coherence 0.97 / answer_relevance 0.86에 도달합니다. -
-
반면 v3의 groundedness는 0.77로 낮아졌습니다. 이는 놓칠 수 없는 발견입니다. claude-sonnet-4-6은 표현력이 뛰어나 정확하고 읽기 쉬운 답변을 반환하는 반면, 실험 결과로서 검색한 문맥에 엄밀히 포함되지 않는 보충 설명이나 일반 상식을 섞어서 답변하는 경향이 있음이 관측됩니다. 그 때문에 "답변이 문맥에 근거하고 있는가"를 측정하는 groundedness가 낮아진 것입니다. 정확성 (correctness)과 근거성 (groundedness)이 반드시 일치하지 않는다는, 실제 운영에서 매우 중요한 논점이 수치로 나타나고 있습니다. (참고: 이 결과는 이번 검증에서 발생한 현상이며, claude-sonnet-4-6이 항상 문맥에 엄밀히 포함되지 않는 보충 설명이나 일반 상식을 섞는다는 의미는 아닙니다.)
-
토큰 소비는 209(v1) → 466(v2) → 755(v3)로 단조 증가 (= 비용 증가) 합니다.

즉, "검색 결과 수를 늘린다고 해서 context relevance(문맥 관련성)가 올라가는 것"도 아니며, "더 강력한 LLM을 사용한다고 해서 모든 지표가 올라가는 것"도 아닙니다. precision(정밀도, context relevance)과 coverage(커버리지, correctness)는 트레이드오프(trade-off) 관계이며, 나아가 correctness(정확성)와 groundedness(근거성) 또한 동시에 최대화되지 않는다는 경향을 확인할 수 있습니다. 이러한 다차원적인 구조를 수치로 명시해 주는 것이 AI Observability의 가치입니다.
결론: SnowflakeDesk의 헬프데스크 RAG는 정확성과 가독성을 우선한다면 v3(top-4 + claude-sonnet-4-6)가 좋을 것입니다. 다만 비용은 v1의 약 3.6배에 달하며, groundedness의 저하(hallucination(환각) 리스크)에도 주의가 필요합니다. "4개의 결과를 반환하면서 context relevance도 높이고 싶다"거나 "groundedness를 담보하고 싶다"면, retriever(검색기)에 re-ranking(재순위화)을 추가하고 프롬프트에서 문맥 외 보충을 금지하는 등의 개선을 거친 새로운 버전(v4)을 만든 뒤, 동일한 데이터셋으로 다시 검증을 실행하여 비교하는 것이 좋습니다.
이러한 조치를 실행하고 평가하는 것이 AI Observability를 활용한 반복적 개발 사이클입니다.
스코어는 어디에 저장되어 있는가 (SQL로 읽기)
평가 결과는 SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS 이벤트 테이블에 OpenTelemetry 형식으로 저장됩니다. 커스텀 대시보드를 만들려면 SQL로 직접 집계할 수 있습니다.
-- 사전에 읽기 권한(role) 부여
GRANT APPLICATION ROLE SNOWFLAKE.AI_OBSERVABILITY_READER TO ROLE <your_role>;
GRANT ROLE observability_user_role TO USER <user>;
...

트레이스(Trace)로 디버깅하기
Snowsight의 AI & ML » Evaluations 메뉴에서 App → Run → Record 순으로 들어가면, 각 질문에 대해 "검색된 문맥", "LLM으로의 입력", "생성 결과", "각 메트릭(metric)의 스코어와 judge(판단) 설명"을 단계별로 확인할 수 있습니다.
예를 들어 v3에서 answer relevance(답변 관련성)가 낮았던 "API rate limit(API 호출 제한)을 플랜별로 알려주세요."라는 질문의 트레이스를 열어보면, 답변의 근거가 되는 정보 검색의 context relevance가 낮았다는 실패의 인과관계를 그대로 추적할 수 있습니다.


여러 버전을 선택하여 Compare하면, 동일한 질문에 대한 답변과 스코어의 차이점도 나란히 확인할 수 있습니다.

파트 2:
컨셉 정리
ML Observability는 Model Registry에 배포된 정형 데이터 기반의 머신러닝 모델(회귀, 이진 분류, 다중 클래스 분류)을 **저장된 추론 로그(inference logs)**를 대상으로 모니터링합니다. 모니터링 대상 버전당 monitor는 1개이며, 모니터링할 수 있는 지표는 다음 세 가지 계통입니다.
- Drift(드리프트): 특성(feature), 예측값, 실제값의 분포 변화 (Jensen-Shannon, PSI, Wasserstein, 평균 차이)
- Performance(성능): AUC, F1, accuracy(정확도) 등 (실제 라벨이 있는 경우)
- Statistical(통계): 건수, NULL 수
monitor는 내부적으로 소스 테이블을 **테이블로 마테리얼라이즈(materialize, 구체화)**하며, 지정된 간격(REFRESH_INTERVAL)으로 리프레시하여 집계합니다.
검증: 이용 지속 예측 모델의 드리프트 감지하기
SnowflakeDesk의 "해지 예측 모델"(이진 분류)에서 의도적으로 이상치를 검출하기 위해, 이상치를 포함한 데이터를 준비합니다.
SnowflakeDesk의 "해지 예측 모델"을 Model Registry에 등록하고, 28일 분량의 추론 로그를 준비했습니다. 28일 중 이상치로서 후반 7일에 의도적으로 드리프트(drift)를 주입했습니다. 이는 "이용 일수가 전반적으로 감소하고, 실제 해지가 예상보다 증가했다"는 실제 운영 환경에서 흔히 발생하는 성능 저하 시나리오입니다.
이 검증 상황을 도식화하면 다음과 같습니다. 모델은 "평상시(baseline)\
이것을 model monitor에서 어떻게 포착할 수 있는지, 이후 실제 데이터와 함께 살펴보겠습니다.
학습과
from sklearn.ensemble import GradientBoostingClassifier
from snowflake.ml.registry import Registry
clf = GradientBoostingClassifier(random_state=42).fit(X, y) # train AUC=0.765
...
추론 로그와 베이스라인 (Baseline) 준비
model monitor에는 엄격한 타입 제약(type constraints)이 있습니다. 구현 시 반드시 지켜야 할 사항은 다음과 같습니다.
.
예측 컬럼(prediction column) 및 실측 컬럼(actual column)은 TIMESTAMP_COLUMN은 TIMESTAMP_NTZ,
NUMBER.
. NULL/NaN/Inf 불가, 확률 점수(probability score)는 0–1.
- 세그먼트 컬럼(segment column, 이번에는
PLAN_TYPE)은 STRING.
CREATE OR REPLACE TABLE ML_AI_OBS_BLOG.ML.CHURN_SCORING AS
SELECT ACCOUNT_ID,
DATEADD('day', -DAY_OFFSET, CURRENT_TIMESTAMP())::TIMESTAMP_NTZ AS EVENT_TS,
...
F1 스코어(F1 score)나 정확도(accuracy)를 구하려면 **예측 클래스 컬럼(prediction class column)**도 필요합니다 (후술하는 바와 같이 F1 계열은 prediction_class를 요구함). 임계값(threshold) 0.5를 기준으로 클래스 컬럼을 추가합니다 (참고로 임계값 0.5는 임시 값이며, 실제 운영 시에는 적절히 조정해야 합니다).
ALTER TABLE ML_AI_OBS_BLOG.ML.CHURN_SCORING ADD COLUMN PREDICTION_CLASS NUMBER;
UPDATE ML_AI_OBS_BLOG.ML.CHURN_SCORING SET PREDICTION_CLASS = IFF(PREDICTION_SCORE >= 0.5, 1, 0);
드리프트(drift) 비교를 위한 베이스라인 테이블 (baseline table) (학습 시 분포의 스냅샷)도 준비합니다. 모니터링 대상인 추론 로그와는 별도로, '정상 시기(학습 시)의 분포'를 나타내는 기준 데이터로서 생성합니다.
# 학습 시와 동일한 분포(드리프트 없음)를 생성하고, 예측값을 붙여 저장
base = gen_accounts(3000, drift=False)
base["PREDICTION_SCORE"] = clf.predict_proba(base[FEATURES])[:, 1].round(4)
...
-- SOURCE에 맞춰 베이스라인에도 예측 클래스 컬럼을 추가
ALTER TABLE ML_AI_OBS_BLOG.ML.CHURN_BASELINE ADD COLUMN PREDICTION_CLASS NUMBER;
UPDATE ML_AI_OBS_BLOG.ML.CHURN_BASELINE SET PREDICTION_CLASS = IFF(PREDICTION_SCORE >= 0.5, 1, 0);
추론 로그의 기간별 요약(실측값)은 다음과 같습니다. 드리프트 기간에는 모델의 추론이 해지를 과소평가하고 있음을 알 수 있습니다.
| 기간 | 건수 | 평균 예측 점수 | 실측 해지율 |
|---|---|---|---|
| baseline (~8일 전) | 3,150 | 0.244 | 0.234 |
| recent (최근 7일, 드리프트 주입) | 1,200 | 0.527 | 0.708 |
model monitor 생성하기
CREATE OR REPLACE MODEL MONITOR ML_AI_OBS_BLOG.ML.CHURN_MONITOR WITH
MODEL = ML_AI_OBS_BLOG.ML.CHURN_MODEL
VERSION = 'V1'
...
메트릭 (Metrics) 조회하기
생성 후, 테이블 함수(table function)를 통해 메트릭을 가져올 수 있습니다. 이진 분류(binary classification)에서는, ROC_AUC는 prediction_score + actual_class가, F1/PRECISION/RECALL/ACCURACY는 prediction_class + actual_class가 필요합니다.
-- 성능(일간·최근 30일)
SELECT EVENT_TIMESTAMP::date AS d, ROUND(METRIC_VALUE, 4) AS v
FROM TABLE(MODEL_MONITOR_PERFORMANCE_METRIC(
...
모니터링 결과: 드리프트(Drift)와 성능 저하가 동시에 관찰됨
아래 그림은 일간 성능과 드리프트(Drift)를 겹쳐서 나타낸 것입니다. 7월 2일에 드리프트 (Jensen-Shannon)가 0.100.17에서 0.450.51로 급상승하였으며, 동일한 시점에 정확도(Accuracy)가 약 0.77에서 약 0.62로 저하되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기