1 이 포스트의 핵심 질문
§1.1에서 벡터의 대수적 연산(덧셈, 스칼라 곱, 선형결합)을 다루었다. 이제 §1.2는 기하학적 연산으로 들어간다.
두 벡터가 이루는 각도는 얼마인가? 벡터의 길이는 어떻게 측정하는가?
이 두 질문을 하나의 연산으로 포착하는 것이 내적(dot product)이다. 내적은 수치 계산과 기하학적 직관을 연결하는 가장 근본적인 도구이며, 머신러닝의 유사도 측정, 딥러닝의 어텐션 메커니즘, 통계학의 상관계수 모두가 내적 위에 세워진다 (Strang, 2009, §1.2).
2 내적 (Dot Product)
2.1 정의
\(n\) 차원 벡터 \(\mathbf{v} = (v_1, v_2, \ldots, v_n)^\top\) 와 \(\mathbf{w} = (w_1, w_2, \ldots, w_n)^\top\) 의 내적(dot product)은 스칼라:
\[\mathbf{v} \cdot \mathbf{w} = v_1 w_1 + v_2 w_2 + \cdots + v_n w_n = \sum_{i=1}^{n} v_i w_i\]
결과는 벡터가 아니라 실수(스칼라) 하나이다.
기호 약속:
- \(\mathbf{v} \cdot \mathbf{w}\) : 점(dot) 표기. 가장 일반적
- \(\langle \mathbf{v}, \mathbf{w} \rangle\) : 내적 공간 이론에서 사용하는 각괄호 표기
- \(\mathbf{v}^\top \mathbf{w}\) : 행렬 곱으로 표현한 내적 (행벡터 × 열벡터)
세 가지는 동일한 연산이다.
2.2 핵심 성질
| 성질 | 수식 | 직관 |
|---|---|---|
| 교환 법칙 | \(\mathbf{v} \cdot \mathbf{w} = \mathbf{w} \cdot \mathbf{v}\) | 성분별 곱셈의 순서가 무관함 |
| 선형성 | \((c\mathbf{v}) \cdot \mathbf{w} = c(\mathbf{v} \cdot \mathbf{w})\) | 스칼라는 빼낼 수 있다 |
| 분배 법칙 | \((\mathbf{u} + \mathbf{v}) \cdot \mathbf{w} = \mathbf{u} \cdot \mathbf{w} + \mathbf{v} \cdot \mathbf{w}\) | 덧셈에 대해 분배된다 |
| 양정치성 | \(\mathbf{v} \cdot \mathbf{v} \geq 0\), 등호는 \(\mathbf{v} = \mathbf{0}\) 일 때만 | 자기 자신과의 내적은 항상 0 이상 |
이 4가지 성질이 정확히 내적 공간(inner product space)의 공리이다. 즉, 임의의 내적을 정의할 때 반드시 이 성질을 만족해야 한다.
2.3 예시: 2차원
\[\mathbf{v} = \begin{bmatrix} 4 \\ 2 \end{bmatrix}, \quad \mathbf{w} = \begin{bmatrix} -1 \\ 2 \end{bmatrix}\]
\[\mathbf{v} \cdot \mathbf{w} = (4)(-1) + (2)(2) = -4 + 4 = 0\]
내적이 0이다 — 이것은 우연이 아니다. 두 벡터가 직각(90°)을 이룬다는 뜻이다. 직관적으로, 이 두 벡터를 그려보면 실제로 수직임을 확인할 수 있다.
2.4 예시: 3차원 경제 해석
가격 벡터 \(\mathbf{p} = (p_1, p_2, p_3)\) 와 판매량 벡터 \(\mathbf{q} = (q_1, q_2, q_3)\) 의 내적이 총 수입이다 (Strang, 2009, §1.2):
\[\mathbf{q} \cdot \mathbf{p} = q_1 p_1 + q_2 p_2 + q_3 p_3 = \text{총 수입}\]
\(\mathbf{q} \cdot \mathbf{p} = 0\) 이면 “장부가 균형(the books balance)”이다 — 총 판매 = 총 구입. 이때 \(\mathbf{p}\) 는 \(\mathbf{q}\) 에 직교한다. 내적이 0이 되는 것이 균형의 의미이다.
도트곱(dot product) \(\mathbf{v} \cdot \mathbf{w}\) 는 실 \(\mathbb{R}^n\) 에서 정의된 구체적 연산이다. 이를 일반화한 개념이 내적(inner product) \(\langle \mathbf{v}, \mathbf{w} \rangle\) 이다. 내적은 다음 공리를 만족하는 모든 이중선형 형식(bilinear form)을 가리킨다:
- 첫 번째 인수에 대한 선형성: \(\langle c\mathbf{x} + d\mathbf{y}, \mathbf{z} \rangle = c\langle \mathbf{x}, \mathbf{z}\rangle + d\langle \mathbf{y}, \mathbf{z}\rangle\)
- 켤레 대칭성: \(\langle \mathbf{v}, \mathbf{w} \rangle = \overline{\langle \mathbf{w}, \mathbf{v} \rangle}\) (실수 공간에서는 단순 대칭)
- 양정치성: \(\langle \mathbf{v}, \mathbf{v} \rangle \geq 0\), 등호는 \(\mathbf{v} = \mathbf{0}\) 일 때만
복소 벡터 공간에서는 두 번째 인수에 대해 켤레 선형성을 요구한다 \(\langle \mathbf{v}, c\mathbf{w} \rangle = \bar{c}\langle \mathbf{v}, \mathbf{w}\rangle\). 이 조건이 \(\|\mathbf{v}\|^2 = \langle \mathbf{v}, \mathbf{v}\rangle\) 을 실수로 유지한다. 복소 내적의 정식 정의는 Ch.10 에르미트 행렬에서 다룬다.
3 벡터의 길이 (Norm)
3.1 정의
벡터 \(\mathbf{v}\) 의 길이(length) 또는 L2 노름(norm):
\[\|\mathbf{v}\| = \sqrt{\mathbf{v} \cdot \mathbf{v}} = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}\]
\(\|\mathbf{v}\|^2 = \mathbf{v} \cdot \mathbf{v}\) 는 길이의 제곱이다.
3.2 왜 \(\sqrt{\mathbf{v} \cdot \mathbf{v}}\) 인가 — 피타고라스 정리의 확장
2차원에서 벡터 \(\mathbf{v} = (v_1, v_2)\) 는 직각삼각형의 빗변이다. 피타고라스 정리 \(a^2 + b^2 = c^2\) 에 의해:
\[\|\mathbf{v}\|^2 = v_1^2 + v_2^2\]
3차원으로 가면 두 번 적용한다. \((v_1, v_2, 0)\) 의 길이가 \(\sqrt{v_1^2 + v_2^2}\) 이고, 이것과 수직인 \((0, 0, v_3)\) 를 더하면:
\[\|\mathbf{v}\|^2 = \left(\sqrt{v_1^2 + v_2^2}\right)^2 + v_3^2 = v_1^2 + v_2^2 + v_3^2\]
\(n\) 차원에서도 이 패턴이 반복된다. 피타고라스 정리가 \(n\) 차원으로 자연스럽게 확장된다.
3.3 예시: 3차원
\[\mathbf{v} = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}, \quad \|\mathbf{v}\|^2 = 1 + 4 + 9 = 14, \quad \|\mathbf{v}\| = \sqrt{14}\]
3.4 \(n\) 차원 단위 큐브의 대각선
\(n\) 차원 벡터 \((1, 1, \ldots, 1)\) 의 길이:
\[\|(1, 1, \ldots, 1)\| = \sqrt{1^2 + 1^2 + \cdots + 1^2} = \sqrt{n}\]
so what: 차원이 높아질수록 “대각선”이 훨씬 길어진다. 10차원 단위 큐브의 대각선 길이는 \(\sqrt{10} \approx 3.16\) 이다. 고차원 공간의 기하학이 2D·3D 직관과 달라지는 이유 중 하나이다.
4 단위벡터 (Unit Vector)
길이가 정확히 1인 벡터를 단위벡터(unit vector)라 한다:
\[\|\mathbf{u}\| = 1 \quad \Longleftrightarrow \quad \mathbf{u} \cdot \mathbf{u} = 1\]
임의의 비영벡터 \(\mathbf{v}\) 를 그 길이로 나누면 단위벡터를 얻는다:
\[\mathbf{u} = \frac{\mathbf{v}}{\|\mathbf{v}\|}\]
이것을 벡터의 정규화(normalization)라 한다.
정규화는 방향만 보존하고 크기 정보는 제거한다. \(\mathbf{u}\) 는 \(\mathbf{v}\) 와 방향이 같지만 길이는 1이다.
4.1 표준 단위벡터 (Standard Basis Vectors)
2차원의 표준 단위벡터:
\[\mathbf{e}_1 = \begin{bmatrix} 1 \\ 0 \end{bmatrix}, \quad \mathbf{e}_2 = \begin{bmatrix} 0 \\ 1 \end{bmatrix}\]
이들은 \(x\) 축, \(y\) 축 방향의 단위벡터이다. 고전적으로 \(\mathbf{i}\), \(\mathbf{j}\) (공학) 또는 \(\hat{x}\), \(\hat{y}\) (물리학)로도 쓴다.
4.2 단위원과 코사인-사인
2차원에서 각도 \(\theta\) 를 이루는 단위벡터:
\[\mathbf{u}(\theta) = \begin{bmatrix} \cos\theta \\ \sin\theta \end{bmatrix}\]
\(\|\mathbf{u}(\theta)\|^2 = \cos^2\theta + \sin^2\theta = 1\) 이므로 단위벡터가 맞다. 이 벡터들의 끝점이 단위원(unit circle) 위에 놓인다.
so what: \(\cos\theta\) 와 \(\sin\theta\) 는 단위원 위의 점 좌표이다. 각도가 이렇게 기하학적 의미를 갖는다.
4.3 예시: 정규화
\[\mathbf{v} = \begin{bmatrix} 3 \\ 4 \end{bmatrix}, \quad \|\mathbf{v}\| = \sqrt{9 + 16} = 5, \quad \mathbf{u} = \frac{\mathbf{v}}{5} = \begin{bmatrix} 3/5 \\ 4/5 \end{bmatrix}\]
검증: \(\|\mathbf{u}\|^2 = (3/5)^2 + (4/5)^2 = 9/25 + 16/25 = 1\) ✓
4차원 예시:
\[\mathbf{v} = (1, 1, 1, 1), \quad \|\mathbf{v}\| = 2, \quad \mathbf{u} = \left(\frac{1}{2}, \frac{1}{2}, \frac{1}{2}, \frac{1}{2}\right)\]
5 두 벡터의 각도 — 코사인 공식
5.1 직각의 조건
두 벡터 \(\mathbf{v}\) 와 \(\mathbf{w}\) 가 직교(perpendicular, orthogonal)한다는 것은 내적이 0인 것과 동치이다:
\[\mathbf{v} \perp \mathbf{w} \quad \Longleftrightarrow \quad \mathbf{v} \cdot \mathbf{w} = 0\]
증명 (피타고라스 역방향):
\(\mathbf{v}\) 와 \(\mathbf{w}\) 가 직각을 이룰 때, 빗변은 \(\mathbf{v} - \mathbf{w}\) 이다. 피타고라스 정리에 의해:
\[\|\mathbf{v}\|^2 + \|\mathbf{w}\|^2 = \|\mathbf{v} - \mathbf{w}\|^2\]
우변을 전개하면:
\[\|\mathbf{v} - \mathbf{w}\|^2 = \|\mathbf{v}\|^2 - 2\mathbf{v} \cdot \mathbf{w} + \|\mathbf{w}\|^2\]
대입하면 \(-2\mathbf{v} \cdot \mathbf{w} = 0\), 즉 \(\mathbf{v} \cdot \mathbf{w} = 0\). \(\square\)
직관: 내적의 부호가 각도의 예비 정보를 준다.
| \(\mathbf{v} \cdot \mathbf{w}\) 의 부호 | 각도 범위 | 의미 |
|---|---|---|
| 양수 \((> 0)\) | $< 90° $ | 같은 방향에 가깝다 |
| 0 | $= 90° $ | 직교 |
| 음수 \((< 0)\) | $> 90° $ | 반대 방향에 가깝다 |
5.2 코사인 공식 (Cosine Formula)
단위벡터 \(\mathbf{u} = \mathbf{v}/\|\mathbf{v}\|\), \(\mathbf{U} = \mathbf{w}/\|\mathbf{w}\|\) 의 내적이 두 벡터의 사잇각 코사인이다:
\[\mathbf{u} \cdot \mathbf{U} = \cos\theta\]
임의의 비영벡터 \(\mathbf{v}\), \(\mathbf{w}\) 에 대해 정규화하면:
\[\cos\theta = \frac{\mathbf{v} \cdot \mathbf{w}}{\|\mathbf{v}\| \|\mathbf{w}\|}\]
여기서 \(\theta\) 는 두 벡터의 사잇각 \((0 \leq \theta \leq \pi)\) 이다.
유도: 2차원에서 \(\mathbf{u} = (\cos\alpha, \sin\alpha)\), \(\mathbf{U} = (\cos\beta, \sin\beta)\) 로 쓰면:
\[\mathbf{u} \cdot \mathbf{U} = \cos\alpha \cos\beta + \sin\alpha \sin\beta = \cos(\beta - \alpha) = \cos\theta\]
삼각함수 덧셈공식이 코사인 공식의 핵심이다. 이 결과는 \(n\) 차원에서도 그대로 성립한다 (Strang, 2009, §1.2).
제2 코사인 법칙 \(\cos\theta = \frac{\|\mathbf{v}\|^2 + \|\mathbf{w}\|^2 - \|\mathbf{v} - \mathbf{w}\|^2}{2\|\mathbf{v}\|\|\mathbf{w}\|}\) 의 분자를 내적으로 전개해도 같은 공식에 도달한다. \(\|\mathbf{v}\|^2 = \mathbf{v} \cdot \mathbf{v}\) 를 이용하면:
\[ \begin{aligned} \|\mathbf{v}\|^2 + \|\mathbf{w}\|^2 - \|\mathbf{v} - \mathbf{w}\|^2 &= \mathbf{v}\cdot\mathbf{v} + \mathbf{w}\cdot\mathbf{w} - (\mathbf{v} - \mathbf{w})\cdot(\mathbf{v} - \mathbf{w}) \\ &= \mathbf{v}\cdot\mathbf{v} + \mathbf{w}\cdot\mathbf{w} - \mathbf{v}\cdot\mathbf{v} + 2\mathbf{v}\cdot\mathbf{w} - \mathbf{w}\cdot\mathbf{w} \\ &= 2\mathbf{v}\cdot\mathbf{w} \end{aligned} \]
따라서 \(\cos\theta = \dfrac{\mathbf{v}\cdot\mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}\). 이 유도는 \(n\) 차원에서 삼각함수 없이 내적 공리만으로 코사인 공식을 얻는다는 점이 장점이다. 기하학적 의미: “제곱 길이의 차이”가 내적의 2배이다.
so what: 내적 하나로 각도를 계산할 수 있다. 각도를 삼각함수로 직접 계산할 필요가 없다. 이것이 내적이 기하학의 핵심 도구인 이유이다.
5.3 예시: 각도 계산
\[\mathbf{v} = \begin{bmatrix} 2 \\ 1 \end{bmatrix}, \quad \mathbf{w} = \begin{bmatrix} 1 \\ 2 \end{bmatrix}\]
\[\mathbf{v} \cdot \mathbf{w} = 2 \cdot 1 + 1 \cdot 2 = 4, \quad \|\mathbf{v}\| = \|\mathbf{w}\| = \sqrt{5}\]
\[\cos\theta = \frac{4}{\sqrt{5} \cdot \sqrt{5}} = \frac{4}{5}, \quad \theta = \arccos\left(\frac{4}{5}\right) \approx 36.9° \]
내적이 양수이므로 $90° $ 미만임을 미리 알 수 있다. 계산 결과 약 $37° $ 로 확인된다.
6 슈바르츠 부등식과 삼각 부등식
6.1 슈바르츠 부등식 (Schwarz Inequality)
코사인은 \([-1, 1]\) 범위를 벗어날 수 없다. 코사인 공식 \(\cos\theta = \frac{\mathbf{v} \cdot \mathbf{w}}{\|\mathbf{v}\| \|\mathbf{w}\|}\) 에서:
모든 벡터 \(\mathbf{v}\), \(\mathbf{w} \in \mathbb{R}^n\) 에 대해:
\[|\mathbf{v} \cdot \mathbf{w}| \leq \|\mathbf{v}\| \|\mathbf{w}\|\]
등호 조건: \(\mathbf{w} = c\mathbf{v}\) (두 벡터가 평행)
이 부등식은 Cauchy-Schwarz-Bunyakovsky 부등식이라고도 하며, 수학에서 가장 중요한 부등식 중 하나이다. 프랑스, 독일, 러시아에서 독립적으로 발견되었다 (Strang, 2009, §1.2).
등호 조건의 의미: 내적이 최대값 \(\|\mathbf{v}\| \|\mathbf{w}\|\) 에 도달하는 것은 두 벡터의 방향이 완전히 같을 때 ( $= 0° $ ) 이고, 최솟값 \(-\|\mathbf{v}\| \|\mathbf{w}\|\) 에 도달하는 것은 정반대 방향일 때 ( $= 180° $ )이다.
유용한 특수 케이스: \(\mathbf{v} = (a, b)\), \(\mathbf{w} = (b, a)\) 로 놓으면:
\[\mathbf{v} \cdot \mathbf{w} = 2ab, \quad \|\mathbf{v}\| = \|\mathbf{w}\| = \sqrt{a^2 + b^2}\]
슈바르츠 부등식을 적용하면 \(2ab \leq a^2 + b^2\), 즉:
\[\sqrt{xy} \leq \frac{x + y}{2} \quad (x = a^2, y = b^2)\]
이것이 기하-산술 평균 부등식(AM-GM inequality)이다.
6.2 삼각 부등식 (Triangle Inequality)
모든 벡터 \(\mathbf{v}\), \(\mathbf{w} \in \mathbb{R}^n\) 에 대해:
\[\|\mathbf{v} + \mathbf{w}\| \leq \|\mathbf{v}\| + \|\mathbf{w}\|\]
등호 조건: \(\mathbf{w} = c\mathbf{v}\), \(c \geq 0\) (같은 방향)
증명: 슈바르츠 부등식에서 유도한다.
\[\|\mathbf{v} + \mathbf{w}\|^2 = \|\mathbf{v}\|^2 + 2\mathbf{v} \cdot \mathbf{w} + \|\mathbf{w}\|^2 \leq \|\mathbf{v}\|^2 + 2\|\mathbf{v}\|\|\mathbf{w}\| + \|\mathbf{w}\|^2 = (\|\mathbf{v}\| + \|\mathbf{w}\|)^2\]
양변에 제곱근을 취하면 삼각 부등식이다. \(\square\)
기하학적 의미: 삼각형의 한 변의 길이는 나머지 두 변의 합보다 작거나 같다. 직선을 따라 이동하는 것이 꺾어서 가는 것보다 짧다.
예시 (\(\mathbf{v} = (3, 4)\), \(\mathbf{w} = (4, 3)\)):
\[\mathbf{v} \cdot \mathbf{w} = 24, \quad \|\mathbf{v}\| = \|\mathbf{w}\| = 5\]
- 슈바르츠: \(|24| \leq 5 \times 5 = 25\) ✓
- \(\mathbf{v} + \mathbf{w} = (7, 7)\), \(\|\mathbf{v} + \mathbf{w}\| = 7\sqrt{2} \approx 9.9\)
- 삼각: \(7\sqrt{2} \leq 5 + 5 = 10\) ✓
7 왜 필요한가
내적과 길이는 선형대수 전체의 기하학적 뼈대이다.
직교성(orthogonality)의 언어: 이후 Ch.4(직교성), Ch.4.3(최소제곱법), Ch.4.4(Gram-Schmidt)는 모두 내적이 0인 것의 의미 위에 세워진다. 직교 보공간(orthogonal complement), 직교 투영(orthogonal projection)이 모두 여기서 시작된다.
거리의 언어: 두 벡터 \(\mathbf{v}\), \(\mathbf{w}\) 의 거리는 \(\|\mathbf{v} - \mathbf{w}\|\) 이다. 이 거리 개념이 최소제곱법(“가장 가까운 해”)의 기반이다.
각도의 언어: 코사인 유사도는 내적을 길이로 정규화한 것이다. 벡터의 방향적 유사성을 측정한다.
이 세 언어 없이는 Ch.4의 “직교 투영”도, Ch.6의 “대칭 행렬의 직교 고유벡터”도 이해할 수 없다.
8 응용 분야
| 분야 | 활용 | 구체적 예시 |
|---|---|---|
| 머신러닝 | 유사도 측정 | 코사인 유사도 \(= \frac{\mathbf{v} \cdot \mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}\) |
| 딥러닝 | Attention 메커니즘 | Query-Key 내적으로 관련도 계산 |
| 통계학 | 상관계수 | Pearson 상관계수 = 표준화된 벡터의 내적 |
| 통계학 | 최소제곱법 | 잔차 벡터와 열공간의 직교 조건 \(\mathbf{A}^\top (\mathbf{b} - \mathbf{A}\hat{\mathbf{x}}) = \mathbf{0}\) |
| 신호처리 | 주파수 분석 | 푸리에 계수 = 신호와 기저함수의 내적 |
| 정보 검색 | 문서 유사도 | TF-IDF 벡터의 코사인 유사도 |
| 컴퓨터 그래픽스 | 조명 계산 | 법선벡터와 광원 방향의 내적 (Lambert’s law) |
9 예시
9.1 예시 1: 직교 여부 판단
\(\mathbf{v} = (1, 2, -1)\), \(\mathbf{w} = (3, 0, 3)\) 이 직교하는지 확인한다:
\[\mathbf{v} \cdot \mathbf{w} = 1 \cdot 3 + 2 \cdot 0 + (-1) \cdot 3 = 3 + 0 - 3 = 0\]
내적이 0이므로 직교한다.
9.2 예시 2: 단위벡터 구성
\(\mathbf{v} = (2, 2, 1)\) 의 단위벡터:
\[\|\mathbf{v}\| = \sqrt{4 + 4 + 1} = 3, \quad \mathbf{u} = \frac{1}{3}(2, 2, 1) = \left(\frac{2}{3}, \frac{2}{3}, \frac{1}{3}\right)\]
검증: \(\|\mathbf{u}\|^2 = \frac{4}{9} + \frac{4}{9} + \frac{1}{9} = 1\) ✓
9.3 예시 3: 코사인 공식 완전 계산
\(\mathbf{v} = (3, 4)\), \(\mathbf{w} = (4, 3)\) 의 사잇각:
\[\mathbf{v} \cdot \mathbf{w} = 12 + 12 = 24, \quad \|\mathbf{v}\| = \|\mathbf{w}\| = 5\]
\[\cos\theta = \frac{24}{25}, \quad \theta = \arccos(0.96) \approx 16.3° \]
두 벡터가 거의 같은 방향이므로 각도가 작다 — 직관과 일치한다.
9.4 예시 4: 수직인 단위벡터 찾기
\(\mathbf{v} = (3, 4)\) 에 수직인 단위벡터를 찾는다.
수직 벡터 후보: \(\mathbf{V} = (-4, 3)\) (x성분과 y성분을 뒤집고 하나의 부호를 바꿈)
확인: \(\mathbf{v} \cdot \mathbf{V} = 3(-4) + 4(3) = -12 + 12 = 0\) ✓
정규화: \(\|\mathbf{V}\| = \sqrt{16 + 9} = 5\), 단위벡터 \(\mathbf{U} = \left(-\frac{4}{5}, \frac{3}{5}\right)\)
10 코드 예시
10.1 Step 1: Low-level 구현 (원리 이해)
import math
from typing import Union
Vector = list[float]
def dot_product(v: Vector, w: Vector) -> float:
"""내적: 대응 성분끼리 곱해 모두 합산한다"""
assert len(v) == len(w), "차원이 같아야 한다"
return sum(vi * wi for vi, wi in zip(v, w))
def norm(v: Vector) -> float:
"""L2 노름: 성분 제곱합의 제곱근"""
return math.sqrt(dot_product(v, v))
def normalize(v: Vector) -> Vector:
"""단위벡터: 벡터를 길이로 나눈다"""
n = norm(v)
assert n > 0, "영벡터는 정규화할 수 없다"
return [vi / n for vi in v]
def cosine_angle(v: Vector, w: Vector) -> tuple[float, float]:
"""코사인 공식: cos(θ)와 θ(도)를 반환한다"""
cos_theta = dot_product(v, w) / (norm(v) * norm(w))
# 부동소수점 오차로 [-1, 1] 범위를 벗어날 수 있으므로 클리핑
cos_theta = max(-1.0, min(1.0, cos_theta))
theta_deg = math.degrees(math.acos(cos_theta))
return cos_theta, theta_deg
def is_orthogonal(v: Vector, w: Vector, tol: float = 1e-9) -> bool:
"""직교 판별: 내적이 0이면 직교한다"""
return abs(dot_product(v, w)) < tol
# --- 예시 실행 ---
v = [3.0, 4.0]
w = [4.0, 3.0]
perp = [-4.0, 3.0]
print("=== 내적 ===")
print(f"v·w = {dot_product(v, w)}") # 24.0
print(f"v·perp = {dot_product(v, perp)}") # 0.0
print("\n=== 길이 ===")
print(f"‖v‖ = {norm(v)}") # 5.0
print(f"‖w‖ = {norm(w)}") # 5.0
print("\n=== 단위벡터 ===")
u = normalize(v)
print(f"u = {u}") # [0.6, 0.8]
print(f"‖u‖ = {norm(u):.6f}") # 1.000000
print("\n=== 사잇각 ===")
cos_theta, theta = cosine_angle(v, w)
print(f"cos(θ) = {cos_theta:.4f}") # 0.9600
print(f"θ ≈ {theta:.2f}°") # 16.26°
print("\n=== 직교 판별 ===")
print(f"v ⊥ perp: {is_orthogonal(v, perp)}") # True
print(f"v ⊥ w: {is_orthogonal(v, w)}") # False
# 슈바르츠 부등식 검증
dp = abs(dot_product(v, w))
product_of_norms = norm(v) * norm(w)
print(f"\n=== 슈바르츠 부등식 ===")
print(f"|v·w| = {dp}, ‖v‖·‖w‖ = {product_of_norms}")
print(f"부등식 성립: {dp <= product_of_norms}") # True10.2 Step 2: NumPy 구현 (실무 활용)
import numpy as np
import matplotlib.pyplot as plt
# --- 기본 연산 ---
v = np.array([3.0, 4.0])
w = np.array([4.0, 3.0])
dot = np.dot(v, w) # 내적: 24.0
norm_v = np.linalg.norm(v) # L2 노름: 5.0
norm_w = np.linalg.norm(w)
cos_theta = dot / (norm_v * norm_w)
theta_deg = np.degrees(np.arccos(np.clip(cos_theta, -1, 1)))
print(f"내적: {dot}")
print(f"‖v‖ = {norm_v}, ‖w‖ = {norm_w}")
print(f"cos(θ) = {cos_theta:.4f}, θ = {theta_deg:.2f}°")
# 단위벡터
u = v / norm_v
print(f"단위벡터 u = {u}, ‖u‖ = {np.linalg.norm(u):.6f}")
# --- 코사인 유사도 행렬 ---
# ML에서 자주 쓰는 패턴: 벡터 집합 사이의 유사도 행렬
vectors = np.array([
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
])
# 각 벡터를 정규화 (L2 norm = 1로)
norms = np.linalg.norm(vectors, axis=1, keepdims=True)
normalized = vectors / norms
# 코사인 유사도 행렬: (i, j) 원소 = 벡터 i와 j의 cos(θ)
cosine_sim = normalized @ normalized.T # (4, 4) 행렬
print("\n=== 코사인 유사도 행렬 ===")
np.set_printoptions(precision=3, suppress=True)
print(cosine_sim)
# 대각 원소: 자기 자신과의 유사도 = 1 (단위벡터이므로)
# (0, 2) 원소: (1,0,0)과 (0,0,1)은 직교 → 0
# --- 단위원과 벡터 시각화 ---
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 왼쪽: 두 벡터와 사잇각
ax = axes[0]
origin = np.zeros(2)
for vec, color, label in [(v, 'royalblue', r'$\mathbf{v}=(3,4)$'),
(w, 'coral', r'$\mathbf{w}=(4,3)$')]:
ax.annotate('', xy=vec, xytext=origin,
arrowprops=dict(arrowstyle='->', color=color, lw=2))
ax.text(vec[0] * 1.05, vec[1] * 1.05, label, fontsize=11, color=color)
# 호(arc)로 각도 표시
theta_rad = np.linspace(0, np.radians(theta_deg), 60)
arc_r = 1.5
ax.plot(arc_r * np.cos(theta_rad), arc_r * np.sin(theta_rad), 'k-', lw=1)
ax.text(arc_r * 0.6, arc_r * 0.2, f'θ≈{theta_deg:.1f}°', fontsize=10)
ax.set_xlim(-0.5, 5.5); ax.set_ylim(-0.5, 4.5)
ax.axhline(0, color='k', lw=0.5); ax.axvline(0, color='k', lw=0.5)
ax.set_aspect('equal'); ax.set_title('두 벡터의 사잇각')
ax.grid(True, alpha=0.3)
# 오른쪽: 단위원과 코사인-사인
ax2 = axes[1]
angles = np.linspace(0, 2 * np.pi, 300)
ax2.plot(np.cos(angles), np.sin(angles), 'k-', lw=1, label='단위원')
# 몇 가지 각도의 단위벡터
for deg, color in [(0, 'red'), (45, 'green'), (90, 'blue'), (135, 'purple'), (180, 'orange')]:
rad = np.radians(deg)
u_vec = np.array([np.cos(rad), np.sin(rad)])
ax2.annotate('', xy=u_vec, xytext=np.zeros(2),
arrowprops=dict(arrowstyle='->', color=color, lw=1.5))
ax2.text(u_vec[0] * 1.15, u_vec[1] * 1.15, f'{deg}°', fontsize=9, color=color, ha='center')
ax2.set_xlim(-1.5, 1.5); ax2.set_ylim(-1.5, 1.5)
ax2.set_aspect('equal')
ax2.axhline(0, color='k', lw=0.5); ax2.axvline(0, color='k', lw=0.5)
ax2.set_title(r'단위원: $\mathbf{u}=(\cos\theta, \sin\theta)$')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()10.3 Step 3: 슈바르츠 부등식과 코사인 유사도 실무 응용
import numpy as np
# --- 슈바르츠 부등식 확인 ---
def schwarz_check(v: np.ndarray, w: np.ndarray) -> dict:
"""슈바르츠 부등식 |v·w| ≤ ‖v‖·‖w‖ 를 수치로 확인한다"""
lhs = abs(np.dot(v, w))
rhs = np.linalg.norm(v) * np.linalg.norm(w)
return {
"|v·w|": lhs,
"‖v‖·‖w‖": rhs,
"성립": lhs <= rhs + 1e-12,
"비율(= |cos θ|)": lhs / rhs if rhs > 0 else float('nan'),
}
# 등호 조건: w = c*v (평행)
v = np.array([1.0, 2.0, 3.0])
w_parallel = 2.5 * v # 평행 → 등호
w_random = np.array([4.0, -1.0, 2.0])
print("=== 평행 벡터 (등호 조건) ===")
result = schwarz_check(v, w_parallel)
for k, val in result.items():
print(f" {k}: {val:.6f}" if isinstance(val, float) else f" {k}: {val}")
print("\n=== 일반 벡터 ===")
result = schwarz_check(v, w_random)
for k, val in result.items():
print(f" {k}: {val:.6f}" if isinstance(val, float) else f" {k}: {val}")
# --- 코사인 유사도로 문서 유사도 계산 ---
# 단어 빈도 벡터 예시 (bag-of-words)
# 단어: ['data', 'science', 'machine', 'learning', 'python']
doc1 = np.array([2, 1, 3, 2, 1], dtype=float) # 데이터 과학 문서
doc2 = np.array([1, 0, 4, 3, 2], dtype=float) # 머신러닝 문서
doc3 = np.array([0, 3, 0, 0, 0], dtype=float) # science 전문 문서
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
"""두 벡터의 코사인 유사도 (정규화된 내적)"""
denom = np.linalg.norm(a) * np.linalg.norm(b)
if denom == 0:
return 0.0
return np.dot(a, b) / denom
print("\n=== 문서 유사도 (코사인 유사도) ===")
print(f"doc1-doc2: {cosine_similarity(doc1, doc2):.4f}") # 유사한 분야
print(f"doc1-doc3: {cosine_similarity(doc1, doc3):.4f}") # 다소 다른 분야
print(f"doc2-doc3: {cosine_similarity(doc2, doc3):.4f}") # 매우 다른 분야11 핵심 요약
§1.2의 세 가지 핵심 개념:
| 개념 | 정의 | 핵심 공식 | 의미 |
|---|---|---|---|
| 내적 | \(\mathbf{v} \cdot \mathbf{w} = \sum v_i w_i\) | 결과는 스칼라 | 두 벡터의 “정렬도” 측정 |
| 길이 | \(\|\mathbf{v}\| = \sqrt{\mathbf{v} \cdot \mathbf{v}}\) | 피타고라스의 \(n\) 차원 확장 | 크기 측정 |
| 단위벡터 | \(\mathbf{u} = \mathbf{v}/\|\mathbf{v}\|\) | \(\|\mathbf{u}\| = 1\) | 방향만 보존 |
| 코사인 공식 | \(\cos\theta = \frac{\mathbf{v} \cdot \mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}\) | \([-1, 1]\) 범위 | 각도를 내적으로 계산 |
| 슈바르츠 부등식 | \(|\mathbf{v} \cdot \mathbf{w}| \leq \|\mathbf{v}\|\|\mathbf{w}\|\) | 등호: 평행 벡터 | 코사인 공식의 기반 |
연결고리: 슈바르츠 부등식 → 코사인 공식 → 직교 조건 → Ch.4 직교성 → 최소제곱법.
12 관련 주제
선행 지식
후속 주제
- Lecture 1 — 선형 방정식의 기하학적 해석 — Row/Column Picture와 \(Ax = b\)
- Lecture 14 — 직교 벡터와 부분공간 — 내적의 심화
- Lecture 15 — 투영과 최소자승법 — 직교 투영
다른 카테고리 연결
- Gram-Schmidt — 직교정규화 — 내적으로 직교기저 구성