← 전체 해설 목록  ·  week-02 · 3강

3강 — 임베딩 심화: 벡터·차원·코사인 유사도

🎯 학습 목표

📖 해설

1주차 2강에서 임베딩을 처음 만났죠. "단어를 좌표로 바꾼다, 가까우면 비슷하다"를 직관적으로 이해하는 게 목표였습니다. 오늘은 한 단계 더 들어갑니다. 실무에서 임베딩을 쓰려면 어떤 모델을 쓸지, 비용은 얼마인지, 단어 임베딩과 문장 임베딩 중 무엇을 쓸지 판단해야 하고, 그러려면 벡터·차원·코사인 유사도 같은 용어를 알아야 해요. 이 용어들을 모르면 API 문서나 기술 블로그, 논문을 읽다 막힙니다. 공식을 외우거나 계산하는 게 목표가 아니라, 뭔지·언제 쓰는지·왜 중요한지만 잡으면 됩니다.

지난 프로젝트(전처리 파이프라인) 복습: Steam 리뷰를 로딩·탐색하고, 결측치·중복을 자동 제거하고, 특수문자 제거·소문자화·공백 정리를 함수로 묶어 재사용 가능하게 만들었습니다. 이제 깨끗한 데이터를 AI에게 넘길 준비가 끝났어요. 그런데 AI는 숫자만 이해하니, 텍스트를 숫자로 바꿔야 합니다. 그 과정이 임베딩이었죠.

0. 2차시에 배웠는데 왜 또 배울까요?

직관적 이해(좌표·가까우면 비슷)만으로는 실무에서 결정을 못 내리기 때문입니다. 세 가지 상황에서 원리가 필요해요.

  1. 모델 선택 — 임베딩 모델은 하나가 아닙니다(768차원·1536차원 등). "무조건 큰 게 좋을까?"를 판단해야 합니다.
  2. 비용 계산 — 차원이 높을수록 비용·저장·계산이 늘어요. 리뷰 10만 건이면 768차원과 1536차원은 처리 비용이 약 2배 차이 납니다.
  3. 디버깅 — AI가 이상한 결과(예: "좋아요"와 "싫어요"가 비슷하다고)를 냈을 때, 원리를 알아야 왜 그런지 추론하고 고칠 수 있습니다.

그래서 오늘 용어와 원리를 확실히 정리합니다. 실무에서 판단을 내릴 수 있도록요.

1. 용어 ① 벡터(vector) — "숫자들의 순서 있는 나열"

고등학교 때 벡터는 "방향과 크기를 가진 화살표"라고 배웠습니다. 수학에선 맞아요. 그런데 프로그래밍, 특히 AI에서 벡터는 그냥 숫자들의 순서 있는 나열이라고 생각하면 됩니다. [0.8, 0.3, 0.5] 처럼요.

임베딩 API를 호출하면 바로 이 숫자 배열이 돌아옵니다. [0.12, -0.45, 0.78, ...] 같은 식으로요. 왜 벡터가 중요할까요? 벡터로 바꿔야 계산이 가능하기 때문입니다. "좋아요"라는 글자로는 계산을 못 하지만, 벡터로 바꾸면 다른 벡터와 비교·거리 계산이 됩니다. 실무에서 API 문서에 returns vector, embedding vector 같은 말이 나오면 "아, 숫자 배열이 돌아오는구나" 하면 됩니다.

2. 용어 ② 차원(dimension) — "벡터를 이루는 숫자의 개수"

차원은 벡터를 구성하는 숫자의 개수입니다. 숫자가 3개면 3차원, 768개면 768차원이에요. 차원이 높을수록 표현력이 좋아집니다. 2차원에서는 평면 위 위치(XY)만 표현하지만, 768차원이면 "게임"이라는 단어의 재미·경쟁·온라인·커뮤니티 같은 여러 측면을 담을 수 있어요.

하지만 차원이 높다고 무조건 좋은 건 아닙니다. 여기서 비용이 들어가거든요.

차원 벡터 1개 크기 리뷰 10만 건 저장
768차원 약 3KB 약 300MB
1536차원 약 6KB 약 600MB

저장 공간도, 계산 시간도 약 2배 차이가 납니다. 모델을 고를 때 이 트레이드오프를 알아야 해요.

3. 용어 ③ 코사인 유사도(cosine similarity) — "방향이 얼마나 비슷한가"

실무에서 가장 많이 쓰이는 유사도 측정법입니다. 두 벡터가 얼마나 비슷한 방향을 가리키는지 재며, 결과는 -1에서 1 사이 숫자로 나옵니다.

값 의미 예시
1 완전히 같은 방향 "좋아요" vs "최고예요" ≈ 0.9
0 무관계(직각) "게임" vs "사과" ≈ 0
-1 정반대 방향 "좋아요" vs "싫어요" (음수)

왜 하필 코사인일까요? 벡터의 크기(길이)가 달라도 방향만 비교하기 때문입니다. 그래서 긴 리뷰에서 뽑은 벡터와 짧은 리뷰에서 뽑은 벡터를 공정하게 비교할 수 있어요.

이걸 실무 그림으로 풀면 — 검색어를 입력하면 그 검색어가 벡터로 바뀌고, 이미 벡터로 저장된 수많은 문서(보통 벡터 DB에 저장)와 코사인 유사도를 비교해, 검색어와 가장 비슷한 문서를 뽑아 줍니다. 검색·추천·분류가 전부 이 원리예요.

4. 단어 임베딩 vs 문장 임베딩

임베딩에는 두 종류가 있습니다.

GPT와 BERT는 딥러닝에서 문장을 이해하는 대표적인 두 모델입니다. GPT의 G는 Generate(생성) — 문장 생성에 특화. BERT의 B는 Bidirectional(양방향) — 문장을 앞→뒤, 뒤→앞 양방향으로 읽어 이해도가 높습니다. 요즘은 GPT 계열이 크게 각광받고 있죠.

리뷰 분석에는 문장 임베딩을 씁니다. 리뷰가 문장이고, 같은 단어라도 문맥에 따라 긍정·부정이 갈리기 때문이에요. "이 게임에 미쳤다"는 칭찬이지만 "버그가 미쳤다"는 욕이잖아요. 문장 임베딩은 이 차이를 구분합니다.

5. 사전학습(pre-trained) 모델 — 남이 만든 엔진을 빌린다

사전학습 모델은 구글·OpenAI·마이크로소프트 같은 회사가 수십억 개의 텍스트로 몇 주~몇 달간 미리 학습시켜 둔 모델입니다. 우리는 그걸 API 호출 한 번으로 가져다 씁니다. 왜 직접 학습 안 할까요?

  1. 시간 — 임베딩 모델 하나 학습에 며칠~몇 주. API는 호출 한 번이면 끝.
  2. 비용 — 고성능 GPU를 클라우드에서 빌리면 시간당 수만~수십만 원, 한 번 학습에 수천만 원. API는 건당 0.몇 원 수준.
  3. 성능 — 구글·OpenAI 연구원이 최적화해 둔 모델이라 직접 만든 것보다 훨씬 좋습니다.

요리에 비유하면, 채소를 직접 키우고 소를 기르는 대신 마트에서 손질된 재료(혹은 완성된 요리)를 사 오는 것과 같습니다. 시간도 아끼고 품질도 보장돼요.

6. 실제 유사도, 직관과 맞을까? — 세 가지 예시

# 실제로는 임베딩 API로 문장을 벡터로 바꾼 뒤 코사인 유사도를 계산합니다.
# 결과 수치는 모델·환경에 따라 달라질 수 있습니다(아래는 강의에서 제시한 예시 값).
from numpy import dot
from numpy.linalg import norm

def cosine_similarity(a, b):
    """두 벡터 a, b의 코사인 유사도(-1~1)를 계산한다."""
    return dot(a, b) / (norm(a) * norm(b))

# v1 = get_embedding("이 게임 정말 재밌어요")  # ← 임베딩 API 호출(개념)
# v2 = get_embedding("플레이하는 내내 즐거웠습니다")
# print(cosine_similarity(v1, v2))  # 예시: 0.89
문장 쌍 유사도 왜?
"이 게임 정말 재밌어요" ↔ "플레이하는 내내 즐거웠습니다" 0.89 둘 다 긍정 + '재밌다≈즐겁다'. 글자는 달라도 의미가 비슷
"버그가 너무 많아요" ↔ "오류가 자주 발생합니다" 0.85 '버그≈오류', 같은 불만
"그래픽이 예뻐요" ↔ "스토리가 감동적이에요" 0.31 둘 다 긍정이지만 대상이 다름(그래픽 vs 스토리)

핵심: 글자가 달라도 의미가 비슷하면 높고, 감정이 같아도 대상이 다르면 낮습니다. 단순 키워드 매칭으로는 불가능한 분석이에요.

7. 임베딩의 실무 활용 5가지

  1. 검색 — 기존엔 키워드 매칭이라 "게임 추천"을 검색하면 그 단어가 든 문서만 나왔습니다. 임베딩을 쓰면 의미로 검색해서, "재미있는 거 뭐 있어요"라고 쳐도 게임 추천 글이 나옵니다.
  2. 추천 — 사용자가 좋아한 아이템과 비슷한 아이템을 추천. 넷플릭스의 "이 영화 봤으면 이것도 좋아하실 거예요"가 이 원리이고, 이를 협업 필터링(collaborative filtering)의 핵심으로 봅니다.
  3. 분류 — 텍스트를 벡터로 바꾼 뒤, '긍정 카테고리 벡터'와 '부정 카테고리 벡터' 중 어느 쪽에 가까운지로 분류합니다.
  4. 중복 탐지 — 같은 내용의 리뷰 반복, 표절 의심 글을 찾아냅니다.
  5. RAG (Retrieval-Augmented Generation) — 챗봇이 질문을 받으면, 먼저 관련 문서를 임베딩으로 검색해 찾고, 그 문서를 AI에게 컨텍스트로 제공해 답변을 생성합니다.

8. 비용 트레이드오프 — 차원은 무조건 높다고 좋지 않다

  1. 저장 비용 — 768차원은 벡터당 약 3KB, 1536차원은 약 2배. 10만 건이면 300MB vs 600MB.
  2. 계산 시간 — 차원이 높을수록 유사도 계산이 오래 걸립니다. 실시간 검색이라면 응답 속도가 중요하죠.
  3. 한계 수익 — 768→1536으로 올리면 정확도가 조금 오릅니다. 하지만 1536→3072는 비용은 2배인데 효과는 미미해요. 어느 시점부터는 차원을 높이는 의미가 없습니다.

실무 결론: 대부분 768차원으로 충분합니다. 법률 문서나 의료 기록처럼 정밀함이 아주 중요할 때만 더 높은 차원을 고려하세요.

9. 실무에서 자주 하는 실수 3가지

  1. 무조건 높은 차원 선택 — "높으면 좋겠지" 하고 1536·3072를 고릅니다. → 768로 시작하고, 정확도가 부족할 때 올리세요.
  2. 같은 텍스트를 반복 임베딩 — 임베딩은 결정론적입니다(같은 입력 → 항상 같은 출력). 그런데 매번 API를 또 호출하면 돈 낭비예요. 한 번 계산한 걸 저장해 두고 재사용(캐싱, caching) 하면 비용을 90% 이상 줄일 수 있습니다. (고급 영역)
  3. 단어 임베딩으로 문장 분석 — 리뷰는 문장이고 문맥이 가장 중요합니다. 리뷰 분석에는 반드시 문장 임베딩을 쓰세요.

🔑 핵심 용어

용어 쉬운 설명
벡터(vector) 숫자들의 순서 있는 나열. 임베딩 API의 결과물
차원(dimension) 벡터를 이루는 숫자의 개수 (768·1536 등)
코사인 유사도 두 벡터의 방향이 얼마나 비슷한지 (-1~1)
단어/문장 임베딩 단어 하나 / 문장 전체를 벡터로. 리뷰엔 문장 임베딩
BERT / GPT 양방향 이해(B) / 생성(G)에 특화된 대표 모델
Sentence-BERT(SBERT) 문장 비교에 특화된 문장 임베딩 모델
사전학습 모델 남이 미리 학습시켜 공개한 모델. 가져다 씀
캐싱(caching) 계산 결과를 저장해 재사용 → 비용 절감
벡터 DB 문서 벡터를 저장·검색하는 데이터베이스

🎮 게임 기획자 시점

"감정이 같아도 대상이 다르면 유사도가 낮다"(그래픽 0.31 vs 스토리)는 결과는 기획에 직접 쓰입니다. 긍정 리뷰를 무엇에 대한 칭찬인지(그래픽/스토리/전투/과금)로 자동 분류하면, "유저가 정확히 어디에 만족하는가"를 데이터로 볼 수 있어요. 임베딩 구조(텍스트→벡터→유사도)를 이해한 기획자는 단순히 "긍정 70%"가 아니라 "긍정의 결이 어디로 쏠려 있나"를 설계할 수 있습니다. 또 캐싱으로 비용 90%를 아끼는 감각은 그대로 운영비 절감 의사결정입니다.

⚠️ 흔한 오해 / 짚고 갈 점

✅ 30초 정리

  1. 벡터=숫자 나열, 차원=숫자 개수, 코사인 유사도=두 벡터의 방향 비교(-1~1). API 문서·블로그가 읽히게 됩니다.
  2. 리뷰 분석엔 문장 임베딩(문맥 반영), 사전학습 모델(가져다 쓰기)을 씁니다.
  3. 768차원으로 시작, 캐싱으로 절감, 용도에 맞게 선택. 한 줄 요약: 임베딩은 텍스트를 숫자로 바꿔 계산 가능하게 만드는 것.

▶️ 다음 강 연결

이제 질문 하나. 리뷰가 10만 건 있으면 전부 임베딩해서 분석해야 할까요? 정답은 아니오입니다. 잘 뽑은 1,000건이 10만 건과 거의 같은 결론을 냅니다. 다음 4강에서 샘플링과 대표성을 배웁니다.

전체📚 강의 목록