데이터로 해자를 만든다는 것 (여정1)
배경
미용 의료 플랫폼은 크게 두 종류의 데이터를 가지고 있습니다.
하나는 예약 데이터입니다. 고객이 어떤 시술을 원하고, 얼마를 지불할 의향이 있는지. 강남언니 같은 예약 플랫폼이 이 데이터를 대량으로 보유하고 있죠. 다른 하나는 "실 결제 데이터"입니다. 고객이 병원에 와서 실제로 어떤 시술을 받고, 얼마를 결제했는지. 병원 CRM(KOS, 제품 이름 - 이하 KOS)이 이 데이터를 가지고 있습니다.
문제는 이 두 데이터 사이에 꽤 큰 간극이 존재한다는 점입니다. 환자가 "사각턱 보톡스"를 예약하고 왔는데, 상담 후에 "사각턱 + 이마 + 미간"으로 시술이 확장되거나, 아예 다른 시술로 변경되는 경우가 빈번합니다. 예약 데이터만으로는 실제 시술 시장의 그림을 정확하게 그릴 수 없다는 뜻이예요.
KOS는 오프라인 미용 의료 병원의 실제 결제 데이터를 보유하고 있습니다. 이 데이터를 의미 있게 분석하려면 한 가지 전제가 필요했는데요, 바로 시술 데이터 표준화 입니다.
문제
병원 진료항목 데이터는 병원마다 완전히 다르게 생겼습니다. (같은 시술인데도 이렇게 병원의 운영에 따라 많이 상이해요)
A 병원: "턱보톡스 뉴럭스(개봉) 100U"
B 병원: "사각턱BT_나보타_50"
C 병원: "JAW BTX 엘러간"
D 병원: "사각턱보톡스"
이 네 개는 전부 같은 시술인 사각턱보톡스 인데, 약품명이 섞여있고, 단위 표기법이 다르고, 영어/한글이 혼재합니다. (KOS에서 운영중인 병원에서 수집한 진료항목만 수 만개가 넘어요) 이걸 사람이 일일이 분류하는 건 현실적이지 않았습니다.
그리고 표준 시술 체계가 애초에 존재하지 않았습니다. 사각턱보톡스라는 표준명이 업계에 합의된 적이 없거든요. 그래서 표준 분류 체계 자체를 만드는 것부터 시작해야 했습니다.
고려한 방법들
접근 1: 수동 매핑
병원 운영 담당자가 각 진료항목을 수동으로 분류하는 방식입니다.
장점은 정확도가 높다는 것. 단점은 수 만개의 항목(게다가 앞으로 더 늘어날.. 데이터)에 대해 이걸 하려면 시간이 너무 오래 걸리고, 병원이 늘어날 때마다 반복해야 합니다. 확장성이 전혀 없었습니다.
접근 2: LLM 기반 분류
GPT 등 LLM에 진료항목명을 넣고 표준 시술을 맞추게 하는 방식입니다.
실제로 시도해봤는데, 몇 가지 문제가 있었습니다.
첫째, 의료 도메인 특화 지식이 부족해서 "나보타"가 보톡스 약품명이라는 걸 모르는 경우가 많았습니다. 둘째, 일관성이 없었습니다. 같은 입력에 대해 다른 결과를 줄 때가 있었고, 이건 데이터 파이프라인에서는 치명적입니다. 셋째, 비용과 속도 — 수만 개를 매번 API로 돌리면 비용도 문제지만, 일배치에서 안정적으로 돌리기 어려웠습니다.
접근 3: 규칙 기반 매칭 파이프라인
도메인 지식을 규칙으로 코드화하고, 단계별로 매칭 정밀도를 올려가는 방식입니다.
장점은 결정론적(같은 입력 → 같은 출력), 확장 가능, 디버깅 가능. 단점은 초기 규칙 구축에 노력이 필요하고, 새로운 패턴이 나타나면 규칙을 추가해야 한다는 점입니다.
선택과 이유
접근 3을 선택했습니다. 판단 기준은 세 가지였습니다.
일관성 > 정확도. 99% 정확하지만 1%가 랜덤하게 틀리는 것보다, 95% 정확하고 나머지 5%는 "모르겠다"고 솔직하게 말하는 시스템이 데이터 분석에서는 더 낫다고 생각했습니다.
분석 결과를 신뢰할 수 있어야 하니까요.
첫째, 디버깅 가능성. "왜 이 진료항목이 이 표준 시술에 매핑됐지?"라는 질문에 답할 수 있어야 합니다. LLM은 이게 안 됩니다. 규칙 기반은 매칭된 규칙 ID, 스코어, 단계를 전부 추적할 수 있습니다.
둘째, 자기학습 루프. 사람이 수동으로 매핑한 결과를 새로운 규칙으로 환류(feedback)시킬 수 있는 구조를 원했습니다. 시간이 지날수록 자동 매핑률이 올라가는 시스템이요.
그래서 설계한 게 4단계 매칭 파이프라인입니다.
flowchart TD
Input["9,546개 병원 진료항목"]
S1["Stage 1: Exact Match"]
S2["Stage 2: Keyword Match"]
S3["Stage 3: Regex Match"]
S4["Stage 4: N-gram Match"]
Mapped["매핑 완료"]
Unmapped["unmapped"]
Input --> S1
S1 -->|"성공 (1.0)"| Mapped
S1 -->|실패| S2
S2 -->|"성공 (0.85)"| Mapped
S2 -->|실패| S3
S3 -->|"성공 (0.75)"| Mapped
S3 -->|실패| S4
S4 -->|"성공 (0.65)"| Mapped
S4 -->|실패| Unmapped
각 단계의 매칭 예시를 정리하면 이렇습니다.
| Stage | 입력 예시 | 매칭 방식 |
|---|---|---|
| Exact | "사각턱보톡스" | 정확히 같은 문자열 |
| Keyword | "턱보톡스 뉴럭스" | 키워드 "턱보톡스" 포함 |
| Regex | "사각턱BT_나보타_50" | `/사각턱.*B(TX |
| N-gram | "JAW BTX 엘러간" | 2-gram 유사도 계산 |
앞 단계에서 매칭에 성공하면 뒷 단계는 실행하지 않습니다. Exact가 가장 정확하고 빠르니까 우선 적용하고, 매칭 안 된 것만 다음 단계로 넘어가는 구조입니다. 각 단계마다 score가 붙어서, 나중에 "이 매핑은 신뢰도가 낮으니 사람이 확인해야 한다"는 판단도 가능합니다.
실제로 한 것
표준 시술 체계 구축
표준 시술 분류가 없으니 직접 만들어야 했습니다.
자사 플랫폼(B2C 제품)에는 시술 카테고리 체계가 잡혀있었는데, (병원의 요청과 시술 전문가가 시계열로 만든 카테고리 체계임)
그래서 초기 KOS에서는 이를 시드 데이터로 활용했습니다. 이미 시장에서 검증된 분류 체계이고, 나중에 강남언니 데이터와 비교할 때도 같은 기준으로 볼 수 있으니까요.
여기에 KOS 데이터에서만 나타나는 시술 N개도 시술 전문가 AI를 만들어, 같이 추상화하여 추가(해서 약 800개의 표준 시술을 확보했습니다.
매칭 규칙 시딩
800개 표준 시술에 대해 수천 개의 매칭 규칙을 자동 생성했습니다. (초기 정확도는 꽤 낮았음)
| 규칙 타입 | 역할 |
|---|---|
| Exact | 정확히 같은 이름 매칭 |
| Keyword | 핵심 키워드 포함 여부 |
| Regex | 약품명/영어 변형 패턴 |
| N-gram | 2-gram 유사도 기반 매칭 |
| Exclude | 오매칭 방지 (마취, 부자재 등) |
규칙 생성 과정에서 재밌었던 트레이드오프가 하나 있었습니다.
N-gram 단계를 처음에는 넣지 않았는데, 매핑률이 65% 언저리에서 멈추더라고요. "JAW BTX"처럼 영어 약어로만 적어놓은 항목들이 Keyword나 Regex로는 잡히지 않았습니다.
예상할 수 잇는 지점이지만, N-gram을 추가하면 매핑률은 올라가지만, 오매칭 리스크도 같이 올라갑니다.
"피부보톡스"와 "피부관리"의 2-gram 유사도가 의외로 높게 나올 수 있거든요. 그래서 N-gram 매칭에는 score threshold를 다른 단계보다 높게 설정하고, Exclude 규칙으로 알려진 오매칭 패턴을 차단하는 방식으로 해결했습니다.
결과 측정을 위한 대시보드
매핑 엔진을 만드는 것만큼 중요했던 게 "지금 얼마나 잘 되고 있는지"를 지속적으로 볼 수 있는 대시보드였습니다. BI 도구인 Metabase에 아래 항목들을 구성했습니다.
전체 매핑률 (현재 약 80%)
병원별 매핑률 분포
매칭 단계별 기여도 (Exact가 몇 %, Keyword가 몇 %)
unmapped 항목 목록 (왜 매핑 안 됐는지 원인 분류)
unmapped 항목을 보면 매핑 엔진의 한계가 아니라, 표준 시술 체계의 한계인 경우가 대부분이었습니다. "마스크팩", "진정관리", "줄기세포지방이식" 같은 건 현재 800개의 표준 시술에 해당하는 분류 자체가 없어서 매핑이 안 되는 거예요. (알고리즘 결함이 아닌 타겟 부재로 판단함)
가격 비교에서 만난 용량 문제
아래 수치는 실제 값이 아닌 예시 값을 기입했습니다.
표준화가 끝나니 다음 질문이 자연스럽게 이해 관계자분들과의 미팅에서 나왔습니다.
"플랫폼(온라인)에서 '사각턱보톡스'로 예약한 사람이 결제한 금액 vs KOS(오프라인)에서 실제 결제된 금액이 얼마나 차이 나는가?"
그런데 비교하려고 데이터를 뽑아보니 문제가 보였는데요.
사각턱보톡스 실 결제 데이터
- 최솟값: 480원
- 최댓값: 1,197,900원
- 비율: 약 2,485배
같은 "사각턱보톡스"인데 가격이 2,485배 차이...? 시술명만으로 비교하면 완전히 무의미한 데이터가 됩니다.
원인은 용량이었습니다. KOS 결제 데이터에는 다행히 실제 시술 시점의 단위와 수량이 기록되어 있었습니다.
사각턱보톡스, 용량별 분포
- 50 UNIT → 평균 62,809원 (71% 점유)
- 100 UNIT → 평균 164,270원 (23% 점유)
- 150 UNIT → 평균 790,374원 (소수)
이걸 단위당 가격으로 정규화하면 이야기가 많이 달라지는데요.
단가 정규화 후
- 50 UNIT → 1,256원/UNIT
- 100 UNIT → 1,643원/UNIT
- 125 UNIT → 1,034원/UNIT
가격 편차: 2,485배 → 1.6배
같은 데이터인데 보는 관점만 바꿨더니 의미 있는 비교가 가능해졌습니다.
하지만 모든 시술에 용량 데이터가 있는 건 아닙니다. 전체 N만 건 중 71%(M만 건)만 단위 정보를 보유하고 있었고, 시술별로도 편차가 컸습니다. 보톡스류는 거의 94% 커버리지인데, 토닝 류는 1.5%밖에 안 되더라고요.
그래서 3-Tier 가격 비교 프레임워크를 설계했습니다. (아직 실험중!)
| Tier | 조건 | 비교 방식 | 대상 시술 | 커버리지 |
|---|---|---|---|---|
| Tier 1 (정밀) | 양측 단위 정보 존재 | 단가 정규화 (원/UNIT, 원/CC) | 보톡스, 필러, 리쥬란, 스킨부스터 | ~60% |
| Tier 2 (근사) | 최빈 용량이 명확 | 해당 용량 기준 평균가 비교 | 리프팅류 (온다, 울쎄라, 슈링크) | ~25% |
| Tier 3 (분포) | 단위 정보 없음 | Median + IQR로 분포 비교 | 토닝, 필링, 점제거, 관리류 | ~15% |
정밀도가 떨어지더라도 커버리지를 확보하는 방향으로 갔습니다. Tier 1로 비교할 수 없는 시술이라고 해서 분석에서 제외하면, 데이터의 가치가 그만큼 줄어드니까요.
결과
작업 후 일주일이 지난 현재까지의 정량적 성과입니다. (아래 데이터는 실 데이터들이 나와있어 잘랐습니다)
매핑률 80%
N개 병원 운영 중
(수십만 건 이상의) 표준 시술 기준으로 재 구매율 / 실 결제액 / 인기있는 시술 등 집계 가능 (+ 대시보드 제공)
아, 그리고 unmapped에 대해서 다시 조금 남겨보자면, 나머지 20%가 매핑되지않은 이유는 크게 두 가지입니다.
하나는 표준 시술 체계에 해당 분류가 없는 경우 ("마스크팩", "진정관리" 등)
다른 하나는 비시술 항목이 섞여 있는 경우 ("수면마취", "가스마취")
이건 위에서 잠깐 언급했듯 매핑 알고리즘의 결함이 아닌 표준 체계 확장이나 제외 규칙 추가로 해결할 영역으로 바라보고있습니다.
정리하며
이 작업의 본질은 이면 데이터로 해자를 만드는 것입니다. AI가 판 치는 시대에 쉽게 획득할 수 있는 정보들은 점점 더 가치가 낮아지고 이면 데이터들은 가치가 극단적으로 올라갈것이라 생각합니다.
예약 플랫폼은 예약 데이터를 가지고 있습니다. 누가 어떤 시술에 관심이 있고, 얼마를 쓸 의향이 있는지(표면). 하지만 실제로 어떤 시술이 행해졌고 얼마가 결제됐는지는(이면) 모릅니다.
하지만 오프라인 시술 데이터를 다루는 KOS는 "실제 데이터"를 가지고 있습니다. (우리는 이걸 이면 데이터라고 표현하고있습니다)
그래서 표준화된 시술 분류 체계 위에서 이 데이터를 분석할 수 있게 노력중입니다.
시간이 지날수록 데이터가 쌓이고, 매핑 정확도는 자기학습으로 올라가고, 비교할 수 있는 시술의 범위도 넓어집니다. 이게 복리로 작동하는 데이터 해자의 구조라고 기대합니다.
아직 초기 단계고 풀어야 할 과제가 많습니다. 플랫폼 측과의 실제 가격 비교 분석, 표준 시술 확장 프로세스 정의, unmapped 항목의 체계적 처리 등. 진행되는 대로 후속 글에서 다루보겠습니다.


