브로드캐스팅
* 원래 덧셈, 뺄셈은 차원이 같은 두 벡터끼리만 가능하지만, 벡터와 스칼라의 경우 관례적으로 일벡터를 사용해 스칼라를 벡터로 변환한 연산을 허용한다.
선형조합(Linear Combination)
* 벡터/행렬에 다음처럼 스칼라곱을 곱한 후 더하거나 밴 것을 벡터/행렬의 선형조합이라고 한다.
* 벡터나 행렬을 선형조합해도 크기는 변하지 않는다.
벡터와 벡터의 곱셈
내적(inner product)
* 벡터 x와 벡터 y의 내적은 다음과 같이 표기한다. 내적은 점으로도 표기할 수 있고(dot product), <x, y>기호로 나타낼 수도 있다.
* 내적에는 다음과 같은 조건이 필요하다.
1. 두 벡터의 차원이 같음.
2. 앞의 벡터가 행 벡터이고 뒤의 벡터가 열 벡터의 형태를 띰.
* 위에서 열거한 조건 하에 내적이 이뤄질 때 결과 값은 scalar값이 된다.
import numpy as np
x=np.array([[1],[2],[3]])
y=np.array([[4],[5],[6]])
x.T @ y
#array([[32]])
* 벡터의 내적은 python에서 구현할 때 @ 연산자를 사용한다.
x=np.array([1,2,3])
y=np.array([4,5,6])
x@y
#32
* 또한 python에서 벡터를 1차원 array로 구현하였을 때는 따로 Transpose를 해주지 않아도 알아서 내적을 계산해준다.
가중합
* 위에서 배운 내적은 가중합 계산에서 사용될 수 있다.
* 만약 데이터 벡터가 $x=[x_1, ... , x_N]^T$ 이고 가중치 벡터가 $w=[w_1, ... , w_N]^T$ 이면 데이터 벡터의 가중합은 다음과 같다.
* 위 식을 벡터 표현으로 나타내면 $w^T x$ 또는 $x^T w$ 라는 간단한 수식으로 표시할 수 있게 된다.
* 만약 가중치가 모두 1이면 일반적인 합을 계산한다.
평균
* 평균을 구하는 식을 벡터로 표현하면 다음과 같다.
* 이를 python으로 코딩하면 다음과 같다.
x=np.arange(10)
N=len(x)
np.ones(N) @ x / N
* 위와 같이 계산할 수도 있지만, 사실 x.mean()을 사용하는 것이 더 편하다.
유사도(Similarity)
* 두 벡터가 닮은 정도를 정량적으로 나타낸 값
* 내적을 이용하면 cosine 유사도를 계산하는 것이 가능하다.
from sklearn.datasets import load_digits
import matplotlib.gridspec as gridspec
digits=load_digits()
d1=digits.images[0]
d2=digits.images[10]
d3=digits.images[1]
d4=digits.images[11]
v1=d1.reshape(64, 1)
v2=d2.reshape(64, 1)
v3=d3.reshape(64, 1)
v4=d4.reshape(64, 1)
plt.figure(figsize=(9, 9))
gs = gridspec.GridSpec(1, 8, height_ratios=[1],
width_ratios=[9, 1, 9, 1, 9, 1, 9, 1])
for i in range(4):
plt.subplot(gs[2 * i])
plt.imshow(eval("d" + str(i + 1)), aspect=1,
interpolation='nearest', cmap=plt.cm.bone_r)
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.title("image {}".format(i + 1))
plt.subplot(gs[2 * i + 1])
plt.imshow(eval("v" + str(i + 1)), aspect=0.25,
interpolation='nearest', cmap=plt.cm.bone_r)
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.title("vector {}".format(i + 1))
plt.tight_layout()
plt.show()
print('vector 1과 vector2의 내적 값: {}'.format((v1.T @ v2)[0][0]))
print('vector 3과 vector4의 내적 값: {}'.format((v3.T @ v4)[0][0]))
print('vector 1과 vector3의 내적 값: {}'.format((v1.T @ v3)[0][0]))
print('vector 1과 vector4의 내적 값: {}'.format((v1.T @ v4)[0][0]))
print('vector 2과 vector3의 내적 값: {}'.format((v2.T @ v3)[0][0]))
print('vector 2과 vector4의 내적 값: {}'.format((v2.T @ v4)[0][0]))
# vector 1과 vector2의 내적 값: 3064.0
# vector 3과 vector4의 내적 값: 3661.0
# vector 1과 vector3의 내적 값: 1866.0
# vector 1과 vector4의 내적 값: 1883.0
# vector 2과 vector3의 내적 값: 2421.0
# vector 2과 vector4의 내적 값: 2479.0
* 상대적으로 같은 숫자를 나타내는 이미지 벡터끼리 유사도가 높은 것을 확인할 수 있다.
선형회귀 모형
* 독립변수 x1, ... ,xn 과 가중치 변수 w1, .... , wn의 선형결합으로 이뤄진 선형회귀 모형은 다음과 같다.
* 이를 독립변수 벡터 x와 가중치 벡터 w를 사용해 나타내면 다음과 같이 표현할 수 있다.
교환 법칙과 분배 법칙
* 행렬의 곱셈에서 교환법칙은 성립하지 않지만, 덧셈에 대한 분배법칙은 성립한다.
* 전치 연산도 마찬가지로 분배법칙이 성립한다.
* 덧셈에 대해서는 순서의 변경이 없지만, 곱셈에 대해서는 순서가 바뀌게 된다.
곱셈의 연결
* 연속된 행렬의 곱셈은 계산 순서를 임의로 해도 상관이 없다.
항등행렬의 곱셈
* 어떤 행렬이든 항등행렬을 곱하면 그 행렬의 값이 변하지 않는다.
행렬과 벡터의 곱
1) 열 벡터의 선형 조합
* 행렬 X와 벡터 w의 곱은 행렬 X를 이루는 열벡터들과 가중치 벡터의 선형 결합을 통해 나타낼 수 있다.
* 벡터의 선형 조합은 두 이미지를 morping하는데 사용될 수 있다.
from sklearn.datasets import fetch_olivetti_faces
faces=fetch_olivetti_faces()
f, ax = plt.subplots(1,3)
ax[0].imshow(faces.images[6], cmap=plt.cm.bone)
ax[0].grid(False)
ax[0].set_xticks([])
ax[0].set_yticks([])
ax[0].set_title("image 1: $x_1$")
ax[1].imshow(faces.images[10], cmap=plt.cm.bone)
ax[1].grid(False)
ax[1].set_xticks([])
ax[1].set_yticks([])
ax[1].set_title("image 2: $x_2$")
new_face = 0.7 * faces.images[6] + 0.3 * faces.images[10] #6번 이지마와 10번 이미지의 선형결합
ax[2].imshow(new_face, cmap=plt.cm.bone)
ax[2].grid(False)
ax[2].set_xticks([])
ax[2].set_yticks([])
ax[2].set_title("image 3: $0.7x_1 + 0.3x_2$")
plt.show()
여러 개의 벡터에 대한 가중합 동시 계산
* 여러개의 벡터에 대한 선형 결합은 다음과 같이 나타낼 수 있다.
잔차
* 선형회귀분석을 통해 도출해 낸 가중치 벡터 w를 활용하였을 때의 예측값과 실제 값 사이의 차이를 잔차라고 한다.
잔차 제곱합(RSS : Residual Sum of Squares)
* 잔차의 크기는 잔차 벡터의 각 원소를 제곱한 후 더한 잔차 제곱합을 통해 나타낼 수 있다.
* 벡터의 제곱은 앞에서 살펴봤듯이 전치된 벡터(행벡터)와 원본 벡터(열벡터)의 곱을 통해 나타낼 수 있다.
* 또한 벡터를 제곱하면 '정방행렬' 형태가 된다((M x N) * (N x M) = M x M).
이차형식(Quadratic Form)
* 행벡터 x 정방행렬 x 열벡터의 형식으로 되어있는 것을 이차 형식이라고 한다.
* 위 식에서 이차형식을 풀면 i=1, ..., N, j=1, ..., N에 대해 가능한 모든 i,j쌍의 조합을 구한 다음 i,j에 해당하는 원소 $x_i, x_j$를 가중치 $a_{i, j}$와 같이 곱한 값 $a_{i, j} x_i x_j$의 총합이 된다.
부분행렬
* 다음과 같은 2차원 정방행렬 A,B가 있을 때 두 행렬의 곱 AB를 구하는 방법은 여러가지가 될 수 있다.
1) 앞에 곱해지는 행렬을 행 벡터로 나누어 계산
2) 뒤에 곱해지는 행렬을 열 벡터로 나누어 계산
3) 앞에 곱해지는 행렬을 열벡터로 뒤에 곱해지는 행렬을 행 벡터로 나누어 스칼라처럼 계산
'수학 > Numpy로 공부하는 선형대수' 카테고리의 다른 글
선형대수와 해석기하의 기초 (0) | 2021.11.22 |
---|---|
선형 연립방정식과 역행렬 (0) | 2021.11.18 |
행렬의 성질 (0) | 2021.11.15 |
데이터와 행렬 (0) | 2021.11.12 |