본문으로 바로가기
dobidugi
목록으로
수학

벡터의 내적과 추천 점수

7분
목차

📋 요약 한 줄 요약 내적은 두 벡터의 대응하는 항목을 곱해 모두 더한 숫자 하나를 구하는 연산이다. 수량과 단가로 합계 금액을 구하거나, 관심도와 주제 점수로 추천 점수를 구하는 데 사용할 수 있다.

2026-09-30 수학 공부 대화에서 배운 내용을 정리한 개인 학습 노트. 먼저 내적 자체의 계산과 추천 예시를 이해하고, 정규화와 유사도는 그다음에 연결한다.

1. 내적(Dot Product)이란 무엇인가

내적은 두 벡터(vector)를 입력받아, 같은 자리의 값들을 곱해서 모두 더한 숫자 하나를 만드는 연산이다. 이처럼 숫자 하나로 나타내는 값을 수학에서는 스칼라(scalar)라고 부른다.

입력: 두 벡터
계산: 같은 자리끼리 곱하기 → 전부 더하기
출력: 숫자 하나

그 숫자가 무엇을 뜻하는지는 입력한 벡터의 의미에 따라 달라진다. 구매 수량과 상품 단가를 넣으면 총금액이 되고, 사용자 관심도와 글의 주제 점수를 넣으면 정한 규칙에 따른 추천 점수가 될 수 있다.

왜 같은 자리끼리 곱해서 더하는가

장바구니에 상품 두 종류가 있다고 해보자. 두 벡터의 순서는 모두 [상품 A, 상품 B]이다.

구매 수량 = [2,3]
상품 단가 = [1000,2000]원

상품 A 금액 = 2*1000 = 2000원
상품 B 금액 = 3*2000 = 6000원

총금액 = 2000 + 6000 = 8000원

이 계산이 바로 두 벡터의 내적이다. 같은 자리끼리 곱하면 각 상품의 금액이 나오고, 이를 더하면 전체 금액이 나온다. 서로 대응하는 두 정보를 항목별로 결합한 뒤 하나의 결과로 합산하는 것이다.

추천 점수(Recommendation Score)도 내적으로 계산할 수 있다

개발 글 추천 서비스를 만든다고 가정한다. 숫자 순서는 항상 [Java, AI]이다. 아래 값은 직접 정한 설명용 관심도와 주제 점수이다.

사용자 관심도 = [2,1]
→ Java 주제 점수에 2배, AI 주제 점수에 1배의 비중을 준다.

글 A의 주제 점수 = [3,0]
글 B의 주제 점수 = [1,3]

장바구니에서는 수량 * 단가를 더했다. 추천에서는 각 주제의 관심도 * 주제 점수를 더한다.

글 A 추천 점수 = 2*3 + 1*0
               = 6 + 0
               = 6

글 B 추천 점수 = 2*1 + 1*3
               = 2 + 3
               = 5

추천 점수를 수식으로 표현하면 다음과 같다. 첫 줄은 글 A, 둘째 줄은 글 B의 점수이다.

[2,1]⋅[3,0]=2×3+1×0=6[2,1]⋅[1,3]=2×1+1×3=5\begin{aligned} \left[2,1\right]\cdot\left[3,0\right] &= 2\times3 + 1\times0 = 6 \\ \left[2,1\right]\cdot\left[1,3\right] &= 2\times1 + 1\times3 = 5 \end{aligned}

점수가 높은 순서로 정렬하면 글 A → 글 B 순서로 추천한다. Java에 높은 비중을 두었기 때문에 Java 주제 점수가 큰 글 A가 우선한다.

이 예시에서 내적은 여러 항목의 중요도를 반영해 점수 하나를 만드는 도구이다. 이를 가중합(weighted sum), 즉 각 항목에 중요도를 곱해서 더한 값으로 이해할 수 있다.

추천 알고리즘에는 점수 계산 외에도 관심도를 정하는 방법, 글의 주제 점수를 정하는 방법, 이미 읽은 글을 제외하는 규칙 등이 들어간다. 내적은 그중 점수 계산에 사용할 수 있는 방법이다.

같은 자리는 같은 항목을 나타내야 한다. 사용자 벡터는 [Java, AI]인데 글 벡터는 [AI, Java]라면 의도한 추천 점수를 계산할 수 없다.

숫자만으로 계산해보기

두 벡터의 같은 자리끼리 곱한 다음, 그 결과를 모두 더한다. 두 벡터는 숫자의 개수가 같아야 한다.

A = [2,3]
B = [4,5]

첫 번째끼리 곱하기: 2*4 = 8
두 번째끼리 곱하기: 3*5 = 15

내적 = 8 + 15
     = 23

숫자가 두 개인 벡터에서는 다음처럼 쓴다.

내적 = A의 첫 번째 값 * B의 첫 번째 값
     + A의 두 번째 값 * B의 두 번째 값

수식으로 표현한 내적 공식

두 벡터가 다음과 같을 때:

A=[a1,a2],B=[b1,b2]\mathbf{A}=[a_1,a_2],\quad \mathbf{B}=[b_1,b_2]

숫자가 두 개인 벡터의 내적 공식은 다음과 같다.

A⋅B=a1b1+a2b2\mathbf{A}\cdot\mathbf{B}=a_1b_1+a_2b_2

위에서 계산한 예시에 적용하면:

[2,3]⋅[4,5]=2×4+3×5=8+15=23[2,3]\cdot[4,5]=2\times4+3\times5=8+15=23

💡 TIP 내적의 결과는 숫자 하나 [2,3]과 [4,5]를 내적한 결과는 23이다. 결과가 [8,15]인 것은 아니다. 자리별 곱셈 결과를 마지막에 더한다.

2. 변화량과 거리 계산에서 달라지는 부분

계산하는 일결과
변화량 B-A같은 자리끼리 뺀다벡터
두 점 사이 거리차이를 각각 제곱해 더하고 루트를 구한다길이를 나타내는 숫자 하나
내적 A·B두 벡터의 같은 자리끼리 곱해서 더한다숫자 하나

내적에는 거리 공식처럼 뺄셈이나 루트를 넣지 않는다. 내적 결과가 곧 두 점 사이 거리인 것도 아니다.

3. 내적과 정규화(Normalization)는 각각 무엇인가

내적은 두 벡터에서 숫자 하나를 계산하는 연산이고, 정규화는 벡터의 길이를 맞추는 작업이다.

개념계산 방법결과
내적같은 자리끼리 곱해서 모두 더한다숫자 하나
지금 배우는 정규화벡터의 각 값을 그 벡터 자체의 길이로 나눈다길이가 1인 벡터

정규화 예시:

벡터 = [3,4]
길이 = sqrt(3^2 + 4^2) = 5

정규화 = [3/5, 4/5]
       = [0.6,0.8]

벡터의 길이는 원점 [0,0]에서 그 벡터의 끝점까지의 거리이다. 정규화할 때는 다른 벡터와의 거리가 아니라 자기 자신의 길이를 사용한다. 길이가 0인 벡터는 이 방식으로 정규화할 수 없다.

다음에 연결할 주제: 방향의 유사도

내적 결과는 벡터의 방향과 길이에 모두 영향을 받는다. 길이의 영향을 없애고 방향의 유사도를 비교하려면, 두 벡터를 각각 길이 1로 정규화한 뒤 내적한다. 그 결과가 코사인 유사도(cosine similarity)이다.

내적 자체는 계산 방법이고, 그 결과를 무엇으로 해석할지는 사용하는 상황에 따라 정한다. 앞의 추천 예시에서는 정한 관심도를 반영한 점수로 사용했다. 정규화와 코사인 유사도는 별도로 복습할 후속 주제이며, 이 노트에서는 계산과 추천 점수에 집중한다.

RAG에서도 임베딩(embedding) 모델과 검색 방식에 맞게 내적이나 코사인 유사도를 활용할 수 있다. 실제 임베딩의 각 자리가 위 추천 예시처럼 Java나 AI라는 특정 주제를 직접 뜻한다고 가정하지 않는다.

4. Kotlin으로 내적 계산하기

다음 Kotlin 함수는 같은 자리끼리 곱한 값을 누적해서 내적을 계산한다.

fun dot(a: DoubleArray, b: DoubleArray): Double {
    require(a.size == b.size) {
        "두 벡터의 숫자 개수가 같아야 합니다."
    }

    var result = 0.0
    for (i in a.indices) {
        result += a[i] * b[i]
    }
    return result
}

fun main() {
    val user = doubleArrayOf(2.0, 1.0)
    val articleA = doubleArrayOf(3.0, 0.0)
    val articleB = doubleArrayOf(1.0, 3.0)

    println(dot(user, articleA)) // 6.0
    println(dot(user, articleB)) // 5.0
}

a.indices는 배열의 인덱스 범위이다. result += 값은 기존 결과에 값을 더해 저장한다는 뜻이다.

참고 자료

관련 노트



이전 글
벡터의 변화량과 유클리드 거리
다음 글
정규화와 코사인 유사도 — 방향을 비교해 추천하기