기억기반추론 MBR: 유사 사례를 검색해 의사결정에 재사용하는 방법

기억기반추론(MBR)의 검색·재사용·수정·비교·유지 흐름과 거리·결합 함수, 인덱싱 및 운영 설계 기준을 정리한다.

2026-08-14 · 최초 발행 2025-10-14

과거 케이스를 현재 판단에 연결하는 방식

기억기반추론(Memory Based Reasoning, MBR)은 과거의 문제-해결 쌍 가운데 현재 입력과 가까운 사례를 찾아 그 해결을 재사용하는 추론 기법이다. 사례기반 접근의 핵심은 새 문제를 독립적으로 풀기보다, 이미 축적된 경험을 검색 가능한 지식으로 다루는 데 있다.

분류와 예측 모두에 적용할 수 있으며, 레코드 형식의 제약도 비교적 약하다. 수치형·범주형·순서형처럼 서로 다른 데이터가 섞여 있어도 공통 거리 함수를 적절히 정의하면 처리 대상이 될 수 있다.

거리 함수 F_dist는 두 레코드 사이의 거리 d(A, B)를 계산한다. 일반적인 메트릭 성질은 다음과 같다.

  • 비음수성: d(A, B) ≥ 0
  • 대칭성: d(A, B) = d(B, A)
  • 동일성: d(A, A) = 0
  • 삼각부등식: d(A, B) ≤ d(A, C) + d(C, B)

결합 함수 F_comb는 검색된 k개 사례의 결과를 하나의 답으로 만드는 역할을 맡는다. 다수결, 가중 다수결, 반거리 가중 회귀, 사례 적응(adaptation) 규칙이 여기에 해당한다.

검색한 사례를 다시 지식으로 남기는 흐름

MBR은 검색(Retrieve), 재사용(Reuse), 수정(Revise), 비교(Review), 유지(Retain)의 흐름으로 운영된다. 검색 단계에서 유사한 후보를 찾고, 재사용과 수정을 통해 현재 맥락에 맞는 해법으로 조정한다. 비교는 새 사례를 보존할 가치가 있는지 확인하는 관문이며, 유지 단계는 검증된 결과를 케이스베이스에 반영한다.

이 구조는 오프라인 학습 비용이 낮은 지연학습(lazy learning) 특성을 가진다. 대신 실제 요청이 들어오는 온라인 구간에서 거리 계산과 결과 결합이 수행된다.

아니오아니오통과실패로깅입력: 신규 문제(쿼리 케이스)전처리: 정규화/결측치처리/특징선택인덱스 존재?최근접 탐색: ANN/KD-tree선형 검색: 전수 거리 계산상위 k 사례 선택결합 F_comb: 다수결/반거리가중도메인 제약 만족?출력: 해결안/예측값수정 Revise: 규칙/휴리스틱적용검증 Review: 품질/리스크체크유지 Retain: 케이스베이스업데이트예외 처리:에스컬레이션/전문가 검토피드백 저장

최근접 결과가 없어서 k=0이 되면 특징 공간을 다시 설정하거나 유사도 임계값 완화를 검토한다. Review가 실패한 사례는 전문가 검토 큐로 라우팅하고, 케이스를 보존하지 않는 정책을 적용할 수 있다. 동시 업데이트가 발생하는 환경이라면 케이스 버전 관리와 쓰기 락 또는 멀티버전 병행제어가 필요하다.

데이터 유형에 맞춰 거리와 결합을 정한다

수치형 데이터에는 표준화 유클리드 거리나 마할라노비스 거리를, 범주형에는 해밍 또는 오버랩 거리를 사용할 수 있다. 혼합형 데이터는 Gower 거리, 텍스트·이미지 임베딩은 코사인 거리나 내적 기반 거리가 후보가 된다.

분류에서는 k-NN 다수결이나 클래스별 가중 합을 사용한다. 회귀와 예측에서는 반거리 가중 평균, 지역적 선형 적합, 도메인 규칙에 따른 사례 적응이 가능하다.

수치형 특성은 z-score 또는 로버스트 스케일링으로 맞추고, 범주형 특성에는 가중치를 부여해 희소 카테고리가 과소평가되지 않게 한다. 특징별 가중치 w_i는 유전알고리즘, 베이지안 최적화, 학습가능 거리 네트워크로 학습할 수 있으며, 비용 민감 분류에서는 클래스 가중치를 적용한다.

분류 결합은 다음처럼 표현할 수 있다.

argmax_c Σ_i w_i·1(y_i=c), w_i = 1/(d_i+ε)^p

회귀는 다음과 같이 가중 평균을 구한다.

ŷ = Σ_i w_i·y_i / Σ_i w_i

온도나 지역처럼 결과를 조정해야 하는 조건이 있다면 규칙 기반 파라미터 보정으로 사례 적응을 수행한다.

인덱스가 커질수록 검색 전략이 달라진다

선형 검색은 O(N) 비용이 들기 때문에 케이스 수가 늘면 병목이 된다. 저차원 연속형 데이터에는 KD-tree나 Ball-tree가 적합하고, 고차원 또는 임베딩 데이터에는 HNSW, IVF-PQ, ScaNN 같은 근사 최근접 탐색을 고려할 수 있다.

메모리 상주 인덱스와 디스크 기반 인덱스 사이에는 저장·응답 특성의 트레이드오프가 있다. 지연 일관성을 허용하는 경우에도 배치 재색인 전략은 필요하다. 인덱싱 도입 시 평균 응답시간이 10배 이상 개선된 사례가 가능하지만, 데이터와 차원성에 따라 결과는 달라진다.

사고 대응부터 지식관리까지

IT 운영(AIOps)에서는 유사 로그와 알람 패턴을 찾아 재현 사고의 해결책을 추천할 수 있다. 이는 MTTR 단축과 야간 온콜 부담 경감에 연결된다.

설비 예지보전에서는 센서 시계열 임베딩 사이의 유사도를 이용해 고장 유형을 식별하고 잔여수명을 추정한다. 현장 조건 보정 규칙을 사례 적응과 결합하는 방식도 가능하다.

고객지원과 지식관리에서는 과거 티켓 및 솔루션을 검색해 답변을 추천한다. 케이스 품질 리뷰를 운영 흐름에 넣으면 지식베이스를 정제하는 루프를 만들 수 있다. 금융 리스크와 이상치 탐지에서는 거래 패턴의 근접 이웃 밀도를 바탕으로 이상치를 판단하고, 라벨이 부족한 환경에서 준지도 의사결정을 지원할 수 있다.

유사 사례 재사용은 프로세스 성숙도에 따라 초기 대응시간을 20~40% 단축할 수 있다. 콜드스타트 상황에서는 초기 모델이 없어도 기준선 성능을 확보하는 데 도움이 된다. 유사 사례 목록을 함께 제시할 수 있어 판단 근거의 투명성과 신뢰성도 높아지며, 지식 축적과 재사용 문화를 뒷받침한다.

품질과 일관성을 운영 안에 넣는다

도메인을 반영한 특징 정의, 일관된 누락치 전략, drift 모니터링은 기본적인 품질 관리 항목이다. 특징을 다양하게 만들수록 차원의 저주가 커질 수 있으므로 선택적 투영(PCA/UMAP)이나 표현학습을 병행할 수 있다.

Review 단계에서는 라벨 품질을 점검하고, 중복 사례를 제거하며, 노이즈 케이스를 분리한다. 다만 필터링을 지나치게 엄격하게 적용하면 커버리지가 줄어들 수 있으므로 리콜과 정밀도 사이의 균형 정책이 필요하다.

저장소 측면에서는 배치 재색인, 샤딩+ANN, 핫/콜드 티어 분리가 운영 선택지다. 근사탐색은 재현율 손실 가능성이 있으므로 임계값 기반 재검증(Exact rerank)을 함께 둘 수 있다. Retain 트랜잭션 로그, 버전드 스키마, 롤백 전략도 케이스베이스 변경을 통제하는 데 쓰인다. 강한 일관성은 쓰기 지연을 늘릴 수 있어, 지연 일관성과 주기적 정합성 검사를 절충안으로 삼을 수 있다.

지표 관점 요약
성능 평균 지연 인덱싱 유무와 차원성에 민감. ANN+rerank로 지연-정확도 균형
확장성 데이터 크기 선형 증가 경향. 샤딩·압축·표본추출 전략 병행 필요
일관성 결과 안정성 특징/가중치 변화에 민감. 버전 고정과 A/B 검증 권장
안정성 장애 대응 인덱스 재빌드·스냅샷·WAL 기반 복구 체계 필요
운영 편의 유지보수 Retain 정책과 데이터 카탈로그로 누적 품질 관리

혼합형 데이터로 분류와 회귀를 수행하는 예시

전제조건: Python 3.10+, numpy>=1.23, scikit-learn>=1.2 설치

# pip install numpy scikit-learn
import numpy as np
from collections import Counter

def gower_distance(x, y, num_idx, cat_idx, ranges):
    d = 0.0; m = 0
    if num_idx:
        nx = x[num_idx].astype(float)
        ny = y[num_idx].astype(float)
        d += np.sum(np.abs(nx - ny) / (ranges + 1e-12))
        m += len(num_idx)
    if cat_idx:
        d += np.sum(x[cat_idx] != y[cat_idx])
        m += len(cat_idx)
    return d / max(m, 1)

def knn_predict(X_train, y_train, x_query, k=5, task='class',
                num_idx=None, cat_idx=None, ranges=None, p=2.0, eps=1e-6):
    # 거리 계산
    dists = np.array([gower_distance(x_query, xt, num_idx, cat_idx, ranges) for xt in X_train])
    # 상위 k 선택
    idx = np.argsort(dists)[:k]
    neigh_y = y_train[idx]; neigh_d = dists[idx]
    # 결합 함수
    if task == 'class':
        weights = 1.0 / (neigh_d + eps) ** p
        agg = {}
        for cls, w in zip(neigh_y, weights):
            agg[cls] = agg.get(cls, 0.0) + w
        return max(agg.items(), key=lambda t: t[1])[0]
    else:
        weights = 1.0 / (neigh_d + eps) ** p
        return float(np.dot(weights, neigh_y) / np.sum(weights))

# 예시 사용
# 수치 2개, 범주 1개 컬럼 가정
X = np.array([
    [10.0, 0.2, 'A'],
    [11.5, 0.1, 'B'],
    [9.7,  0.4, 'A'],
    [13.0, 0.3, 'B'],
], dtype=object)
y_cls = np.array(['ok', 'bad', 'ok', 'bad'], dtype=object)
y_reg = np.array([100.0, 200.0, 120.0, 220.0], dtype=float)

num_idx = [0,1]; cat_idx = [2]
ranges = np.ptp(np.array(X[:, num_idx], dtype=float), axis=0)

q = np.array([10.5, 0.25, 'A'], dtype=object)

print("분류:", knn_predict(X, y_cls, q, k=3, task='class',
                         num_idx=num_idx, cat_idx=cat_idx, ranges=ranges))
print("회귀:", knn_predict(X, y_reg, q, k=3, task='reg',
                         num_idx=num_idx, cat_idx=cat_idx, ranges=ranges))

특징별 범위(ranges)는 학습셋 기준으로 고정하고, 데이터 드리프트를 감지하면 다시 계산한다. k, p, 가중치 같은 하이퍼파라미터는 검증셋을 바탕으로 베이즈 최적화를 적용할 수 있다. ANN 인덱스를 도입할 때는 상위 M 후보를 ANN으로 가져온 뒤 E=Exact로 재정렬하는 2단계 검색을 사용할 수 있다.

기억기반추론사례기반추론k-NN유사도 검색거리함수데이터 마이닝