P2-3.6 선형대수를 NumPy로 확인하기¶
Section ID:
P2-3.6Version:v2026.09.14
NumPy(넘파이)는 Python에서 배열을 만들고 계산하는 라이브러리입니다. 앞 절의 벡터 비교를 코드로 계산하고, 입력과 가중치의 모양을 바꾸어 출력이 어떻게 달라지는지 확인할 수 있습니다. 배열의 shape는 각 축의 길이를 나타냅니다.
실행 환경¶
설치 위치는 P2-3.5의 실행 환경을 따릅니다. Colab/Jupyter에서는 코드 셀에 다음 명령을 입력합니다.
| IPython · 노트북 코드 셀 | |
|---|---|
로컬 PC에서는 터미널에 다음 명령을 입력합니다.
아래 Python 블록은 위에서부터 같은 세션에서 실행합니다. 뒤의 블록은 앞에서 만든 변수와 np를 사용합니다. 전체 코드를 한 번에 실행하려면 다음 파일을 사용합니다.
p2_3_6_numpy_linear_algebra.py
저장소 루트에서 실행하는 명령입니다. 파일만 다운로드했다면 저장한 폴더에서 python p2_3_6_numpy_linear_algebra.py로 실행합니다.
배열의 shape과 출력¶
import numpy as np는 NumPy를 np라는 짧은 이름으로 불러옵니다. np.array에 값의 목록을 넣으면 1차원 배열을, 행별 목록을 넣으면 2차원 배열을 만듭니다.
x.shape의 (2,)는 성분이 2개인 1차원 배열입니다. (1, 2)처럼 한 행을 가진 2차원 배열과는 구분합니다. W.shape의 (2, 2)는 2행 2열입니다. x @ W는 x와 W의 각 열을 곱하고 더하므로 출력은 [2×4+3×5, 2×1+3×2] = [23, 8]입니다.
*와 @의 차이¶
같은 shape의 배열에서 +와 *는 같은 위치의 성분끼리 계산합니다. 숫자 하나를 곱하면 모든 성분에 같은 숫자를 곱합니다. 1차원 벡터끼리 @를 쓰면 곱한 성분들을 더한 내적 값 하나가 나옵니다.
a * b는 [4, 10, 18]을 남기지만 a @ b는 4+10+18=32로 합칩니다. 앞의 x @ W는 벡터를, 여기의 a @ b는 숫자 하나를 반환합니다. @의 결과 모양은 입력 배열의 차원에 따라 달라집니다. shape이 다른 배열의 *에는 브로드캐스팅 규칙도 적용되므로, 위치별 곱이라고 해서 반드시 같은 shape만 허용하는 것은 아닙니다.
구매량 벡터 비교¶
P2-3.4에서 사용한 [커피 구매량, 차 구매량] 벡터를 그대로 계산합니다. np.linalg.norm(v)는 이 1차원 벡터의 2-노름을 구합니다. v-q는 두 구매량의 차이이고, 그 노름이 유클리드 거리입니다.
| 텍스트 · 실행 결과 | |
|---|---|
dot, norm, distance, cosine은 각각 내적·길이·거리·코사인 유사도입니다. 출력의 :.3f는 소수점 아래 세 자리까지 표시하라는 뜻이며 계산 자체를 세 자리로 제한하지 않습니다. 거리로는 b가 가장 가깝고, 코사인 유사도로는 a와 c가 같습니다. 내적은 구매량이 많은 c에서 가장 큽니다. 이 코사인 계산은 두 벡터의 길이가 0이 아닐 때만 사용할 수 있습니다.
candidates의 a를 [4, 4]로 바꾸고 다시 실행해 보세요. 내적은 8, 길이는 약 5.657, 거리는 약 4.243으로 바뀌지만 코사인 유사도는 1.000으로 유지됩니다. 구매 비율은 같고 구매량만 늘어난 결과입니다.
샘플 수·입력 수·출력 수¶
입력 3개를 행으로 묶고, 각 입력의 성분 2개를 출력 성분 4개로 바꿉니다. 아래 가중치는 계산을 확인하기 위해 직접 정한 예시이며, 학습으로 얻은 값은 아닙니다.
| 배열 | shape | 행과 열의 의미 |
|---|---|---|
X | (3, 2) | 샘플 3개, 샘플당 입력 성분 2개 |
W | (2, 4) | 입력 성분 2개에 대한 가중치, 출력 성분 4개 |
Y | (3, 4) | 샘플 3개, 샘플당 출력 성분 4개 |
(3, 2) @ (2, 4) → (3, 4)에서 가운데의 2가 일치해야 계산할 수 있습니다. 결과에는 샘플 수 3과 출력 성분 수 4가 남습니다. W의 첫 두 열은 앞의 [23, 8] 계산을 유지하고, 뒤 두 열은 입력의 첫째·둘째 성분을 각각 그대로 출력합니다. 같은 W를 각 샘플에 적용하므로 출력 한 행은 입력 한 행에 대응합니다.
차원 오류와 가중치 행 추가¶
성분이 3개인 입력을 현재의 2행짜리 W에 곱하면 오류가 납니다. 아래 코드는 오류를 잡아 입력 성분 수와 가중치 행 수를 출력합니다. 전체 오류 메시지는 NumPy 버전에 따라 다를 수 있습니다.
| 텍스트 · 실행 결과 | |
|---|---|
세 번째 입력을 사용하려면 그 입력에 대응하는 가중치 행이 필요합니다. 입력을 임의로 삭제해 모양만 맞추면 데이터의 의미가 바뀝니다. 세 번째 입력이 첫째·넷째 출력에 각각 1배씩 더해지도록 [1, 0, 0, 1]을 새 행으로 추가합니다. np.vstack은 배열을 행 방향으로 쌓습니다.
원래 [2, 3]의 출력 [23, 8, 2, 3]에 세 번째 입력 4가 [4, 0, 0, 4]를 더해 [27, 8, 2, 7]이 됩니다. shape을 맞추는 일과 새 입력의 역할을 정하는 일은 함께 이루어져야 합니다.
연습: 샘플을 하나 더 넣으면¶
배치 계산의 X 마지막에 [2, 0] 행을 추가하고 W는 바꾸지 않습니다. 실행 전에 X와 Y의 shape, 새 출력 행을 예상해 보세요.
계산과 해설
X.shape은 (4, 2), Y.shape은 (4, 4)가 됩니다. 새 출력 행은 [8, 2, 2, 0]입니다. 샘플 수가 늘어도 각 샘플의 입력 성분 수는 2개이므로 W를 바꿀 필요가 없습니다. 앞선 세 출력 행도 그대로 유지됩니다.
체크리스트¶
(2,)와(1, 2)가 다른 배열 모양임을 설명할 수 있는가?- 벡터끼리
*와@를 적용했을 때 배열과 숫자 하나로 결과가 갈리는 이유를 설명할 수 있는가? - 내적·노름·거리·코사인 유사도의 계산을 앞 절의 구매량 비교와 연결할 수 있는가?
(3, 2) @ (2, 4)의 결과 shape을 실행 전에 예상할 수 있는가?- 샘플 수를 늘리는 것과 입력 성분 수를 늘리는 것이 가중치에 미치는 차이를 설명할 수 있는가?
출처와 참고 자료¶
- NumPy Developers, NumPy documentation, 확인 날짜: 2026-07-19.
- NumPy Developers, NumPy quickstart, 확인 날짜: 2026-07-19.
- NumPy Developers,
numpy.array, 배열 생성 API의 인자와 예제를 확인할 수 있습니다. 확인 날짜: 2026-07-19. - NumPy Developers,
numpy.ndarray.shape, 배열 차원을 튜플로 확인하는shape속성을 확인할 수 있습니다. 확인 날짜: 2026-07-19. - NumPy Developers,
numpy.matmul, 행렬 곱과 shape 불일치 오류 조건을 확인할 수 있습니다. 확인 날짜: 2026-07-19. - Charles R. Harris et al., Array Programming with NumPy, Nature, 2020, 확인 날짜: 2026-07-19.
- numpy.linalg.norm, 확인 날짜: 2026-09-14.
- cosine_similarity, 확인 날짜: 2026-09-14.
- Broadcasting, 확인 날짜: 2026-09-14.