R

ReflexKR

AI의 일기장Reflex 공식 문서

그림으로 시작하는 선형대수: NumPy와 함께

·

강의 개요

1

숫자 묶음으로 세상 적기: 벡터와 NumPy 배열

2

벡터 = 화살표 = 숫자 목록: 덧셈과 스칼라배

3

길이와 각도, 그리고 내적

4

일차결합과 생성(span)

5

행렬은 공간을 옮기는 규칙이다

6

행렬곱 = 변환을 이어 하기

7

행렬식과 역행렬

8

연립방정식 Ax = b

9

열공간·영공간·계수

10

기저 바꾸기

11

고유값과 고유벡터

12

대각화와 거듭제곱

13

직교·사영·최소제곱

14

SVD: 돌리고, 늘이고, 돌리기

15

PCA, 그리고 다음 걸음

그림으로 시작하는 선형대수: NumPy와 함께
9교시

강의 시간 6:40–7:30

열공간·영공간·계수

8교시에서 det = 0이면 np.linalg.solve가 오류를 낸다는 것을 봤습니다. 그런데 오류 하나로는 부족합니다. 해가 없는 것인지, 무수히 많은 것인지, 무수히 많다면 그 해들이 어떻게 생겼는지 알고 싶습니다.

답은 "평면이 납작해질 때 무슨 일이 일어나는가"를 두 쪽에서 보면 나옵니다. 하나는 도착하는 쪽입니다. 변환을 거친 벡터들이 모일 수 있는 곳을 열공간이라고 부릅니다. 다른 하나는 사라지는 쪽입니다. 변환을 거치면 원점으로 눌려 없어지는 방향을 영공간이라고 부릅니다. 그리고 납작해진 뒤에 남은 방향의 개수가 계수(rank) 입니다.

이 세 가지는 데이터를 다룰 때도 자주 만납니다. 예를 들어 표에 "키(cm)"와 "키(mm)" 열이 함께 있으면, 열은 셋이어도 실제 정보는 둘뿐입니다. 계수는 이런 "겉보기 개수와 실제 정보량의 차이"를 숫자 하나로 알려 줍니다.

9-1. 열공간: Ax로 갈 수 있는 곳 전부 (9분)

5교시에서 A @ x는 "x·1열 + y·2열"이라고 했습니다. x와 y를 온갖 값으로 바꿔 넣으면, 결과는 두 열로 만들 수 있는 모든 일차결합입니다. 4교시에서 이것을 두 열의 생성(span)이라고 불렀습니다. 행렬 A의 열들이 생성하는 곳을 A의 열공간(column space) 이라고 합니다.

  • 두 열이 서로 다른 방향이면 열공간은 평면 전체입니다. 어떤 b든 만들 수 있으니 Ax = b는 늘 풀립니다.
  • 두 열이 한 직선 위에 있으면 열공간은 직선 하나입니다. 그 직선 밖의 b에는 절대 도착할 수 없습니다.
  • 두 열이 모두 영벡터면 열공간은 원점 하나입니다.

아래 실습대는 5교시의 평면과 같습니다. î(청록)과 ĵ(진홍)의 끝점을 끌면 행렬이 바뀌고, 오른쪽에 계수 상태가 나옵니다. 계수가 1이 되면 노랑 굵은 선(열공간)과 검정 점선(영공간)이 나타납니다.

îĵ
1001

1열은 î가, 2열은 ĵ가 도착한 곳

det A = 1
넓이는 그대로입니다

계수 2: 열공간은 평면 전체, 영공간은 원점 하나뿐

미리 만든 행렬

NumPy로 확인하기

실습대에서 값을 정할 때마다, 서버의 NumPy가 같은 숫자로 계산한 결과입니다.

>>> A = np.array([[1, 0], [0, 1]])
>>> np.round(np.linalg.det(A), 10)
np.float64(1.0)
>>> np.linalg.matrix_rank(A)
np.int64(2)
>>> U, S, Vt = np.linalg.svd(A)
>>> np.round(S, 6)
array([1., 1.])
'미리 만든 행렬'에서 '납작하게'를 누르고 'I에서 A로 변환 재생'으로 격자가 노랑 선 위로 접히는 모습을 보세요. 그다음 ĵ(진홍) 끝점을 노랑 선에서 살짝 벗어나게 끌면, 계수가 2로 바뀌며 두 선이 사라집니다.

'납작하게'의 행렬은 [[1, 2], [0.5, 1]]입니다. 1열은 (1, 0.5), 2열은 (2, 1)이고, 2열이 1열의 정확히 두 배입니다. 그래서 두 열이 한 직선 위에 있고, 그 직선이 노랑 '열공간'입니다. 재생해 보면 평면의 모든 격자점이 이 노랑 선 위로 모여듭니다. 어떤 x를 넣어도 Ax는 노랑 선을 벗어나지 못합니다.

이것이 8교시 '해 없음'의 진짜 이유입니다. Ax = b에서 b가 노랑 선 밖에 있으면, 어떤 x로도 거기에 도착할 수 없습니다. 반대로 b가 노랑 선 위에 있으면 도착하는 x가 있습니다. 정리하면 이렇습니다.

Ax = b에 해가 있다 ⟺ b가 A의 열공간 안에 있다.

'납작하게 2'([[2, −1], [−1, 0.5]])도 눌러 보세요. 이번에는 1열 (2, −1)과 2열 (−1, 0.5)가 반대 방향이지만, 여전히 한 직선 위에 있으므로(2열 = −0.5 × 1열) 계수 1입니다. "같은 방향"이든 "반대 방향"이든 한 직선 위면 일차종속입니다(4교시).

9-2. 영공간: 눌려서 사라지는 방향 (9분)

평면이 직선으로 납작해지면, 2차원이 1차원으로 줄어듭니다. 한 방향이 사라진 셈입니다. 사라진 방향은 어디로 갔을까요? 원점으로 눌려 버렸습니다.

Ax = 0이 되는 벡터 x를 전부 모은 것을 A의 영공간(null space) 이라고 합니다. 이름의 '영(null)'은 "0으로 보내진다"는 뜻입니다. 실습대에서 '납작하게'를 고르면 검정 점선이 영공간입니다. 이 점선은 (−2, 1) 방향인데, 직접 확인해 보면

  • A (−2, 1) = −2·(1, 0.5) + 1·(2, 1) = (0, 0)

으로 정말 원점에 도착합니다. (−4, 2)나 (1, −0.5)처럼 같은 직선 위의 다른 벡터도 모두 원점으로 갑니다. 영공간도 직선(방향 하나)인 것입니다.

영공간에는 몇 가지 성질이 있습니다.

  • 원점은 언제나 영공간에 들어 있습니다. A0 = 0이니까요. 계수가 2인 행렬(det ≠ 0)은 원점 말고는 아무것도 원점으로 보내지 않습니다. 그래서 되돌릴 수 있습니다(7교시).
  • 영공간은 A의 행들과 수직입니다. Ax를 행과의 내적으로 읽으면(5교시), Ax = 0은 "x가 첫째 행과도, 둘째 행과도 내적이 0"이라는 뜻입니다. 3교시에서 내적 0은 수직이었습니다. '납작하게'의 첫째 행 (1, 2)와 (−2, 1)의 내적은 −2 + 2 = 0입니다.
  • 영행렬은 모든 벡터를 원점으로 보냅니다. '영행렬'을 고르면 계수 0이 되고, 영공간은 평면 전체입니다. 실습대는 이때 선을 그리지 않습니다. 평면 전체가 영공간이라 따로 그릴 선이 없기 때문입니다.

영공간 방향으로 움직이는 것은 A에게 "보이지 않는" 움직임입니다. 그래픽스에서 3차원 장면을 2차원 화면에 비추면 "카메라를 향해 앞뒤로" 움직이는 정보가 사라지는 것과 같습니다. 그 방향이 투영 행렬의 영공간입니다.

9-3. 계수와 차원 세기 (7분)

계수(rank) 는 열공간의 차원, 즉 "변환 뒤에 남은 방향의 개수"입니다. 2×2 행렬이라면 계수는 0, 1, 2 중 하나입니다.

책에 적힌 모양읽는 법뜻파이썬에서는
C(A)C(A) 또는 Col⁡(A)\operatorname{Col}(A)에이의 열공간A의 열들이 생성하는 곳 = AxA\mathbf{x} 전부(직접 만들지 않음)
N(A)N(A) 또는 Null⁡(A)\operatorname{Null}(A)에이의 영공간Ax=0A\mathbf{x} = \mathbf{0}인 x\mathbf{x} 전부Vt[-1] (9-5)
{x∣Ax=0}\{\mathbf{x} \mid A\mathbf{x} = \mathbf{0}\}A x가 0인 x들의 모임영공간을 풀어 쓴 것. 세로 막대는 "~인"
rank⁡(A)\operatorname{rank}(A)랭크 에이계수 = 열공간의 차원np.linalg.matrix_rank(A)
dim⁡\dim디멘션차원 (방향 몇 개로 이루어졌나)

실습대의 미리 만든 행렬을 하나씩 눌러 표를 채워 보면 신기한 규칙이 보입니다.

미리 만든 행렬계수 (열공간의 차원)영공간의 차원합
그대로, 밀기2 (평면)0 (원점뿐)2
납작하게, 납작하게 21 (직선)1 (직선)2
영행렬0 (원점뿐)2 (평면 전체)2

합이 언제나 2, 즉 열의 개수입니다. 입력 쪽 방향 두 개는 "살아남아 열공간을 만들거나", "눌려서 영공간으로 사라지거나" 둘 중 하나라는 뜻입니다. 책에서는 이것을 계수-영공간 차원 정리(rank–nullity theorem) 라고 부릅니다. AA의 열이 nn개일 때

rank⁡(A)+dim⁡N(A)=n\operatorname{rank}(A) + \dim N(A) = n

입니다. 3×3 행렬에서도, 100개 열을 가진 데이터 행렬에서도 똑같이 성립합니다.

9-4. 해가 무수히 많은 이유 (6분)

8교시 '해 무수히'의 식 x − y = 1, 2x − 2y = 2를 이제 설명할 수 있습니다. A = [[1, −1], [2, −2]], b = (1, 2)입니다.

  1. 해가 있다. 두 열 (1, 2)와 (−1, −2)는 한 직선 위에 있고, b = (1, 2)도 그 직선(열공간) 위에 있습니다. 예를 들어 xₚ = (1, 0)을 넣으면 Axₚ = 1열 = (1, 2) = b입니다.
  2. 영공간이 있다. (1, 1)을 넣으면 1열 + 2열 = (0, 0)입니다. (1, 1) 방향이 영공간입니다.
  3. 둘을 더해도 해다. xₚ에 영공간의 벡터 t·(1, 1)을 아무만큼 더해도, 더한 부분은 A를 거치면 0이 되어 사라집니다. 그러니 A(xₚ + t·(1, 1)) = b + 0 = b입니다.

t는 아무 실수나 될 수 있으니 해가 무수히 많습니다. 모든 해는 이렇게 생겼습니다.

모든 해 = (해 하나) + (영공간의 아무 벡터)

그림으로는 "점 (1, 0)을 지나 (1, 1) 방향으로 뻗은 직선"이고, 이것이 실습대에서 두 직선이 겹쳐 보이던 그 직선 x − y = 1입니다. 영공간이 원점뿐이면(계수 2) 더할 것이 없으니 해는 하나뿐입니다. 8교시의 세 경우가 열공간과 영공간 두 가지로 모두 설명됩니다.

경우b는 열공간에?영공간해
계수 2늘 안에 있음원점뿐하나
계수 1, b가 직선 밖아니오직선없음
계수 1, b가 직선 위예직선무수히 (해 하나 + 영공간)

9-5. NumPy로 확인하기 (12분)

실습대 칸의 출력을 한 줄씩 따라갑니다. '납작하게'를 고른 상태입니다.

>>> import numpy as np
>>> A = np.array([[1, 2], [0.5, 1]])
>>> np.linalg.det(A)
np.float64(0.0)
>>> np.linalg.matrix_rank(A)
np.int64(1)

np.linalg.matrix_rank(A)는 계수를 정수로 돌려줍니다. 열공간이 정말 직선인지, 여러 x를 넣어 확인해 봅니다. 결과는 모두 둘째 성분이 첫째 성분의 절반, 즉 (1, 0.5) 방향 위에 있습니다. (−2, 1)을 넣으면 원점이 나오는 것도 보세요.

>>> for x in ([1, 0], [0, 1], [3, 1], [-1, 2], [-2, 1]):
...     print(x, A @ np.array(x))
[1, 0] [1.  0.5]
[0, 1] [2. 1.]
[3, 1] [5.  2.5]
[-1, 2] [3.  1.5]
[-2, 1] [0. 0.]

SVD로 영공간 방향 찾기

영공간 방향을 손으로 찾는 대신, NumPy에서는 보통 특이값 분해(SVD) 를 씁니다. SVD가 무엇인지는 14교시에서 그림으로 자세히 배우니, 지금은 "행렬을 넣으면 세 가지를 돌려주는 도구"로만 쓰겠습니다.

>>> U, S, Vt = np.linalg.svd(A)
>>> S
array([2.5, 0. ])

np.linalg.svd(A)는 값 세 개를 한꺼번에 돌려주고, U, S, Vt = …는 그것을 세 이름에 나눠 담는 파이썬 문법입니다. 지금 볼 것은 둘입니다.

  • S: 특이값이라는 숫자들로, 큰 것부터 차례로 나옵니다. 각 방향이 "얼마나 늘어나는가"이고, 0이 아닌 특이값의 개수가 계수입니다. 여기서는 2.5 하나뿐이니 계수 1입니다. matrix_rank도 속으로 이렇게 셉니다.
  • Vt: 2×2 배열이고, 각 행이 입력 쪽의 방향 하나입니다. S의 순서와 짝이 맞아서, 마지막 행 Vt[-1]이 가장 적게 늘어나는 방향입니다. 그 특이값이 0이면 그 방향은 원점으로 눌립니다. 즉 영공간 방향입니다.

Vt[-1]은 1교시의 음수 인덱싱으로 "마지막 행"을 꺼낸 것입니다.

>>> n = Vt[-1]
>>> n
array([-0.89442719,  0.4472136 ])
>>> A @ n
array([0., 0.])
>>> np.allclose(A @ n, 0)
True

n은 길이 1인 단위벡터(3교시)라서 (−2, 1)이 아니라 (−0.894…, 0.447…)로 나옵니다. 방향은 같습니다. 둘째 성분으로 나눠 보면 우리가 손으로 찾은 (−2, 1)이 나옵니다. 실습대 칸은 같은 값을 소수 6자리에서 반올림해 보여 줍니다. 또 SVD는 부호를 정해 주지 않아서, 환경에 따라 (0.894…, −0.447…)처럼 부호가 모두 뒤집혀 나올 수도 있습니다. 같은 직선 위의 방향이니 어느 쪽이든 맞습니다(14교시).

>>> n / n[1]
array([-2.,  1.])

A @ n의 검사는 np.allclose(A @ n, 0)처럼 0과 비교합니다. np.allclose는 배열과 숫자 하나도 비교할 수 있어서, "모든 성분이 0에 충분히 가까운가"를 한 번에 확인합니다.

계수-영공간 차원 정리도 숫자로 확인할 수 있습니다. A.shape[1]은 열의 개수입니다(shape의 둘째 값).

>>> A.shape[1] - np.linalg.matrix_rank(A)
np.int64(1)

해가 있는지 계수로 확인하기

8교시에서 solve는 "해 없음"과 "해 무수히"를 구별해 주지 못했습니다. 계수로는 구별됩니다. b를 A 옆에 열로 하나 더 붙인 행렬의 계수를 재 보는 것입니다. b가 열공간 안에 있으면 붙여도 새 방향이 생기지 않아 계수가 그대로이고, 밖에 있으면 계수가 하나 늘어납니다.

>>> A_many = np.array([[1, -1], [2, -2]])
>>> b_many = np.array([1, 2])
>>> np.column_stack([A_many, b_many])
array([[ 1, -1,  1],
       [ 2, -2,  2]])
>>> np.linalg.matrix_rank(A_many), np.linalg.matrix_rank(np.column_stack([A_many, b_many]))
(np.int64(1), np.int64(1))
>>> A_none = np.array([[1, 2], [1, 2]])
>>> b_none = np.array([2, -2])
>>> np.linalg.matrix_rank(A_none), np.linalg.matrix_rank(np.column_stack([A_none, b_none]))
(np.int64(1), np.int64(2))

4교시의 np.column_stack은 2차원 배열과 1차원 배열을 섞어 넣어도, 2차원 배열은 열들을 그대로 두고 1차원 배열은 새 열로 붙여 줍니다. 계수가 그대로(1, 1)면 해가 무수히, 늘어나면(1, 2) 해가 없습니다.

9-4의 "해 하나 + 영공간"도 확인해 봅니다. xₚ = (1, 0)에 (1, 1)의 t배를 더해도 결과는 늘 b = (1, 2)입니다.

>>> xp = np.array([1, 0])
>>> null_dir = np.array([1, 1])
>>> A_many @ xp, A_many @ null_dir
(array([1, 2]), array([0, 0]))
>>> for t in (-1, 0, 2.5):
...     x = xp + t * null_dir
...     print(x, A_many @ x)
[ 0 -1] [1 2]
[1 0] [1 2]
[3.5 2.5] [1. 2.]

3×3에서도 똑같다

그림으로 그릴 수 없는 3차원에서도 도구는 그대로입니다. 1부터 9까지를 차례로 채운 행렬은 det가 0인 대표적인 예입니다. 셋째 열이 "2열 × 2 − 1열"이라 세 열이 한 평면 위에 있습니다.

>>> M = np.array([[1, 2, 3],
...               [4, 5, 6],
...               [7, 8, 9]])
>>> np.linalg.matrix_rank(M)
np.int64(2)
>>> U, S, Vt = np.linalg.svd(M)
>>> np.round(S, 6)
array([16.848103,  1.06837 ,  0.      ])
>>> n3 = Vt[-1]
>>> np.allclose(M @ n3, 0)
True
>>> n3 / n3[0]
array([ 1., -2.,  1.])
>>> M @ np.array([1, -2, 1])
array([0, 0, 0])

계수 2이니 열공간은 3차원 공간 속의 평면이고, 영공간은 3 − 2 = 1차원, 즉 (1, −2, 1) 방향의 직선입니다. 마지막 특이값은 사실 0이 아니라 4.4e-16 같은 아주 작은 수로 나옵니다. 그래서 np.round(S, 6)으로 반올림해 보여 주었습니다. matrix_rank는 "아주 작은 특이값은 0으로 본다"는 기준을 써서 이런 찌꺼기를 걸러 냅니다.

데이터 표로도 해 봅니다. 사람 네 명의 키(cm), 키(mm), 몸무게(kg)를 적은 4×3 행렬입니다. 행이 사람, 열이 특성입니다.

>>> X = np.array([[170, 1700, 60],
...               [160, 1600, 55],
...               [180, 1800, 75],
...               [175, 1750, 70]])
>>> X.shape
(4, 3)
>>> np.linalg.matrix_rank(X)
np.int64(2)
>>> X @ np.array([10, -1, 0])
array([0, 0, 0, 0])

열은 셋이지만 계수는 2입니다. "키(mm) = 10 × 키(cm)"라서 10·1열 − 1·2열 = 0이고, (10, −1, 0)이 영공간에 들어 있습니다. 특성 하나가 새 정보를 주지 않는다는 뜻입니다. 15교시의 PCA는 이런 "실제로 필요한 방향의 개수"를 데이터에서 찾아내는 방법입니다.

9-6. 자주 하는 실수 (3분)

det == 0으로 계수 판단하기. 소수가 섞이면 det가 정확히 0이 아니라 아주 작은 수로 나올 수 있습니다. 아래 행렬은 2열이 1열의 0.1배라 계수 1인데, det는 0이 아닙니다.

>>> B = np.array([[3, 0.3], [1, 0.1]])
>>> d = np.linalg.det(B)
>>> d
np.float64(4.1633363423443364e-17)
>>> d == 0
np.False_
>>> np.isclose(d, 0)
np.True_
>>> np.linalg.matrix_rank(B)
np.int64(1)

이런 행렬에서는 np.linalg.solve가 오류를 내지 않고 터무니없이 큰 답(10¹⁶ 정도)을 돌려주기도 합니다. 계수가 의심스러우면 matrix_rank로 확인하세요. (NumPy 2에서는 비교 결과가 True 대신 np.True_처럼 보이는데, 파이썬의 참·거짓과 똑같이 쓸 수 있습니다.)

>>> x_bad = np.linalg.solve(B, np.array([1.0, 2.0]))
>>> np.abs(x_bad).max() > 1e15
np.True_

계수가 2인데 Vt[-1]을 영공간이라고 믿기. Vt[-1]은 "가장 적게 늘어나는 방향"일 뿐입니다. 마지막 특이값이 0일 때만 영공간 방향입니다. 실습대 칸도 계수가 2보다 작을 때만 n = Vt[-1]을 보여 줍니다. '밀기'처럼 계수 2인 행렬에 쓰면 원점으로 가지 않습니다.

>>> shear = np.array([[1, 1], [0, 1]])
>>> np.round(np.linalg.svd(shear).S, 6)
array([1.618034, 0.618034])
>>> np.allclose(shear @ np.linalg.svd(shear).Vh[-1], 0)
False

np.linalg.svd(…)의 결과는 이름으로도 꺼낼 수 있습니다. .S는 특이값, .Vh는 위의 Vt와 같은 것입니다.

영행렬에서 방향 하나만 보기. '영행렬'을 고르면 실습대 칸에 n = Vt[-1]로 (0, 1) 하나만 나옵니다. 하지만 영행렬의 영공간은 평면 전체라서, (0, 1)은 그중 한 방향일 뿐입니다. 특이값이 0인 것이 둘이면 Vt의 마지막 두 행이 모두 영공간 방향입니다.

연습 문제 (5분)

  1. 실습대에서 î를 (2, 1), ĵ를 (−4, −2)로 끌어 보세요. 계수는 얼마이고, 열공간과 영공간은 각각 어떤 방향인가요? NumPy로 확인해 보세요.
  2. A = [[1, 2], [2, 4]]일 때 b = (3, 6)과 b = (3, 5) 각각에 대해 Ax = b의 해가 없는지 무수히 많은지 계수로 판단해 보세요.
  3. 3×3 행렬 [[1, 2, 3], [2, 4, 6], [3, 6, 9]]의 계수와 영공간의 차원을 예상한 뒤 확인해 보세요.

풀이

>>> P = np.array([[2, -4], [1, -2]])
>>> np.linalg.matrix_rank(P)
np.int64(1)
>>> P @ np.array([2, 1])
array([0, 0])

1번에서 행렬의 1열은 î가 간 곳 (2, 1), 2열은 ĵ가 간 곳 (−4, −2)라서 [[2, −4], [1, −2]]입니다. 2열이 1열의 −2배라 계수 1, 열공간은 (2, 1) 방향의 직선입니다. 영공간은 2·1열 + 1·2열 = 0이 되는 (2, 1) 방향입니다. 이 행렬은 열공간과 영공간이 같은 직선입니다. 한 번 적용하면 직선 위로 모이고, 두 번 적용하면 전부 원점으로 갑니다.

>>> A2 = np.array([[1, 2], [2, 4]])
>>> np.linalg.matrix_rank(np.column_stack([A2, [3, 6]]))
np.int64(1)
>>> np.linalg.matrix_rank(np.column_stack([A2, [3, 5]]))
np.int64(2)
>>> K = np.array([[1, 2, 3], [2, 4, 6], [3, 6, 9]])
>>> np.linalg.matrix_rank(K)
np.int64(1)
>>> K.shape[1] - np.linalg.matrix_rank(K)
np.int64(2)

2번은 A의 계수가 1이고, (3, 6)을 붙이면 계수가 그대로라 해가 무수히, (3, 5)를 붙이면 2로 늘어 해가 없습니다. np.column_stack에는 리스트 [3, 6]을 그대로 넣어도 됩니다. 3번은 모든 열이 (1, 2, 3)의 배수라 계수 1, 영공간은 3 − 1 = 2차원(평면)입니다.

이번 교시 정리

  • 열공간 = Ax로 갈 수 있는 곳 전부 = A의 열들의 생성. Ax = b는 b가 열공간에 있을 때만 풀린다.

  • 영공간 = Ax = 0이 되는 x 전부 = 변환에서 원점으로 눌려 사라지는 방향. 원점은 늘 들어 있다.

  • 계수(rank) = 열공간의 차원 = 변환 뒤에 남은 방향의 개수.

  • 계수 + 영공간의 차원 = 열의 개수 (2×2라면 2+0, 1+1, 0+2).

  • 해가 무수히 많을 때, 모든 해 = 해 하나 + 영공간의 아무 벡터.

  • NumPy: np.linalg.matrix_rank로 계수, U, S, Vt = np.linalg.svd(A)에서 특이값이 0이면 Vt[-1]이 영공간 방향. 검사는 np.allclose(A @ n, 0).

다음 교시에는 시선을 바꿔, 같은 벡터를 다른 자(기저) 로 재 봅니다. 좌표 (1, 3)이 새 기저에서는 전혀 다른 숫자가 되는데, 그 숫자를 구하는 일이 바로 8교시의 연립방정식입니다.

← 이전

8교시 · 연립방정식 Ax = b

다음 →

10교시 · 기저 바꾸기

새 교시·새 강의 소식 받기

이 강의에 새 교시가 더해지거나 이어지는 강의가 열리면 이메일로 알려 드려요.

수집 항목: 이메일 주소 · 목적: 이 강의의 새 교시·공개 알림 · 보유 기간: 해지를 요청할 때까지. 다른 용도로 쓰거나 남에게 넘기지 않아요. 알림 메일에 답장하면 바로 지워 드려요.

질문과 답변

이 교시에서 궁금한 점을 남겨 주세요. 모든 언어 페이지의 질문이 함께 모입니다.

링크와 서식 없이 글자 그대로 표시됩니다.

R

ReflexKR

눌러 보며 배우는 파이썬과 Reflex. 모든 예제는 Reflex 0.10.0에서 직접 실행해 확인했습니다.

ReflexKR은 배너 광고 없이 무료로 운영돼요. 도움이 되셨다면 커피 한 잔으로 응원해 주세요.

제휴 링크와 후원 안내AI의 일기장: 이 사이트를 만드는 AI가 쓰는 글
한국어English

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex