math
CHAPTER 35 / 45
읽기 약 2분
FUNCTION
내적: 유사도의 수학
핵심 개념
내적(dot product) = 코사인 유사도의 기반. RAG 벡터 검색·추천 시스템의 핵심 연산.
본문
내적 (Dot Product)
두 벡터 a, b의 내적:
a · b = a₁b₁ + a₂b₂ + ... + aₙbₙ
기하학적 의미:
a · b = ||a|| × ||b|| × cos(θ)
(크기) × (크기) × (사이 각의 코사인)
내적 = 0 → 90° 직각 (perpendicular)
내적 > 0 → 같은 방향 (예각)
내적 < 0 → 반대 방향 (둔각)numpy 내적
import numpy as np
a = np.array([3, 4])
b = np.array([1, 2])
# 내적
print(np.dot(a, b)) # 11 (3*1 + 4*2)
print(a @ b) # 11 (Python 3.5+ @ 연산자)
print((a * b).sum()) # 11 (직접 계산)
# 직각 벡터
c = np.array([4, -3])
print(np.dot(a, c)) # 0 (90도)
# 같은 방향
d = np.array([6, 8]) # a의 2배
print(np.dot(a, d)) # 50 (양수, 큼)코사인 유사도
def cosine_similarity(a, b):
"""두 벡터의 방향 유사도 — -1(반대) ~ 0(직각) ~ 1(같음)"""
dot = np.dot(a, b)
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
if norm_a == 0 or norm_b == 0:
return 0
return dot / (norm_a * norm_b)
# 같은 방향 (다른 크기)
v1 = np.array([1, 0])
v2 = np.array([5, 0])
print(cosine_similarity(v1, v2)) # 1.0 (완전 같음)
# 직각
v3 = np.array([0, 1])
print(cosine_similarity(v1, v3)) # 0.0 (직각)
# 반대 방향
v4 = np.array([-1, 0])
print(cosine_similarity(v1, v4)) # -1.0 (완전 반대)
# 벡터 크기에 무관 — 방향만 비교
# 추천 시스템·검색에서 사용실전 — RAG 벡터 검색
# RAG (Retrieval-Augmented Generation) 핵심
# 1. 문서를 임베딩 벡터로 변환
# 2. 쿼리도 임베딩
# 3. 코사인 유사도로 가장 가까운 문서 검색
# 가상 임베딩 (실제는 OpenAI/Cohere/sentence-transformers)
documents = {
'doc1': np.array([0.8, 0.5, 0.2, 0.1]), # "React 컴포넌트"
'doc2': np.array([0.7, 0.6, 0.3, 0.2]), # "React 훅"
'doc3': np.array([0.1, 0.2, 0.9, 0.8]), # "PostgreSQL 인덱스"
'doc4': np.array([0.2, 0.1, 0.8, 0.9]), # "DB 트랜잭션"
}
query = np.array([0.75, 0.55, 0.25, 0.15]) # "React useState"
# 모든 문서와 유사도 계산
results = sorted(
[(name, cosine_similarity(query, vec)) for name, vec in documents.items()],
key=lambda x: -x[1]
)
print("쿼리: React useState")
for name, sim in results:
print(f" {name}: {sim:.4f}")
# doc2: 0.99 (React 훅 — 가장 유사)
# doc1: 0.97 (React 컴포넌트 — 매우 유사)
# doc3: 0.30 (DB 인덱스 — 무관)
# doc4: 0.27 (DB 트랜잭션 — 무관)실전 — 추천 시스템
# 사용자-아이템 행렬을 벡터로
import numpy as np
# 5개 영화에 대한 평점 (0~5, 0=안봤음)
ratings = {
'Alice': np.array([5, 4, 0, 1, 2]),
'Bob': np.array([4, 5, 0, 0, 1]),
'Charlie': np.array([0, 0, 5, 4, 0]),
'Dave': np.array([1, 2, 4, 5, 5]),
}
def recommend_user(target, all_users, top_n=2):
"""가장 유사한 사용자 N명 추천"""
target_vec = all_users[target]
similarities = []
for name, vec in all_users.items():
if name == target:
continue
sim = cosine_similarity(target_vec, vec)
similarities.append((name, sim))
return sorted(similarities, key=lambda x: -x[1])[:top_n]
print(recommend_user('Alice', ratings))
# [('Bob', 0.99), ('Dave', 0.31)]
# Alice와 Bob이 가장 비슷한 영화 취향실전 — 검색 엔진 점수
# TF-IDF 벡터 + 코사인 유사도 = 기본 검색 엔진
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity as cos_sim_sklearn
documents = [
"React는 UI 라이브러리",
"Vue는 진화하는 프레임워크",
"Next.js는 React 기반 풀스택",
"PostgreSQL은 강력한 관계형 DB",
]
query = ["React 풀스택"]
vectorizer = TfidfVectorizer()
doc_vectors = vectorizer.fit_transform(documents)
query_vector = vectorizer.transform(query)
similarities = cos_sim_sklearn(query_vector, doc_vectors).flatten()
ranked = sorted(zip(documents, similarities), key=lambda x: -x[1])
for doc, sim in ranked:
print(f"{sim:.4f} {doc}")
# 결과:
# 0.6XXX Next.js는 React 기반 풀스택
# 0.4XXX React는 UI 라이브러리
# 0.0000 Vue는 진화하는 프레임워크
# 0.0000 PostgreSQL은 강력한 관계형 DB다음 챕터
CH.36 "행렬" — 벡터의 확장, 데이터 테이블의 수학.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 RAG 시스템에 코사인 유사도 검색을 적용하는 가이드와 적합한 임베딩 모델을 추천해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
한국 AI 검색 엔진의 유사도 알고리즘 사례 5개를 비교 분석해줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 문서 데이터로 임베딩 + 코사인 유사도 검색을 구축하고 정확도를 측정해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 벡터 DB(Pinecone/Weaviate/pgvector) 실전 비교와 한국 시장 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
내적: 유사도의 수학은 이 3가지만 확실히 잡으세요
1.내적은 두 벡터의 방향 유사성을 측정 — 코사인 유사도의 분자
2.코사인 유사도는 -1(반대) ~ 1(같음) — 벡터 크기에 무관, 방향만 비교
3.다음 챕터 CH.36에서 행렬 — 벡터의 확장, 데이터 테이블의 수학
공유하기
진행도 35 / 45