Python/NumPy

NumPy 선형대수: 행렬 곱셈 (dot, matmul)

임베디드 친구 2025. 10. 13. 20:01
반응형

NumPy 선형대수: 행렬 곱셈 (dot, matmul)

선형대수학은 데이터 과학, 머신 러닝, 과학 계산에서 중요한 역할을 합니다. 특히 행렬 곱셈은 벡터와 행렬 연산의 핵심입니다. 이번 포스팅에서는 Python의 NumPy 라이브러리를 사용하여 행렬 곱셈을 수행하는 방법에 대해 자세히 알아보겠습니다. NumPy는 빠르고 효율적인 수치 계산을 위해 설계된 강력한 라이브러리로, 행렬 연산을 간단하고 직관적으로 처리할 수 있도록 다양한 기능을 제공합니다.

NumPy에서의 행렬 곱셈

NumPy는 행렬 곱셈을 수행하기 위해 dot 함수와 matmul 함수를 제공합니다. 이 함수들은 다차원 배열 간의 내적 계산에 사용되며, 각각의 차이에 대해 이해하는 것이 중요합니다.

행렬 곱셈의 기본 개념

행렬 곱셈은 두 행렬의 원소를 특정 규칙에 따라 결합하여 새로운 행렬을 생성하는 연산입니다. 일반적으로, 두 행렬 $A$와 $B$가 있을 때:

  • $A$의 열의 개수와 $B$의 행의 개수가 같아야 행렬 곱셈이 가능합니다.
  • 결과 행렬의 크기는 $A$의 행의 개수와 $B$의 열의 개수로 결정됩니다.

예를 들어, $A$가 $3 \times 2$ 행렬이고 $B$가 $2 \times 4$ 행렬이라면 결과는 $3 \times 4$ 행렬이 됩니다.

dot 함수

numpy.dot 함수는 두 배열의 내적을 계산합니다. 2차원 배열에 대해 dot 함수는 행렬 곱셈을 수행합니다. 다차원 배열에 대해서는 축(axis)을 따라 계산을 수행합니다.

import numpy as np

# 예제: 2D 배열의 행렬 곱셈
A = np.array([[1, 2], [3, 4], [5, 6]])  # 3x2 행렬
B = np.array([[7, 8, 9], [10, 11, 12]])  # 2x3 행렬

result = np.dot(A, B)  # 3x3 결과 행렬
print(result)

위 코드의 출력 결과:

[[ 27  30  33]
 [ 61  68  75]
 [ 95 106 117]]

matmul 함수

numpy.matmul 함수는 dot 함수와 유사하지만 몇 가지 차이점이 있습니다. 주로 다음과 같은 경우에 유용합니다:

  1. 다차원 배열에서 행렬 곱셈을 수행할 때 브로드캐스팅(broadcasting)을 지원합니다.
  2. 스칼라 곱셈은 지원하지 않습니다.
# 예제: matmul 함수 사용
A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.array([[7, 8, 9], [10, 11, 12]])

result = np.matmul(A, B)
print(result)

결과는 dot 함수와 동일합니다:

[[ 27  30  33]
 [ 61  68  75]
 [ 95 106 117]]

1차원 배열의 경우

1차원 배열(벡터)의 경우, dot 함수와 matmul 함수는 다르게 작동합니다. dot은 내적을 계산하지만, matmul은 1차원 배열에서 오류를 발생시킵니다.

# 1D 배열 예제
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])

# dot 함수 사용
print(np.dot(x, y))  # 내적 결과: 32

# matmul 함수 사용
try:
    print(np.matmul(x, y))  # 오류 발생
except ValueError as e:
    print(e)

출력:

32
matmul: Input operand 1 does not have enough dimensions

브로드캐스팅과 다차원 배열의 곱셈

다차원 배열에서 matmul 함수는 브로드캐스팅을 지원하여 더 복잡한 연산을 수행할 수 있습니다.

# 다차원 배열 예제
A = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
B = np.array([[1, 0], [0, 1]])

result = np.matmul(A, B)
print(result)

출력:

[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]

성능 비교

큰 행렬의 경우, dotmatmul은 동일한 성능을 제공합니다. NumPy는 내부적으로 고도로 최적화된 BLAS 라이브러리를 사용하기 때문입니다. 성능 테스트는 다음과 같이 수행할 수 있습니다:

import time

# 큰 행렬 생성
A = np.random.rand(1000, 1000)
B = np.random.rand(1000, 1000)

# dot 성능 테스트
start = time.time()
np.dot(A, B)
print("dot: {:.5f}초".format(time.time() - start))

# matmul 성능 테스트
start = time.time()
np.matmul(A, B)
print("matmul: {:.5f}초".format(time.time() - start))

결론

이번 포스팅에서는 NumPy에서 행렬 곱셈을 수행하는 두 가지 주요 함수, dotmatmul에 대해 알아보았습니다. 각 함수는 특정 상황에서 유용하며, 차이를 이해하면 보다 효율적인 코드를 작성할 수 있습니다. 이를 통해 선형대수학의 기본적인 문제를 해결하고, 데이터 분석과 머신 러닝 작업에서 활용할 수 있습니다.

반응형